170 likes | 185 Views
chapter 2 - Hello World Model. chenbo2008@ustc.edu.cn 中国科学技术大学软件学院. Definition : Device drivers take on a special role in the Linux kernel.
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