您的位置:首页 > 运维架构 > Linux

Linux驱动程序学习备忘之一

2014-04-01 14:39 190 查看
以前断断续续也看过一些linux驱动程序的内容,只知道这个很高深东西。也想过学习一下,但是来来回回,始终实在HelloWorld阶段,话说这个HelloWorld模块已经被我写了n遍了。



终于我决心要系统的走一边这个流程,于是周末去图书馆借了一本讲嵌入式驱动的书,《深入浅出嵌入式底层软件开发》主要从这本书的第8章开始看起。

在学习驱动之前,首先要明确:设备驱动程序的作用是在于提供机制,而不是提供策略,编写访问硬件的内核代码时,不要给用户强加任何策略。这个需要特别注意。

通常我们需要为每个驱动创建一个不同的模块,而不是在一个模块中实现多个设备的驱动。这里使用的思想是最小模块化,而不是通用化。最小模块化的好处在于可以实现良好的伸缩性和扩展性,并且在编写代码的时候,思路也会很清晰不需要考虑很多。

Linux系统将设备驱动分成三种:

字符设备

块设备

网络设备驱动和网络接口

字符设备:能够像字节流(如文件)一样访问设备

块设备:按照块为单位来访问数据,一块为512k,和字符设备的区别就是内核内部管理方式不同,应用程序一般通过文件系统间接地对快设备进行操作,块设备和文件系统关系紧密

网络设备驱动和网络接口:和字符设备和块设备有很大的不同

还是拿我写了很多遍的HelloWorld来举例,用来看看一个最简单的模块是如何生产、加载、卸载的。

首先是写代码,如下

hello.c

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

MODULE_LICENSE("GPL");

void __init hello_init(void)  //加载
{
printk("<0>Hello World! init\n");
}

void __exit hello_exit(void)  //卸载
{
printk("<0>Hello World! exit\n");
}

module_init(hello_init);  //此处可以省略,因为在函数前已经有__init修饰
module_exit(hello_exit);  //此处可以省略,因为在函数前已经有__exit修饰


Makefile

obj-m:=hello.o
PWD:=$(shell pwd)
KVER:=$(shell uname -r)
KDIR:=/lib/modules/$(KVER)/build

all:
$(MAKE) -C $(KDIR) M=$(PWD)
clean:
rm -rf *.o *.mod.c *.ko *.symvers *.order *.markers *~


把上面的两个文件放在同一个目录下面,然后运行命令行,

打入sudo make等待编译完成。

完成后,原来目录中多了好多文件,其中一个叫hello.ko,这个就是我们需要加载的文件。

在命令行中打入sudo insmod hello.ko,模块就加载了。

可以通过dmesg命令来查看加载是输出的信息,通过lsmod加grep可以查询对应模块是否已经加载,modinfo可以用来查看模块信息。

sudo rmmod hello.ko可以卸载模块。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: