linux下编写hello驱动

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014695839/article/details/83513710

新建一个文件hello.c,编写如下代码:

#include <linux/init.h>
#include <linux/module.h>
#include <linux/moduleparam.h>

MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(void)
{
	printk(KERN_ALERT"Hello!\n");
	return 0;
}

static void hello_exit(void)
{
	printk(KERN_ALERT"Goodbye!\n");
}

module_init(hello_init);
module_exit(hello_exit);

新建一个Makefile文件,编写以下内容:

KERN_DIR = /lib/modules/$(shell uname -r)/build

all:
	make -C $(KERN_DIR) M=`pwd` modules

clean:
	make -C $(KERN_DIR) M=$(shell pwd) modules clean
	rm -rf modules.order

obj-m := hello.o

然后在终端输入:

$ make (即可在目录下看到生成的驱动模块hello.ko文件)

$ sudo insmod hello.ko (将模块加载入内核)

$ sudo rmmod hello (移除指定的内核模块)

本驱动在x86 上测试的, printk 打印出来的信息会在日志文件里。

因此,想查看printk打印的内容,还需要输入:

$ dmesg

结果:

[30664.513378] Goodbye!
[30666.802957] Hello!
 

下面是对makefile的一些备注:

1、操作符“”:=" 和 操作符“=”的解释

":="操作符实现简单的变量扩展,当右边是变量时,“:=”操作符左边的变量引用右边变量的当前值,它与"="操作符有点区别,“=”操作符实现递归的变量扩展,当右边是变量时,左边变量引用后面的变量,当后边变量值发生变化时,左边变量的值也跟着改变,如:
#b = 4
#a = $(b)
#b = 100
#最后a的值为100,而
#b = 4
#a := $(b)
#b = 100
#最后a的值为4
#其中 = 和 := 的区别在于, := 只能使用前面定义好的变量, = 可以使用后面定义的变量

2、KERN_DIR = /lib/modules/$(shell uname -r)/build 的解释

$(shell uname -r):这个shell应该是make里面的一个函数,shell函数把执行操作系统命令后的输出作为函数返回。函数调用很像变量的使用,也是以“$” 来标识的,其语法:$(<function> <arguments> )或是${<function> <arguments>},<function> 是函数名,<arguments> 是函数的参数,参数间以逗号“,” 分隔,而函数名和参数之间以“ 空格” 分隔。

3、all: 的解释

all是一个目标。一般来说,make命令可以指定目标目标(即:$ make 目标名称),例如$make clean 中的clean也是一个目标名称)。make命令在没有指定目标的情况下,会默认执行第一个目标(在这里是all)下的内容。

4、make -C $(KERN_DIR) M=`pwd` modules 的

-C 选项的作用是指将当前工作目录转移到指定的位置,-C $(KERN_DIR) 指明跳转到内核源码目录下,读取那里的Makefile。

M是内核根目录下的Makefile中使用的变量,“M=”的作用是在make命令中对变量M进行赋值。当用户需要以某个内核为基础编译一个外部模块的话,需要在make modules 命令中加入“M=dir”,表示包含dir下的Makefile文件,加入M选项后,程序会自动到你所指定的dir目录中查找模块源码,将其编译,生成KO文件(M=$(PWD) 表明返回到当前目录继续读入、执行当前的Makefile)。

modules是内核根目录下的Makefile的一个目标,表示编译成模块的意思(大约在Makefile的1253行,内核版本4.13.0-43-generic)。

5、obj-m := hello.o 的解释

obj-m表示把编译hello.c生成的文件hello.o编译成内核模块(不会编译到内核,但是会生成一个独立的 "hello.ko" 文件)。ko 文件是内核模块文件,是内核加载的某个模块,一般是驱动程序。
如果是obj-y,则表示把test.o文件编译进内核
不太懂得地方,我的猜测:obj-m和obj-y是变量,在内核目录的makefile中会被使用?

(注:本文内容参考自网上的资料和大神们的博客,感谢大家的分享)

猜你喜欢

转载自blog.csdn.net/u014695839/article/details/83513710