oppo n5117 root:Linux驱动编程 step-by-step (一)
来源:百度文库 编辑:偶看新闻 时间:2024/04/29 00:49:15
第三次看了LDD3了(虽然现在已经是kernel3.0但从这本书商还是能学到很多) 每次都有一些收获 现在终于能够些一些代码了
驱动程序的作用:
简单来说 驱动程序就是使计算机与设备通信的特殊的代码,在作单片机时候(无OS)我们自己定义借口及实现结构来操作相关硬件,而在有OS的模式下我们应对,相应的硬件实现对应的借口,才能正确的控制设备。
编写驱动考虑的因素
提供给用户更多的选项
保持用户操作的简单性
编写驱动的时间
驱动分类:
字符设备:能够像字节流(类似文件)一样被访问的设备(至少实现open, close, read ,write等功能)
快设备: 用户空间接口与字符设备相同, 内部实与字符设备完全不同(可以被随即访问,一般在类UNIX系统中快设备的读取每次只能读一整块在linux可以操作任意字节)
网络设备:网络事物通过网络设备形成,能够与主机交换数据的设备
内核功能划分:
进程管理(PM):进程的创建于撤销,在单个或者多个CPU上实现多个进程的抽象
内存管理(MM):管理内存分配及回收的策略
文件系统(FS/VFS): Linux 非常依赖于文件系统,内核在没有结构的硬件系统上构造结构华的文件系统,而文件抽象在整个系统中会广泛使用,Linux会支持多种文件系统类型
设备控制:驱动程序,操控硬件以及相应总线设备
网络(NET): 在网络接口于应用程序之间传输数据。
好了 理论行得东西介绍的差不多了,下边说点有用的,内核的驱动可以做成模块在需要的时候装载,在不需要的时候卸载
我们在编写用户程序的时候总喜欢从编写hello world 写起 , 可内核驱动模块也是一样,下边是一个hello_world的一个模块
//hello_world.c
#include
#include
MODULE_LICENSE("GPL");
static int hello_init(void)
{
printk(KERN_ALERT "hello module\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "hello module exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
以及对应的Makefile
ifneq ($(KERNELRELEASE),)
# call from kernel build system
obj-m := hello_world.o
#if we need more than one source code to build the module
#we should use the variable below: example: modules-objs := file1.o file2.o
modules-objs :=
else
#kernel PTAH
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
有几点与用户空间程序不同的地方
模块程序没有main函数(那么程序入口在哪里?)
打印函数使用的printk 而不是用户空间的printf 而且使用方式不一样
模块的编译不是通常的方式
头文件不是常见的那些头文件
以及编译之后不会产生可执行文件,而是 .ko 文件
...
模块没有main函数,在装载模块 insmod 时会调用module_init注册的函数 此处为hello_init
在模块卸载remod时 会调用module_exit注册的函数 此处为hello_exit
在module_init 注册的函数主要是进行初始化,分配内存, 注册设备等
而module_exit中注册的函数与之相反, 设备注销, 释放内存等
具体的编译模块的Makefile我在另一篇文章中有说到 此处不再赘述
内核的打印函数使用printk去打印信息, printk不支持浮点类型, 在printk中可以加入信息级别有7中
#define KERN_EMERG "<0>" /* system is unusable */
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */
对应与不同的错误等级 选择不懂的option, 并做不同的处理, 小于一定等级的信息会直接打印到终端(非X-window下的终端),可以使用dmesg来查看全部的打印信息
编译内核的头文件是在/lib/modules/$(shell uname -r)/build/include下得,而不是用户模式下得/usr/include
编译后不会生产可执行文件,会生成一个.ko的文件
使用insmod xxx.ko去装载模块
使用lsmod去查看已装载的模块
驱动程序的作用:
简单来说 驱动程序就是使计算机与设备通信的特殊的代码,在作单片机时候(无OS)我们自己定义借口及实现结构来操作相关硬件,而在有OS的模式下我们应对,相应的硬件实现对应的借口,才能正确的控制设备。
编写驱动考虑的因素
提供给用户更多的选项
保持用户操作的简单性
编写驱动的时间
驱动分类:
字符设备:能够像字节流(类似文件)一样被访问的设备(至少实现open, close, read ,write等功能)
快设备: 用户空间接口与字符设备相同, 内部实与字符设备完全不同(可以被随即访问,一般在类UNIX系统中快设备的读取每次只能读一整块在linux可以操作任意字节)
网络设备:网络事物通过网络设备形成,能够与主机交换数据的设备
内核功能划分:
进程管理(PM):进程的创建于撤销,在单个或者多个CPU上实现多个进程的抽象
内存管理(MM):管理内存分配及回收的策略
文件系统(FS/VFS): Linux 非常依赖于文件系统,内核在没有结构的硬件系统上构造结构华的文件系统,而文件抽象在整个系统中会广泛使用,Linux会支持多种文件系统类型
设备控制:驱动程序,操控硬件以及相应总线设备
网络(NET): 在网络接口于应用程序之间传输数据。
好了 理论行得东西介绍的差不多了,下边说点有用的,内核的驱动可以做成模块在需要的时候装载,在不需要的时候卸载
我们在编写用户程序的时候总喜欢从编写hello world 写起 , 可内核驱动模块也是一样,下边是一个hello_world的一个模块
//hello_world.c
#include
#include
MODULE_LICENSE("GPL");
static int hello_init(void)
{
printk(KERN_ALERT "hello module\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "hello module exit\n");
}
module_init(hello_init);
module_exit(hello_exit);
以及对应的Makefile
ifneq ($(KERNELRELEASE),)
# call from kernel build system
obj-m := hello_world.o
#if we need more than one source code to build the module
#we should use the variable below: example: modules-objs := file1.o file2.o
modules-objs :=
else
#kernel PTAH
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
有几点与用户空间程序不同的地方
模块程序没有main函数(那么程序入口在哪里?)
打印函数使用的printk 而不是用户空间的printf 而且使用方式不一样
模块的编译不是通常的方式
头文件不是常见的那些头文件
以及编译之后不会产生可执行文件,而是 .ko 文件
...
模块没有main函数,在装载模块 insmod 时会调用module_init注册的函数 此处为hello_init
在模块卸载remod时 会调用module_exit注册的函数 此处为hello_exit
在module_init 注册的函数主要是进行初始化,分配内存, 注册设备等
而module_exit中注册的函数与之相反, 设备注销, 释放内存等
具体的编译模块的Makefile我在另一篇文章中有说到 此处不再赘述
内核的打印函数使用printk去打印信息, printk不支持浮点类型, 在printk中可以加入信息级别有7中
#define KERN_EMERG "<0>" /* system is unusable */
#define KERN_ALERT "<1>" /* action must be taken immediately */
#define KERN_CRIT "<2>" /* critical conditions */
#define KERN_ERR "<3>" /* error conditions */
#define KERN_WARNING "<4>" /* warning conditions */
#define KERN_NOTICE "<5>" /* normal but significant */
#define KERN_INFO "<6>" /* informational */
#define KERN_DEBUG "<7>" /* debug-level messages */
对应与不同的错误等级 选择不懂的option, 并做不同的处理, 小于一定等级的信息会直接打印到终端(非X-window下的终端),可以使用dmesg来查看全部的打印信息
编译内核的头文件是在/lib/modules/$(shell uname -r)/build/include下得,而不是用户模式下得/usr/include
编译后不会生产可执行文件,会生成一个.ko的文件
使用insmod xxx.ko去装载模块
使用lsmod去查看已装载的模块
使用rmmod xxx 去卸载相应模块(卸载是不带.ko)
step by step 2000
《step by step》
step by step吉他谱
求一首歌,step by step
英语听力STEP BY STEP
step by step 免费下载?
STEP BY STEP是什么呢?
step by step 文本下载
setp by step 文本
武汉师范大学出的Step by Step
询问一首歌~<step by step>
询问一首歌~<step by step>
求Microsoft Press《Step by Step》下载
STEP BY STEP是哪个出版社的?
求step by step 1--4 文本
setp by step 听力下载
如何下载STEP BY STEP 的课文与听力
在哪免费下载Step by Step 听力材料
英语入门听力2000 step by step 电子书
那里可以快速下载英语听力入门2000step by step
谁有step by step 2000的听力答案,急需!!
哪里可以下载step by step的 mp3版?
谁有step by step 2000的听力答案,急需!!
谁有step by step 2000的听力答案,急需!!