2023年6月26日发(作者:)
驱动学习1:第⼀个驱动⼊门Linux驱动程序,⾸先应该知道它是linux的内核模块。Linux内核模块是使得复杂⽽庞⼤的linux内核条理清晰、可裁剪、⾼兼容性的重要特性。
Linux内核模块的特点:1, 模块本⾝不被编译进内核镜像,能够控制内核的⼤⼩。2, 模块可以在需要的时候中被动态加载,⼀旦加载完成就和内核其它部分完全⼀样。
下⾯便是linux内核模块的helloworld程序,结构⼗分固定。(1) 模块加载函数当通过insmod或者modprobe命令加载内核模块时,模块的加载函数会⾃动执⾏,完成本模块的相关初始化⼯作(2) 模块卸载函数当通过rmmod命令卸载内核模块时,模块的卸载函数会⾃动执⾏,完成本模块的卸载功能(3) 模块许可证声明如果不声明LICENSE,模块被加载时,将收到内核被污染(Kernel Tainted)的警告。(4) 模块参数(可选)模块参数是模块被加载的时候可以传递给它的值,它本⾝对应模块内部的全部变量(5) 模块导出符号(可选)内核模块可以导出的符号(symbol,对应函数或变量),若导出,则其他模块可以使⽤本模块中的变量或函数(6) 模块作者等信息声明(可选)
这个驱动并不具有任何控制硬件的⾏为,只是为了展⽰linux驱动的通⽤结构。这⼏乎是所有驱动程序的通⽤模版,如led的驱动程序,只需要在hello_ioctl函数中根据不同的传⼊参数操作gpio寄存器即可。(应⽤层没有操作硬件的权限,⽽内核中具有所有权限。驱动程序的作⽤就是⾼效的、封装的、有限的向应⽤层提供服务)代码: 1 /*
2 hello.c - The simplest kernel module. 3 */ 4 #include
11 #include
15 /* Standard module information */16 MODULE_LICENSE("GPL");17 MODULE_AUTHOR("pp.");18 MODULE_DESCRIPTION("hello module template ");19
20 #define DRIVER_NAME "hello"21
22 unsigned myint = 0xdeadbeef;23 char *mystr = "default";24
25 module_param(myint, int, S_IRUGO);26 module_param(mystr, charp, S_IRUGO);27
28 static int __init hello_init(void)29 {30 printk(KERN_INFO "Hello module world.n");31 printk(KERN_INFO "Module parameters were (0x%08x) and "%s"n", myint,mystr);32
33 return 0;34 }35
36
37 static void __exit hello_exit(void)38 {39 printk(KERN_ALERT "Goodbye module world.n");40 }41
42 module_init(hello_init);43 module_exit(hello_exit);
编译后⽣成.ko⽂件,移植到开发板linux下测试默认情况下root@plnx_arm:/mnt# insmod
Hello module parameters were (0xdeadbeef) and "default"root@plnx_arm:/mnt# lsmod
Tainted: G
hello 817 0 - Live 0xbf004000 (O)root@plnx_arm:/mnt# rmmod hello
Goodbye module world.传⼊参数时:root@plnx_arm:/mnt# insmod myint=123 mystr="pp"Hello module parameters were (0x0000007b) and "pp"root@plnx_arm:/mnt# rmmod helloGoodbye module world.
通过其他的查询命令可以看到内核的输出:root@plnx_arm:/mnt# ls /sys/module/hello/parameters/myint mystrroot@plnx_arm:/mnt# tail -n 2 /var/log/messages
Jun 4 09:56:33 plnx_arm kernel: Hello module 4 09:56:33 plnx_arm kernel: Module parameters were (0x0000007b) and "pp"
在Linux下可以通过两种⽅式加载驱动程序:静态加载和动态加载。静态加载就是把驱动程序直接编译进内核,系统启动后可以直接调⽤。静态加载的缺点是调试起来⽐较⿇烦,每次修改⼀个地⽅都要重新编译和下载内核,效率较低。若采⽤静态加载的驱动较多,会导致内核容量很⼤,浪费存储空间。动态加载利⽤了Linux的module特性,可以在系统启动后⽤insmod命令添加模块(.ko),在不需要的时候⽤rmmod命令卸载模块,采⽤这种动态加载的⽅式便于驱动程序的调试,同时可以针对产品的功能需求,进⾏内核的裁剪,将不需要的驱动去除,⼤⼤减⼩了内核的存储容量。在台式机上,⼀般采⽤动态加载的⽅式;在嵌⼊式产品⾥,可以先采⽤动态加载的⽅式进⾏调试,调试成功后再编译进内核。
发布者:admin,转转请注明出处:http://www.yc00.com/web/1687753765a39584.html
评论列表(0条)