How to write a kernel module, Programming Languages

Assignment Help:

Overview

You will write a loadable kernel module. If you have an idea which you can convince me is a good idea that can not be done as a module, but only via direct modification to the kernel source, then you may do that, but you must convince me that that is the only way to do it and to do it right before proceeding along that path.

Idea Proposal

Using what you have learned in class and in labs, Innovate an idea for a useful kernel module. Write a one-page proposal for

(a) what the idea is,

(b) how long you will need to take it

(c) if you will need to be on a team in order to finish it

(d) who your team members will be

(e) why you need a team to finish on time

(f) the division of labor between team members

(g) what resources you have found already that will help you

(h) why you believe you will be able to finish it on time

That one-page proposal is due on the first friday of April. It will be graded on a-h as well as on (i) is it a kernel module, and (j) is it innovative and/or useful (useful without innovative is fine, but neither innovative nor useful is not). Thus, 10 criteria, 10 points for each criteria, for a 100 point grade. Also, if you fail to convince me that you will be able to both learn from this and complete it on time, you will be given a different project, of the instructor's choosing.

Students that have taken Technical Report Writing have found it useful to have this idea proposal follow the same format as the feasibility study assigned in that class.

The exact details of how to write a kernel module shouldn't be necessary for this proposal. In general, your module can execute code when it is loaded and when it is unloaded, and typically the sort of code that will be executed when loading is code that registers your functions to be called at certain times (perhaps even replacing other functions in the kernel prior to loading) and unregisters those functions when unloading the module. Think in those general terms when writing this proposal. Feel free to search the web for more detailed resources, but be sure that whatever you find is valid for the 2.6 line of Linux kernels.

How to write a kernel module - Example 1

Code for a simple loadable kernel module can be found on a following page.

A makefile for a simple loadable kernel module can be found on another following page. When you type it in, be sure to use the tab key instead of spaces. I want to give you this code to try out before trying out the second example, because it is simpler and so that you realize that this isn't as intimidating of a process as it might seem.

Assuming that you're root, and that the kernel module is named hello.ko then the following would load it into memory:

insmod hello.ko

If it printed out anything via printk when it was loading then you could see it by checking the end of dmesg via the following:

dmesg | tail

When you want to unload that kernel module, you can use the following command:

rmmod hello.ko

If it printed out anything via printk when it was unloading then you could see it by checking the end of dmesg via the following:

dmesg | tail

obj-m := hello.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

all:

$(MAKE) -C $(KERNELDIR) M=$(PWD)

clean:

rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c

rm -rf .tmp_versions

#include

static int hello_init(void)

{

printk("Hello world\n");

return 0;

}

static void hello_exit(void)

{

printk("Goodbye world\n");

}

module_init(hello_init);

module_exit(hello_exit);

MODULE_AUTHOR("CSIS 430");

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("Hello world");

How to write a kernel module - Example 2

Creating a loadable kernel module in Linux that uses /proc to allow user-level code to access it.

Code for a simple loadable kernel module that provides a 1K buffer in /proc/buffer1k can be found on a following page.

A makefile for that simple loadable kernel module can be found on another following page.

When you type it in, be sure to use the tab key instead of spaces.

Assuming that you're root, and that the kernel module is named buffer1k.ko then the following would load it into memory:

insmod buffer1k.ko

If it printed out anything via printk when it was loading then you could see it by checking the end of dmesg via the following:

dmesg | tail

To use this example, you need to be root to write to it:

echo "hi" > /proc/buffer1k

But any user can read from what was written into that buffer.

cat /proc/buffer1k

When you want to unload that kernel module, you can use the following command:

rmmod buffer1k.ko

If it printed out anything via printk when it was unloading then you could see it by checking the

end of dmesg via the following:

dmesg | tail

obj-m := buffer1k.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build

PWD := $(shell pwd)

all:

$(MAKE) -C $(KERNELDIR) M=$(PWD)

clean:

rm -f *.o *~ core .depend .*.cmd *.ko *.mod.c

rm -rf .tmp_versions

/**

* buffer1k.c - create a 1k buffer in /proc at /proc/buffer1k

*

*/

#include /* Specifically, a module */

#include /* We're doing kernel work */

#include /* Necessary because we use the proc fs */

#include /* for copy_from_user */

