170 likes | 190 Views
Learn the key role of device drivers in the Linux kernel and how they interact with hardware through defined interfaces. Explore module licensing, initialization, and printing functions. Understand the kernel source tree's importance in building device drivers.
E N D
chapter 2 - Hello World Model chenbo2008@ustc.edu.cn 中国科学技术大学软件学院
Definition: Device drivers take on a special role in the Linux kernel. They are distinct “black boxes” that make a particular piece of hardware respond to a well-defined internal programming interface; they hide completely the details of how the device works. 《Linux Device Driver 3rd》
MODULE_LICENSE(); module_init(); module_exit(); Unless your module is explicitly marked as being under a free license recognized by the kernel, it is assumed to be proprietary, and the kernel is “tainted” when the module is loaded. In include/linux/module.h, line 126 #define MODULE_LICENSE(_license) MODULE_INFO(license, _license)
MODULE_LICENSE(); module_init(); module_exit(); In include/linux/init.h, line 213 212 /* Each module must use one module_init(), or one no_module_init*/ 213 #define module_init(initfn) \ 214 static inline initcall_t__inittest(void) \ 215 { return initfn; } \ 216 intinit_module(void) __attribute__((alias(#initfn))); 217 218 /* This is only required if you want to be unloadable. */ 219 #define module_exit(exitfn) \ 220 static inline exitcall_t__exittest(void) \ 221 { return exitfn; } \ 222 void cleanup_module(void) __attribute__((alias(#exitfn)));
This module contains kernel function printk(),It behaves similarly to the standard C library function printf. In kernel/printk.c, line 502 502 asmlinkage int printk(constchar *fmt, ...) 503 { 504 va_listargs; 505 intr; 506 507 va_start(args, fmt); 508 r = vprintk(fmt, args); 509 va_end(args); 510 511 return r; 512 }
Why using printk()? The kernel needs its own printing function because it runs by itself, without the help of the C library. In kernel/printk.c, line 502 502 asmlinkage int printk(constchar *fmt, ...) 503 { 504 va_listargs; 505 intr; 506 507 va_start(args, fmt); 508 r = vprintk(fmt, args); 509 va_end(args); 510 511 return r; 512 }
Now, can you explain why kernel source tree is required in building device driver? In kernel/printk.c, line 502 502 asmlinkage int printk(constchar *fmt, ...) 503 { 504 va_listargs; 505 intr; 506 507 va_start(args, fmt); 508 r = vprintk(fmt, args); 509 va_end(args); 510 511 return r; 512 }
KERNELDIR = /usr/src/linux PWD := $(shell pwd) #INSTALLDIR = /home/tekkaman/working/rootfs/lib/modules CC = $(CROSS_COMPILE)gcc obj-m := hello.o moudles: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: cp hello.ko $(INSTALLDIR) clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
#make #insmod ./hello.ko #rmmod hello % make make[1]: Entering directory `/usr/src/linux-2.6.18' CC [M] /root/test/hello.o Building modules, stage 2. MODPOST CC /root/test/hello.mod.o LD [M] /root/test/hello.ko make[1]: Leaving directory `/usr/src/linux-2.6.18' % su root#
[root@bc root]#insmod hello.ko [root@bc root]#hello world enter[root@bc root]#rmmod hello [root@bc root]#hello world exit [root@bc root]#dmesg -c
Compiling kernel modules(An Example) The make file accompany the example KERNELDIR = /usr/src/linux PWD := $(shellpwd) #INSTALLDIR = /home/rootfs/lib/modules #CROSS_COMPILE = /usr/local/arm/2.95.3/bin/arm-linux- CC = $(CROSS_COMPILE)gcc obj-m := hello.o moudles: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules modules_install: cp hello.ko $(INSTALLDIR) clean: rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions