linux设备模型与字符设备驱动.ppt
设备驱动模块的加载 设备驱动程序被静态编译到内核中的情况: module_init()宏是内核在启动过程中运行设备的初始化函数,驱动程序的加载随内核的启动一起完成。 静态编译的内核模块不能被动态卸载,只有到系统关闭时由内核执行相应的卸载函数,如module_exit()。 设备驱动程序被动态加载到内核中的情况: 首先,驱动程序需要被编译成目标文件,如demo.o或demo.ko。 在操作系统运行之后,使用insmod命令将驱动程序模块动态加载到内核中 $ insmod demo.ko 使用insmod命令动态加载的内核模块可以使用rmmod命令动态地从内核中卸载 $ rmmod demo.ko 使用内核的动态模块加载/卸载功能需要内核支持kmod功能。 设备驱动程序的使用方法 应用层使用open、close、read、write系统调用——需要编写应用程序 使用系统命令可以进行最基本的测试: cat /dev/urandom echo /dev/urandom > /dev/fb0 dd if=/dev/touchscreen of=/var/tmp/test bs=16 count=100 设备驱动程序的使用方法 设备驱动程序的使用方法 应用层使用open、close、read、write系统调用——需要编写应用程序 使用系统命令可以进行最基本的测试: cat /dev/urandom echo /dev/urandom > /dev/fb0 dd if=/dev/touchscreen of=/var/tmp/test bs=16 count=100 Linux内核硬件驱动标准模板 #include #include #include static int __init name_of_initialization_routine(void) { /* code here */ } static void __exit name_of_cleanup_routine(void) { /* code here */ } module_init(name_of_initialization_routine); module_exit(name_of_cleanup_routine); module_init(1) include/linux/init.h中 #define module_init(x)__initcall(x); #define __initcall(fn) device_initcall(fn) #define device_initcall(fn)__define_initcall(fn, 6) #define __define_initcall(fn, id) \ static initcall_t __initcall_##fn##id __used \ __attribute__((__section__(".initcall" #id ".init"))) = fn module_init(2) static initcall_t __initcall_fn6 __used \ __attribute__((__section__(".initcall6.init"))) = fn typedef int (*initcall_t)(void); arch/arm/kernel/vmlinux.lds文件中: __initcall_start = .; *(.initcallearly.init) __early_initcall_end = .; *(.initcall0.init) *(.initcall0s.init) *(.initcall1.init) *(.initcall1s.init) *(.initcall2.init) *(.initcall2s.init) *(.initcallrootfs.init) *(.initcall6.init) *(.initcall6s.init) __initcall_end = .; init/main.c文件中定义了do_initcalls函数 __init宏 在include/linux/init.h中 对于非模块加载的驱动程序: #define __init__attribute__ ((__section__ (".text.init"))) 通过__init,会把函数中的代码放到.text.init段。这个段在系统启动以后会被