#define PROCFS_MAX_SIZE 1024

/* the above is why this is 1k */

#define PROCFS_NAME "buffer1k"

/* where in /proc we're puttying this */

/**

* This structure hold information about the /proc file

* Note that we can declare static variables in a kernel module.

* This is far better than declaring a global as it will be module specific.

*/

static struct proc_dir_entry *Our_Proc_File;

/**

* The buffer used to store characters for this module

*/

static char procfs_buffer[PROCFS_MAX_SIZE];

/**

* The size of the buffer

* Note that this can be at most PROCFS_MAX_SIZE

*/

static unsigned long procfs_buffer_size = 0;

/**

* This function is called then the /proc file is read

*

*/

int

procfile_read(char *buffer,

char **buffer_location,

off_t offset, int buffer_length, int *eof, void *data)

{

int ret;

printk("procfile_read (/proc/%s) called\n", PROCFS_NAME);

if (offset > 0) {

/* we have finished to read, return 0 */

ret = 0;

} else {

/* fill the buffer, return the buffer size */

memcpy(buffer, procfs_buffer, procfs_buffer_size);

/* note that yes,

* we can safely use certain standard library functions

* such as memcpy,

* but not any that might actually call the OS

*/

ret = procfs_buffer_size;

}

return ret;

}

/**

* This function is called when the /proc file is written

*

*/

int procfile_write(struct file *file, const char *buffer, unsigned long count,

void *data)

{

/* get buffer size */

procfs_buffer_size = count;

if (procfs_buffer_size > PROCFS_MAX_SIZE ) {

procfs_buffer_size = PROCFS_MAX_SIZE;

}

/* write data to the buffer */

if ( copy_from_user(procfs_buffer, buffer, procfs_buffer_size) ) {

/* we use copy_from_user in case segments happen to be used,

* also because the kernel "page table" and the user page

* table have different virtual addresses, and

* "buffer" is a userspace address

*

* We didn't need to do this on read because the

* copying from kernel space is something the

* I/O related system calls (like "read()") do for us

*/

return -EFAULT;

}

return procfs_buffer_size;

}

/**

*This function is called when the module is loaded

*

*/

static int buffer1k_init(void)

{

/* create the /proc file */

Our_Proc_File = create_proc_entry(PROCFS_NAME, 0644, NULL);

if (Our_Proc_File == NULL) {

remove_proc_entry(PROCFS_NAME, &proc_root);

printk("Error: Could not initialize /proc/%s\n",

PROCFS_NAME);

return -ENOMEM;

}

Our_Proc_File->read_proc = procfile_read;

Our_Proc_File->write_proc = procfile_write;

Our_Proc_File->owner = THIS_MODULE;

Our_Proc_File->mode = S_IFREG | S_IRUGO;

Our_Proc_File->uid = 0;

Our_Proc_File->gid = 0;

Our_Proc_File->size = 37;

printk("/proc/%s created\n", PROCFS_NAME);

return 0; /* everything is ok */

}

/**

*This function is called when the module is unloaded

*

*/

static void buffer1k_exit()

{

remove_proc_entry(PROCFS_NAME, &proc_root);

printk("/proc/%s removed\n", PROCFS_NAME);

}

module_init(buffer1k_init);

module_exit(buffer1k_exit);

MODULE_AUTHOR("CSIS 430");

MODULE_LICENSE("GPL");

MODULE_DESCRIPTION("A 1K buffer");

Detailed Design Document

Do all the hard work, aside from writing code. Provide a detailed design document. This should indicate that you've thought about issues such as what kernel data structures you'll be interacting with, how you'll ensure you don't corrupt them as you interact with them, what kernel functions you'll call, how you'll interact with anything else (I/O, reading a configuration file, etc...), and so on. This should be very detailed - to illustrate how detailed, if you're writing this in C (assembler is another possibility) from this design document, I should be able to determine all the {} that you'll be using. This should be at least 3 pages long, and will be on a check, check plus, check minus, zero scale. If you fail to do this, or if you get a zero, then you'll fail the project - because if you fail to have this sufficiently detailed and thought out, I don't want to bother seeing you try to muddle through crafting a kernel module. Students have found it useful to apply what they learned in software engineering to the creation of this detailed design document.

Due: October 29th

Status Report

A status report. Again, graded on the check, check plus, check minus, or 0 scale.

