目录
1. 驱动模板
1.1. 在源码工程路径下创建.c文件
1.2. 编写驱动模板
1.3. 将模板放到ubuntu上
1.4. 书写Makefile
1.5. 编译和安装
2. printk
2.1. Source Insight查找命令
2.2. printk讲解
2.2.1. 分析函数
2.2.2. 编写代码
2.3. 拓展
2.3.1. 关于printk函数测验用到的命令(掌握)
2.3.2. 赋值知识点
2.3.3. 打印级别的修改
驱动模块由三部分组成:
- 入口(安装):资源的申请
- 出口(卸载):资源的释放
- 许可证:GPL
1. 驱动模板
1.1. 在源码工程路径下创建.c文件
1.2. 编写驱动模板
//头文件支持
#include <linux/init.h>
#include <linux/module.h>
//static防止别人用重名函数
static int __init hello_init(void)//入口:资源申请
{
//_init将hello_init放到.init.text段中
return 0;
}
//static防止别人用重名函数
static void __exit hello_exit(void)//出口:资源释放
{
//_exit将hello_exit放到.exit.text段中
}
module_init(hello_init);//告诉内核驱动的入口地址
module_exit(hello_exit);//告诉内核驱动的出口地址
MODULE_LICENSE("GPL");//许可证
将文件保存到桌面上
1.3. 将模板放到ubuntu上
重点注意:此时的hello.c和任何工程都没关系是我们自己写的
作者将hello.c放在/home/hq/temp/demo下(非必须放到此处,自己决定)
1.4. 书写Makefile
KERNELDIR:=/lib/modules/$(shell uname -r)/build
#KERNELDIR:=/home/hq/temp/kernel-3.4.39/
PWD:=$(shell pwd)
all:
make -C $(KERNELDIR) M=$(PWD) modules
clean:
make -C $(KERNELDIR) M=$(PWD) clean
obj-m:=hello.o
Makefile解析:
KERNELDIR:= b/modules/$(shell uname -r)ild/:这行代码定义了一个变量KERNELDIR,它指定了内核源代码的路径。它使用了uname -r命令来获取当前正在运行的内核的版本号,并将其与b/modules/路径拼接在一起。这样可以确保构建模块时使用正确的内核版本。
PWD:=$(shell pwd):这行代码定义了一个变量PWD,它表示当前目录的路径。pwd命令用于获取当前工作目录的路径,这样可以确保在构建模块时使用正确的路径。
all: :这是一个目标规则,表示默认目标。在这个规则下,它定义了要执行的命令。
make -C $(KERNELDIR) M=$(PWD) modules:这是all目标的命令。它使用make命令来构建内核模块。-C选项指定了内核源代码的路径,M选项指定了模块源代码的路径,modules表示构建模块。因此,这个命令告诉make在指定的内核源代码路径下构建模块。
clean: :这是另一个目标规则,用于清理构建过程中生成的文件。
make -C $(KERNELDIR) M=$(PWD) clean:这是clean目标的命令。它使用make命令来清理构建过程中生成的文件。与all目标类似,它使用-C选项指定了内核源代码的路径,M选项指定了模块源代码的路径,clean表示清理。
obj-m:=hello.o:这行代码定义了一个变量obj-m,它指定要构建的目标模块的名称为hello.o。在这个Makefile中,hello.o是一个示例模块的名称,你可以根据自己的需求修改它。
这个Makefile的作用是通过调用内核源代码中的Makefile来构建指定的内核模块。它通过设置正确的内核源代码路径和模块源代码路径,然后执行make命令来完成构建和清理操作。
1.5. 编译和安装
在hello.c和Makefile同级目录下执行make命令
得到下面文件
、
这个.ko后缀的文件是不是很熟悉?(在驱动移植篇)
我们查看Makefile
所以在ubuntu下安装就可
执行下面命令
sudo insmod hello.ko 安装命令
什么都没有发生,为什么?
拆卸命令sudo rmmod hello
2. printk
2.1. Source Insight查找命令
我们可以使用printk来进行测验
选中printk
按下ctrl+/
就能进入下面的查找页面
将使用例子放到printk处
2.2. printk讲解
2.2.1. 分析函数
printk和printf非常相似,只是多了一个打印级别
printk(KERN_ERR "SouthernBird\n")
在ubuntu下可以查看优先级别
cat /proc/sys/kernel/printk
2.2.2. 编写代码
//头文件支持
#include <linux/init.h>
#include <linux/module.h>
#include <linux/printk.h>
//static防止别人用重名函数
static int __init hello_init(void)//入口:资源申请
{
printk("SouthernBird\n");
//_init将hello_init放到.init.text段中
return 0;
}
//static防止别人用重名函数
static void __exit hello_exit(void)//出口:资源释放
{
printk("I am leave\n");
//_exit将hello_exit放到.exit.text段中
}
module_init(hello_init);//告诉内核驱动的入口地址
module_exit(hello_exit);//告诉内核驱动的出口地址
MODULE_LICENSE("GPL");//许可证
将代码放到ubuntu下重新编译(注makefile,目前不需要进行修改)
安装试验
我们可以看到什么都没打印,这是因为ubuntu开发人员将其屏蔽了
我们可以使用dmesg命令进行查看
2.3. 拓展
2.3.1. 关于printk函数测验用到的命令(掌握)
sudo insmod hello.ko 安装驱动模块
sudo rmmod hello 卸载驱动模块
lsmod 查看模块
dmesg 查看消息
sudo dmesg -C 直接清空消息不回显
sudo dmesg -c 回显后清空
2.3.2. 赋值知识点
= :赋值 需要等其他文件全部执行完,才执行调用的
:= :立即赋值
+= :附加赋值
?= :询问变量之前是否被赋值过,如果被赋值过本次赋值不成立
2.3.3. 打印级别的修改
》1.修改系统默认的级别
su root
echo 4 3 1 7 > /proc/sys/kernel/printk
》2.如果想修改开发板对应的打印级别
vi rootfs/etc/init.d/rcS
echo 4 3 1 7 > /proc/sys/kernel/printk