200 likes | 455 Views
Kernel Modules. CS350 Kartik Gopalan. Kernel Modules. Allow code to be added to the kernel, dynamically Only those modules that are needed are loaded Reduces kernel size Enables independent development of drivers for different devices. Module Control. insmod command does insertion
E N D
Kernel Modules CS350 Kartik Gopalan
Kernel Modules • Allow code to be added to the kernel, dynamically • Only those modules that are needed are loaded • Reduces kernel size • Enables independent development of drivers for different devices
Module Control • insmod command does insertion • rmmod command does removal • lsmodcommand tells what modules are currently loaded
Kernel Modules • Allow code to be added to the kernel, dynamically • Only those modules that are needed are loaded • Reduces kernel size • Enables independent development of drivers for different devices
Simple Kernel Module • http://www.cs.binghamton.edu/~kartik/cs552/examples/module/ #include <linux/init.h> #include <linux/module.h> MODULE_LICENSE("DUAL BSD/GPL"); // called when module is installed int __inithello_init() { printk(KERN_ALERT "mymodule: Hello World!\n"); return 0; } // called when module is removed void __exit hello_exit() { printk(KERN_ALERT "mymodule: Goodbye, cruel world!!\n"); } module_init(hello_init); module_exit(hello_exit);
Compiling the module with a Makefile # To build modules outside of the kernel tree, we run "make" in the kernel source tree; the Makefile there then # includes this Makefile once again. # This conditional selects whether we are being included from the kernel Makefile or not. ifeq ($(KERNELRELEASE),) # Assume the source tree is where the running kernel was built # You should set KERNELDIR in the environment if it's elsewhere KERNELDIR ?= /lib/modules/$(shell uname -r)/build # The current directory is passed to sub-makes as argument PWD := $(shell pwd) modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules_install clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions .PHONY: modules modules_install clean else # called from kernel build system: just declare what our modules are obj-m := hello.o endif • When you type ‘make’, this Makefile is read twice by the make system. • First time to locate the kernel source tree • Second time to actually build the module. • What is .PHONY? Check here: http://theory.uwinnipeg.ca/gnu/make/make_33.html
Module Control • Insmod hello.ko • Inserts a module • Internally, makes a call to sys_init_module • Calls vmalloc() to allocate kernel memory • Copies module binary to memory • Resolves any kernel references (e.g. printk) via kernel symbol table • Calls module’s initialization function • modprobe hello.ko • Same as insmod, except that it also loads any other modules that hello.ko references. • rmmod • Removes a module • Fails if module is still in use • lsmod • Tells what modules are currently loaded • Internally reads /proc/modules
Things to remember • Modules can call exported kernel functions • Such as printk, kmalloc, kfree etc. • Modules (or any kernel code for that matter) cannot call user-space library functions • Such as malloc, free, printf etc. • Modules should not include standard header files • Such as stdio.h, stdlib.h, etc. • Segmentation fault may be harmless in user space • But a kernel fault can crash the entire system • Version Dependency: • Module should be recompiled for each version of kernel that it is linked to.
Concurrency Issues • Many processes could try to access your module concurrently. • So different parts of your module may be active at the same time • Device interrupts can trigger Interrupt Service Routines (ISR) • ISRs may access common data that your module uses as well. • Kernel timers can concurrently execute with your module and access common data. • You may have symmetric multi-processor (SMP) system, so multiple processors may be executing your module code simultaneously (not just concurrently). • Therefore, your module code (and most kernel code, in general) should be re-enterant • Capable of correctly executing in more than one context simultaneously.
Module Parameters • Command line: • insmod hellon.ko howmany=10 whom=“Class” • Module code has: static char *whom = “world”; static int howmany = 1; module_param(howmany, int, S_IRUGO); module_param(whom, charp, S_IRUGO); • See example module • http://www.cs.binghamton.edu/~kartik/cs552/examples/module
Creating a /proc interface for module #include linux/kernel.h> #include <linux/module.h> #include <linux/proc_fs.h> int init_module() { create_proc_read_entry("myxtime", 0, NULL, my_xtime_read, NULL); } void cleanup_module() { remove_proc_entry(“myxtime”, NULL); }
int my_xtime_read( char *sbuffer, char **my_buffer, off_t file_pos, int my_buffer_length, int *eof, void * data) { … }
Version Numbering • Kernel components have inter-dependencies • Version numbers help to track these dependencies • Well-written modules have minimal dependencies • should be backward compatible with all versions. • Linux kernel version numbers: • major.minor.release (e.g. 2.6.20) • Odd numbered minor versions are for developers only. • Even numbers are supposed to be stable enough for general use.
GNU General Public License (GPL) • http://en.wikipedia.org/wiki/Gpl • Basis for all of the GNU software development, including Linux • Allows users to modify software as they see the need • Requires source code be distributed with binaries • “Infects" transitively through modification and distribution by multiple parties • Device drivers need not be licensed under the GPL, but the mainstream ones are