Document how things have changed (if at all) since the detailed design document, and the progress regarding your implementation of that design.

Due: November 19th

Demonstrations and Final Code/Report

Provide a demonstration of your kernel module to me. You will be graded on the same scale as the detailed design document. Set up an appointment with me for this demonstration. Demonstrations must be completed by when the final exam would be scheduled for.

Demonstrations Due: December 3

Final Code/Report Due: December 3

You are to turn in:

Hardcopy of code a final progress report which contains:

how well you followed your design document

how well you didn't follow it

why you didn't follow it

(you may liberally copy and paste from the status report for this final report)

a summary of the project (this should ideally just be a copy of the proposal, but probably should be enhanced with additional details)

what you learned while doing this project

A Bad Example

I wanted to provide an example of something that would not make for a good loadable kernel module. This is the best bad example that I could come up with.

Inter-process communication on most OSes is relatively unstructured. What about having an OS provided mechanism for structured inter-process communication?

Structured IPC done entirely in userspace

Processes interested in being part of this structured IPC memory map in (read only) a particular file which is owned by root but has read access to everyone.

A root setuid program takes arguments (or piped data) and structures it and adds it to the file, updating earlier contents of the file to reflect the new data. It acquires a write (exclusive) lock on the file when doing so.

Non-root processes can call the setuid program.

The setuid program really only enforces the structured aspect of the data.

Processes interested in reading from the memory mapped file may acquire a read (shared) lock on the file when doing so.

Note the complete lack of a need for the OS to be involved.

A good loadable kernel module does something that can't be done in userspace. Possibilities

are:

1) allows access to kernel data structures not otherwise accessible

2) allows access to hardware/devices not otherwise accessible

3) does something which is done faster when in the kernel than in userspace (note that this is rare and few - for example, the above structured IPC might be slightly faster if that setuid program was really a system call instead, but whether or not that would be worth the tradeoff would be dependent on the frequency that such calls were made - if made often, it would be worth it, if not made often, it would not be worth it. An example of how it might be worth it would be if a kernel-level parser for some networked structured data format was supported and a network RPC mechanism had been implemented on top of that, and networked RPC was the main thing that you wanted to do - this way, instead of having the data copied around from network card to kernel to user space to data parser space to the shared memory, it could conceivably go directly from the network card to the data parser (in kernel) to the shared memory)


Related Discussions:- How to write a kernel module

Multiplication of matrices, The last matrix operation which we'll see is ma...

The last matrix operation which we'll see is matrix multiplication. Now there we will start along with two matrices, A nxp and B pxm . Remember hat A must have similar number of c

I got a project and i need help , the details on the two pictures on the li...

the details on the two pictures on the link below : http://rak-up.com/up/files/18637.jpg ">http://rak-up.com/up/files/18636.jpg http://rak-up.com/up/files/18637.jpg

Create a directory, The ?rst task in the project is to develop a sane syste...

The ?rst task in the project is to develop a sane system to store change logs and versions of ?les. The simplest approach is to create a "dot" directory in the location of the ?le

Programming and modelling in uml, Introduction Currently, Omega has 178...

Introduction Currently, Omega has 178 stores UK wide. Most cities and large towns within the UK are catered for by Omega. Omega began in 1960's selling various makes of telep

Cookies management with perl, One of the main strengths of the Perl program...

One of the main strengths of the Perl programming language are its powerful text manipulation features. In this assignment, you will put them to use for writing a Perl program that

Prims algorithm for minimum spanning tree, Implement the Prim's algorithm w...

Implement the Prim's algorithm with array data structure as described in slide 12 of the file 04mst.ppt. Your program should have a runtime complexity of O(n2) and should be as eff

Api in c#, i what to know how setcapture() api work in c#

i what to know how setcapture() api work in c#

Shell script, program for pyramid in shell script

program for pyramid in shell script

Loops, I have doubt in this section .do-while loop.could you able to clear ...

I have doubt in this section .do-while loop.could you able to clear it for me.

Write Your Message!

Captcha
Free Assignment Quote

Assured A++ Grade

Get guaranteed satisfaction & time on delivery in every assignment order you paid with us! We ensure premium quality solution document along with free turntin report!

All rights reserved! Copyrights ©2019-2020 ExpertsMind IT Educational Pvt Ltd