520 likes | 974 Views
Kernel Modules. Goals . Learn how to study kernel code. Learn about modules. Learn how create, compile, install, and uninstall modules. Kernel Modules. A module is a set of functions and data types that can be compiled as an independent program Two ways of installing modules
E N D
Kernel Modules • Goals. • Learn how to study kernel code. • Learn about modules. • Learn how create, compile, install, and uninstall modules. CS 310 Project 4
Kernel Modules • A module is a set of functions and data types that can be compiled as an independent program • Two ways of installing modules • linked into the kernel when the kernel is started (static loading) • or installed while the kernel is running (dynamic loading) • kernel can be built to not allow dynamic loading. CS 310 Project 4
Kernel Modules • when a system call that is defined in your module is made • the kernel will field the system call and pass to the corresponding function in your kernel • if your kernel is not yet installed (in dynamic loading), call fails. • can determine which modules are running by reading the file /proc/modules CS 310 Project 4
Kernel Modules • device drivers • can use modules to implement device drivers • UNIX systems have a traditional static method for defining and adding device drivers at kernel configuration. • module API generally conforms to the API for a device driver • modules can implement any function, not just device drivers. CS 310 Project 4
Module Organization • Module is part of the kernel • executes in supervisor mode • has access to kernel data structures (if it knows their addresses) • Problem: finding the address of kernel data structures • module is in a different file than the kernel; doesn’t know kernel variable names • normal C method: define variables as extern • but modules are compiled separately from kernel, so extern doesn’t work. CS 310 Project 4
Module Organization • Solution: • Linux kernel incorporates mechanism by which files that implement a data structure can export the symbolic name of the structure at runtime. • Debuggers use this technique (e.g., dbx uses information created with the -g flag to gcc) • Must tell the compiler to export symbols. • kernel public symbols are exported by using the file’s header file. • See the file kernel/ksyms.c CS 310 Project 4
Module Organization • A module is a dynamic abstract data type that has an interface that can be interpreted by the static kernel. • Minimum module interface must include two functions. • Kernel calls these when it installs and removes the module: • init_module( ) • cleanup_module( ) CS 310 Project 4
Module Organization • Example: #include <linux/kernel.h> #include <linux/module.h> … int init_module( ){ /* code to initialize the module when it is installed */ } void cleanup_module( ){ /* code to clean up when module is removed } CS 310 Project 4
Module Organization • Can write a module that contains only these two routines. • In this case, init_module would have to start an activity that would continue as long as the module is installed. • Linux includes a mechanism for defining a new API for the module with as many functions as you want. CS 310 Project 4
Module Organization • Module interface. • module writer must be able to inform OS of her new functions • Each new function that is added to the module must be registered • done when the module is installed in the kernel. • if module is statically loaded, all functions are registered when kernel is booted. • if module is dynamically loaded, functions must be dynamically registered with the kernel when the module is installed. CS 310 Project 4
Module Organization • Module interface. • if module is dynamically loaded, its functions must be dynamically removed. • Do this by unregistering functions. • Registration is usually done in init_module( ) • Unregistration is usually done in cleanup_module( ) CS 310 Project 4
Module Organization • Module interface. • There are two types of interfaces available to use with a module • device driver • /proc file • device driver interface is more general: can read and write it. • /proc files can be read, but not written. CS 310 Project 4
Module Organization • /proc interface • When module uses /proc interface, it’s implementation file will be saved in the /proc directory • module is then referenced via /proc-style file operations. • The module is registered with proc_register( ) • module is unregistered with proc_unregister( ) CS 310 Project 4
Module Registration • proc_register( ) and proc_unregister( )interfaces • reference a struct proc_dir_entry data structure • this struct specifies the characteristics of the new pseudo file that will appear in /proc after the module has been registered. • this is defined in include/linux/proc_fs.h • this is used in …/linux/kernel/fs/proc/array.c • see next slide CS 310 Project 4
Module Registration struct proc_dir_entry ={ unsigned short low_ino; // inode # unsigned short namelen; // length of the filename const char *name; // the filename mode_t mode; // File mode nlink_t nlink; // number of links to this file uid_t uid; // uid for the file gid_t gid; // gid for the file unsigned long size; // size of file as it will be reported by ls CS 310 Project 4
Module Registration struct inode_operations *ops; // functions to manipulate inode int (*get_info)(char *, char **, off_t, int, int); // function entry point void (*fill_inode)(struct inode *); // function to change permissions, etc. struct proc_dir_entry *next, *parent, *subdir; // optional links if in a list void *data // unused int (*read_proc)(char *page, char **start, off_t off, int count, int eof, void *data) }; CS 310 Project 4
Module Registration • low_ino is set to 0 to tell the system to assign this value. Has to do with the file structure of Linux. • namelen length of the module name. • name the actual name of the module. • mode describes the mode of the resulting pseudo file. These values are designated for the mode argument in stat(2). See man 2 stat for the values. • nlink is the number of links that reference this pseudo file. Usually one. CS 310 Project 4
Module Registration • uid and gid fields are the user and group Ids for the pseudo file. If 0, root is owner. • size is the size of the file that ls returns. Does not have to have any relationship to real size of the file. • ops field is a pointer to a list of functions to manage the pseudo file inode. Has to do with files. Usually this field is NULL. • get_info see later slides. CS 310 Project 4
Module Registration *next, *parent, *subdir these are optional; can leave out *data unused; can leave out read_proc optional; can leave out CS 310 Project 4
Module Registration • get_info is a pointer to the function that should be called by the kernel in response to the read( ) system call. • a /proc pseudo file is a program in memory that responds to a read( ) system call on that pseudo file. • The module get_info( ) function has a prototype of the form: int get_info(char *sys_buffer, char ** my_buffer, off_t file_pos, int my_buffer_length, int zero ); CS 310 Project 4
Module Registration • get_info parameters: • char *sys_bufferThe system reserves buffer space for the pseudo file; this parameter points to that space. • char ** my_buffer The module programmer can also reserve system space and then use an application space pointer to reference the reserved area. Uses this pointer. CS 310 Project 4
Module Registration • get_info parameters: • off_t file_pos is the pseudo file position; usually meaningless • int my_buffer_lengththe number of bytes allocated for my_buffer. • int zero not currently used. CS 310 Project 4
Module Registration • Code to register a module named my_module with a supplementary function my_read: #include <linux/kernel.h> #include <linux/module.h> #include <linux/proc_fs.h> … int my_read(char *, char **, off_t, int, int){ /* define this function here */ } CS 310 Project 4
Module Registration struct proc_dir_entry my_mod_proc_file = { 0, 9, “my_module”, S_IFREG|S_IRUGOP, 1, 0, 0, BUF_LEN, NULL, my_read, NULL }; low_ino namelen name mode nlink uid gid mode of S_IFREG|S_IRUGOP is a regular file which can be read by its owner, its group, and everybody else CS 310 Project 4
Module Registration struct proc_dir_entry my_mod_proc_file = { 0, 9, “my_module”, S_IFREG|S_IRUGOP, 1, 0, 0, BUF_LEN, NULL, my_read, NULL }; size ops get_info fill_inode CS 310 Project 4
Module Registration int int_module( ){ /* proc_root is the root of /proc */ return proc_register(&proc_root, &my_mod_proc_file); }( void cleanup_module( ){ proc_unregister (&proc_root, my_mod_proc_file.lowino); } CS 310 Project 4
Module Installation • Compile module in user space • need appropriate flags (see later) • result is an executable file • executable can reference kernel variables (if the kernel allows these to be referenced) • module can also export its own symbols so that other modules can use them. CS 310 Project 4
Module Installation • Next install module using insmod (see later) • new module is added to kernel address space (use the kernel function create_module( ) ). • the kernel function get_kernel_syms() resolves the external symbol references in the module by searching • the exported kernel symbols • followed by the list of other modules that have already been loaded. • if one module references a symbol exported by another module, the latter module must be loaded before the former module CS 310 Project 4
Module Installation • create_module( ) allocates memory space for the module • the module is loaded by the init_module( ) system call. • here is where symbols defined by this module are exported. • insmod calls the init_module( ) function for the newly loaded module. CS 310 Project 4
Module Removal • To remove a module call rmmod (see later slides) • cleanup_module is called • the space used by the module is released • the virtual addresses used by the module are unmapped • Caution: if remove a module and another module (that is still installed) uses functions from the removed module, second module will cause an error. CS 310 Project 4
Compiling a Module • must instruct compiler to compile your code as kernel code • use flag -D in conjunction with next two to tell compiler that • use flag _ _KERNEL_ _ (note two underscores preceding and following) • use the MODULE compile-time flag to tell compiler that the file is a module rather than an ordinary flag • use the -W compiler option to pass the word all to the loader. This word does • use the -c switch to tell the compiler not to call the linker after it compiles • Example command line to compile the file foo.c that contains a module: gcc -c -Wall -D_ _KERNEL_ _ -DMODULE foo.c back CS 310 Project 4
Installing and Removing a Module • must be superuser or root to install and remove a module from the command line • use the command: /sbin/insmod<module_name> • print /proc/modules before and after you install to verify that the ismod call worked. • when finished with the module, remove it with /sbin/rmmod back CS 310 Project 4
Assignment • “Design and construct a module that implements a clock file in /proc. The file should support only the file read( ) operation. • When read( ) is called, it should return a single ASCII string with two numerical substrings separated by a single space. • Example: it must return a string of the form 934380108 184263 if the system time variable xtime was set to xtime.tv_sec = 934380108 xtime.tv_usec = 184263 CS 310 Project 4
Assignment • “Also provide an application program that demonstrates your module. As one particular test of your program, write a tight loop of the following form. #include <stdio.h> #include <sys/time.h> #define N … CS 310 Project 4
Assignment struct timeval gtodTimes[N]; char *procClockTimes[N]; … my_clock = fopen(“/proc/…”,’r”); for (i = 0; i < N; i++){ gettimeofday(>odTimes[i], 0); fgets(procClockTime[i],LENGTH, my_clock); } for (i=0; i<N; i++) printf(“….”gtodTimes[i], procClockTime[i]; CS 310 Project 4
Assignment • use gettimeofday() to determine the apparent resolution of the clock values that you read and of the values read from the kernel variables. • Explain why gettimeofday() has a much finer resolution than the 10ms time between timer interrupts. CS 310 Project 4
Assignment hints • write a module with the get_info field set to reference your read function • my_read( ) is used in earlier slides • reserve your own buffer inside of the get_info( ) routine • return a pointer to this buffer by using the second parameter • must assure that after you allocate your buffer, it does not “disappear” when get_info( ) returns • Might need to use the file position parameter to determine how many characters have been read on previous operations. CS 310 Project 4
Assignment hints • EOF (end of file) for a file in /proc • when your file is read by an application, its read function needs to know that it has encountered the end of the file. • You must use buffers to read the entire file content into an array. • Then you introduce your own EOF condition. • Return this when the entire buffer has been consumed by read operations. • Can use the value of the file position that is passed into your read( ) function. • You may assume that every read consumes the entire contents of the file and returns an EOF • See the man page for the read( ) system call to understand what must be returned. CS 310 Project 4
Assignment hints • To answer the clock resolution question, read the Linux source code. • …/linux/kernel/time.c • …/linux/arch/i386/kernel/time.c CS 310 Project 4
References • Ori Pomerantz’s book (ok, it’s only 120 pages). Most complete reference available. http://metalab.unc.edu/mdw/lDP/lkmpg/mpg.html this book is also available at many Linux sites. • Matt Welsh (coauther of Running Linux) has an article “Implementing Loadable Kernel Modules for Linux’ in the May 1995 issue of Dr. Dobb’s Journal: • http://www.ddj.com/articles/1995/9505/9505a/9595a.htm CS 310 Project 4