61.linux 第三方驱动移植
在以往的思路里,我们想要实现一个功能,要进行驱动移植,这个时候其他人正好写完了这个驱动,我们直接将第三方的驱动移植到我们的内核中就可以正常使用了,此时别人的驱动写的很完善了,我不关注里面的实现,直接用到我的系统中,这种方法叫黑盒移植。
一.黑盒移植
编译驱动进内核
以一个灯的驱动为例,fs4412_led_drv.c
1.选择驱动存放目录
我们打开我们之前移植好的内核,因为它属于字符设备驱动放在drivers/char目录下,此时我们就可以直接make了吗?这层的makefile肯定是找不到这个文件的,是编译不上的。
2.修改当前子目录的Makefile
模仿其他驱动obj-y += fs4412_led_drv.o
这个时候编译就可以编译进来了。
可以通过应用程序对驱动进行验证。
3.修改Kconfig(方便管理)
我们平时改驱动就是使用菜单选配就完了,我们的这个第三方驱动也可以添加到菜单中。
打开子目录的Kconfig,进行模仿添加。但是需要注意的是修改了Kconfig,还需要再次修改 Makfile,Makfile才是最后编译选项的执行者,Kconfig只是一个图形界面选择。
obj-y += fs4412_led_drv.o 改为 obj-$(CONFIG_LED) += fs4412_led_drv.o
,配合kconfig变为动态的编译
[] 只有两种选项编译(y)或者不编译(n) , <> 三种选项 编译(y)、不编译(n)或者编译成模块(m)
上面的方法还需要改Makefile Kconfig然后进行编译,(自己写的驱动东一个西一个的不好管理)想将驱动和内核独立出来,对自己的一系列驱动进行管理。
编译驱动为独立的模块。
1. Makefile 编写(适用编译驱动的Makefile)
2. C程序代码编写(驱动编写)
3. 编译出 ko 模块
make modules 编译所有的模块
在linux运行时,可以动态装载和卸载模块
根据需要手动加载模块 insmod *.ko(更灵活的管控)
mknod (创建设备文件)
二 .白盒移植
就是进行内部详细的逻辑分析。
打印跟踪的方法,对驱动进行调试。
需要阅读阅读源码,熟悉驱动框架,才能进行跟踪调试
驱动框架:
字符设备和平台设备框架
设备驱动框架:
三、字符设备引入
1.一切设备皆文件
对设备的操作的就是 对设备文件的 read write
2. open read write ioctl
3. 将设备进行编号 设备号(主次设备号组成)
字符设备驱动相关
驱动编写阶段
1. 注册获取设备号(不同设备通过设备号进行区分)
2. 初始化设备
3. 操作设备 file_operations -- open release read write ioctl...(统一接口)
生成.ko后
insmod fs4412_led_drv.ko
mknod /dev/led c 501 0 //创建设备文件,字符设备,主设备号,次设备号
4. 两个宏定义 module_init module_exit 两个命令 insmod (加载) rmmod
驱动是被动调用的,是被应用程序触发的
应用程序的 open 调用到驱动的file_operations 的 open
应用程序的 read 调用到驱动的file_operations 的 read
应用程序的 write 调用到驱动的file_operations 的 write
应用程序的 ioctl 调用到驱动的file_operations 的 ioctl
应用程序的 close 调用到驱动的file_operations 的 release
四、平台设备引入
驱动里的详细操作:
1. 寄存器的地址值是根据芯片手册 和原理图找到的
2. 对寄存器地址内容操作不能直接使用物理地址,需要ioremap
3. ioremap 将物理地址 映射到虚拟地址
4. platform 用于将硬件信息 和驱动代码做分离
5. 从设备树中通过名字匹配,匹配成功执行 probe函数
6. 驱动通过 platform_get_resource 获取硬件设备资源
7. 作用 容易维护
驱动框架---》平台设备框架---》设备树