目录
1.常用命令:
lsmod(list module,将模块列表显示):功能是打印出当前内核中已经安装了哪些模块
分别为:模块名、大小以及被谁所使用。
insmod(install module,安装模块):功能是向当前内核中去安装一个模块,用法是insmod xxx.ko
modinfo(module information,模块信息):功能是打印出一个内核模块的自带信息。,用法是modinfo xxx.ko
rmmod(remove module,卸载模块):功能是从当前内核中卸载一个已经安装了的模块,用法是rmmod xxx(注意卸载模块时只需要输入模块名即可,不能加.ko后缀)
modprobe和depmod以后再说
2.insmod与module_init宏
module_int宏的作用是:将这个代码里的chrdev_init函数与insmod进行绑定,也就是说,当我们执行insmod xxx.ko时,实际上就是进行调用chrdev_init函数。
按照这样子的分析:那insmod时就应该能看到chrdev_init中使用printk打印出来的一个chrdev_init字符串,但是实际没看到。原因是ubuntu中拦截了,要怎么才能看到呢?在ubuntu中使用dmesg命令就可以看到了。
其次呢这里有一点:static的作用是将函数的连接属性从全局变为内部链接属性(防止在其他文件中出现同名的函数造成的冲突)(一般一个项目里,一个函数不被外界使用,只在内部使用,加上static)
这里还有一个知识点:函数修饰符
- __init,本质上是个宏定义
- __exit
3.模块的版本信息查看:
(1)使用modinfo查看模块的版本信息
(2)内核zImage中也有一个确定的版本信息
(3)insmod时模块的vermagic必须和内核的相同,否则不能安装,报错信息为:insmod: ERROR: could not insert module module_test.ko: Invalid module format
(4)模块的版本信息是为了保证模块和内核的兼容性,是一种安全措施
(5)如何保证模块的vermagic和内核的vermagic一致?编译模块的内核源码树就是我们编译正在运行的这个内核的那个内核源码树即可。说白了就是模块和内核要同出一门。
4.模块中常用宏
(1)MODULE_LICENSE,模块的许可证。一般声明为GPL许可证,而且最好不要少,否则可能会出现莫名其妙的错误(譬如一些明显存在的函数提升找不到)。
(2)MODULE_AUTHOR 模块的作者
(3)MODULE_DESCRIPTION 模块介绍
(4)MODULE_ALIAS 模块别名
5.printk函数:(调试程序是可以用到)
和printk函数是在内核源码钟用来打印学习的函数,用法和printf非常像
但是有区别:
1.
- printf是C库函数,是在应用层编程中使用的,不能在linux内核源代码中使用;
- printk是linux内核源代码中自己封装出来的一个打印函数,是内核源码中的一个普通函数,只能在内核源码范围内使用,不能在应用编程中使用。
2.
- printk相比printf多了一个“打印级别的设置”,用来控制printk打印的这条信息是否在终端上显示
- 在应用程序中,调试信息要么全都打开,要么全都关闭。(一般用DEBUG宏来实现)
- 但是在内核中,因为内核非常庞大,打印信息非常多,有时候整体调试内核时打印信息要么太多找不到想要的要么一个没有,没法调试。所以才有了打印级别这个概念。
打印机别:0-7
查看:
cat /proc/sys/kernel/printk
修改:
echo 4 >/proc/sys/kernel/printk
PS:修改的时候如果出现:bash: /proc/sys/kernel/printk: Permission denied的错误
原因分析:因为重定向符号 “>” 也是 bash 的命令。sudo 只是让 echo 命令具有了 root 权限,
但是没有让 “>” 命令也具有root 权限,所以 bash 会认为这个命令没有写入信息的权限。
解决:提升shell 权限。
sudo -s //提到root 权限。提示符为#
当你觉得该退回到普通权限时
sudo su username //退回到username 权限,提示符为$
好啦~~,回到正题:
操作系统的命令行中也有一个打印信息级别属性,值为0-7。当前操作系统中执行printk的时候会去对比printk中的打印级别和我的命令行中设置的打印级别,小于我的命令行设置级别的信息会被放行打印出来,大于的就被拦截的。譬如我的ubuntu中的打印级别默认是4,那么printk中设置的级别比4小的就能打印出来,比4大的就不能打印出来。
但是,ubuntu中这个printk的打印级别控制没法实践,ubuntu中不管你把级别怎么设置都不能直接打印出来,必须dmesg去查看。
6.关于驱动模块中的头文件
我们编写驱动时,包含的头文件和应用程序中包含的头文件不是一个概念。
应用编程中包含的头文件是应用层的头文件,是应用程序的编译器带来的(譬如gcc的头文件路径在 /usr/include下,这些东西是和操作系统无关的)。驱动源码属于内核源码的一部分,驱动源码中的头文件其实就是内核源代码目录下的include目录下的头文件。
比如:
如果需要mmc,我们就#include<linux/mmc/mmc.h>
总的来说就是要去内核文件中找。