Linux Kernel Programming Intro
Linux Kernel Programming Intro
Programming
Don Porter
Lab 4
ò You will write a Linux kernel module
ò Nothing, except it is a bit more work to find the right address
ò Example code to do this in the lab4 handout
Kernel Programming
ò Big difference: No standard C library!
ò Sound familiar from lab 1?
ò Why no libc?
ò But some libc-like interfaces
ò malloc -> kmalloc
ò printf(“boo”) -> printk(KERN_ERR “boo”)
ò Some things are missing, like floating point division
Kernel Programming, ctd
ò Stack can’t grow dynamically
ò Generally limited to 4 or 8KB
ò So avoid deep recursion, stack allocating substantial
buffers, etc.
ò Why not?
ò Mostly for simplicity, and to keep per-thread memory
overheads down
ò Also, the current task struct can be found by rounding
down the stack pointer (esp/rsp)
Validating inputs
super-important!
ò Input parsing bugs can crash or compromise entire OS!
ò Example: Pass read() system call a null pointer for buffer
ò OS needs to validate that buffer is really mapped
ò Tools: copy_form_user(), copy_to_user(), access_ok(),
etc.
Cleaning up
ò After an error, you have to be careful to put things back
the way you found them (generally in reverse order)
ò Release locks, free memory, decrement ref counts, etc.
ò The _one_ acceptable use of goto is to compensate for
the lack of exceptions in C
Clean Up Example
str = getname(name);
if (IS_ERR(str)) {
err = -EFAULT;
printk (KERN_DEBUG "hash_name: getname(str) error!\n");
goto out;
}
if (!access_ok(VERIFY_WRITE, hash, HASH_BYTES)) {
err = -EFAULT;
printk (KERN_DEBUG "hash_name: access_ok(hash) error!\n");
goto putname_out;
}
// helper function does all the work here
putname_out:
putname(str);
out:
return err;
}
Key objects
ò task_struct – a kernel-schedulable thread
ò current points to the current task
ò inode and dentry – refer to a file’s inode and dentry, as
discussed in the VFS lectures
ò Handy to find these by calling helper functions in the fs
directory
ò Read through open and friends
Object-orientation in the
VFS
ò Files have a standard set of operations
ò Read, write, truncate, etc.
ò Each inode includes a pointer to a ‘file_operations’ struct
ò Which in turn points to a lot of functions
ò VFS code is full of things like this:
ò int rv = inode->f_op->stat(inode, statbuf);
OO, cont.
ò When an inode is created for a given file system, the file
system initializes the file_operation structure