linux系统驱动
1.驱动
定义:驱使硬件动起来的程序
种类:
- 裸机驱动:流程:需求分析–》查原理图–》查芯片手册–》code
- 系统驱动:流程:需求分析–》查原理图–》查芯片手册–》设备树–》code–》安装到内核中
1.1裸机开发&系统开发的优缺点?
裸机开发:成本低 运行效率高 安全性低 单任务
系统开发:成本高 运行效率低 安全性高 多任务
1.2应用程序和驱动程序的区别?
不同点 | 应用程序 | 驱动程序 |
---|---|---|
加载方式 | 主动加载 | 被动加载 |
运行空间 | 用户空间 | kernel空间 |
执行权限 | 低 | 高 |
影响力 | 局部 | 全局 |
函数来源 | 自定义/库/系统调用 | 内核函数/自定义 |
2 模块–》驱动模块
- 模块定义:能够单独命名并且独立完成一定功能的程序语句的集合(程序代码和数据结构)
- 驱动模块:能够单独命名并且独立完成特定外设功能驱动的程序语句的集合
- 注:一个驱动模块就是一个完整的外设驱动程序,驱动程序被安装到操作系统内核中,当该驱动程序对应的外设要工作时,该驱动模块被调用。
2.1如何写一个驱动模块?
- 模块初始化函数 int 函数名1(void)
- 模块清除函数 void 函数名2(void)
- 模块加载函数 module_init(函数名1)–》sudo insmod hello.ko
- 模块卸载函数 module_exit(函数名2)–》sudo rmmod hello.ko
- 声明该驱动遵守GPL–》MOUDULE_LICENSE("GPL”) GPL开源许可协议
《include/linux/init.h》
#define module_init(initfn)
static inline initcall_t __inittest(void)
{ return initfn; }
#define module_exit(exitfn)\
static inline exitcall_t __exittest(void)\
{ return exitfn; }
2.2如何编译驱动模块
hello.c–>hello.ko
test.c–>a.out
需要实现一个Makefile:
Makefile:
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
//进入/lib/modules/3.5.0-23-generic/build下执行Makefile,
将PWD路径下的代码编译成一个hello.o
else
obj-m := hello.o //将hello.o链接成hello.ko
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
Module* modules*
指令:lsmod :查看当前系统中已加载的驱动模块
sudo rmmod hello.ko 卸载一个已经存在的驱动模块
sudo insmod hello.ko 安装驱动模块
dmesg |tail:打印内核缓冲区的后十行
查看某一模块的信息描述
uname -r 查看内核版本号
2.3 将驱动模块安装到Linux内核中
sudo insmod hello.ko–>将驱动模块hello.ko安装到linux内核中
lsmod–>查看当前系统中所有已加载的驱动模块
dmesg |tail–>查看内核缓存区后10行打印信息
dmesg |tail -20–>查看内核缓存区后20行打印信息
modinfo hello.ko–>查看模块信息描述
sudo rmmod hello.ko–>将hello.ko从内核中移除
2.4将驱动代码分成两个文件
hello.c–>hello_init.c&hello_exit.c–>hello_init.o&hello_exit.o–>hello.ko
需要实现一个Makefile:
Makefile:
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
//进入/lib/modules/3.5.0-23-generic/build下执行Makefile,
将PWD路径下的代码编译成一个hello.o
else
obj-m := hello.o //将hello.o链接成hello.ko
hello-objs=hello_init.o hello_exit.o//将两个.o文件连接成一个hello.o文件
endif
clean:
rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions
Module* modules*