驱动开发-1 模块hello world

        本文介绍在内核编译模块、加载和卸载模块的过程。

        首先开发环境是Linux-4.4.0+两份代码,hello.c+Makefile。

        这两份代码放到哪里呢?答案是哪里都可以,不过要注意放在一个文件夹下。这个文件夹的位置就是Makefile中的CURRENT_PATH,编译终端在这个文件夹打开就行。

hello.c

/*编写一个helloworld向内核输出*/
#include<linux/init.h>/*包含__init和__exit*/
#include<linux/module.h>/*必须包含*/

MODULE_LICENSE("Dual BSD/GPL");/*许可证,不然加载时会提示该模块污染内核*/

static char *name = "yr";
static int __init name_init(void)
{
	printk("hello world!\n");
	printk("hello %s!\n", name);
	return 0;
}

static void __exit name_exit(void)
{
	printk(KERN_INFO"NAME MODULE EXIT\n");
}

module_init(name_init);/*加载模块时调用初始化函数*/
module_exit(name_exit);/*卸载模块时*/
module_param(name, charp, S_IRUGO);

        关键部分有注释,不过这离中文注释要当心,博主一开始用的//被报错了。

Makefie如下:

#编译后模块名
obj-m:=hello.o 
#获取当前终端路径
CURRENT_PATH:=$(shell pwd)
#获取Linux内核路径名 
LINUX_KERNEL_PATH:=/usr/src/linux-source-4.4.0

all:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) modules #C 表示进入内核目录读取Makefile; M 表示回到当前目录读Makefile
clean:
	make -C $(LINUX_KERNEL_PATH) M=$(CURRENT_PATH) clean

        注意到makefile中的注释是#,$(shell + commond)就是命令行执行commond的效果。大家都清楚内核版本号用uname -r得到,内核源码路径LINUX_KERNEL_PATH怎么办呢?C文件中的可是引用内核中的头文件的。内核源码一般在/usr/src文件夹下,不幸的博主这个文件夹下有好多4.4.0开头的文件,这个方法不奏效。解决方法是在/lib/module/$(shell uname -r)/build,这里妥妥指的就是内核版本号啦。简单说是,如果你不清楚内核代码路径,Makefile中的LINUX_KERNEL_PATH:=/lib/module/$(shell uname -r)/build。


       在这两个文档所在文件下开终端,运行sudo make编译,成功的话,文件下会产生很多新文件,比如这样:

        然而这只是最后的结果,编译过程并没有看上去顺利。小提醒,一个大家可能会遇到的问题:***missing separator . Stop,一般是Makefile文件中两个make那一行开始需要用tab然而你用的是空格。如果用了tab还是会报同样的错——那你大概和博主遇到的问题一样。看看gredit的编辑->首选项->编辑器,把“使用空格代替tab”前面的选项去掉。


        现在已经编译好啦~ sudo insmod ./hello.ko 加载模块,可以使用lsmod看到你的模块,dmesg看到printk的内容。
       sudo rmmod hello卸载模块,lsmod看不到你的hello啦,dmesg可以看到对应printk的内容。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值