构建Linux系统的驱动从原料、方法到应用层调用

总论:构建Linux系统的驱动是一种环环相扣的困难事,这种困难主要是驱动被包含在操作系统内核中,使得驱动被迫遵循Linux的各种规则。本文试图从原料、方法和应用层调用角度构建Linux系统驱动。本文不是阐述动态加载驱动模块,而是一开始将驱动编进内核的做法。从构建Linux可以体现线性和感性思维被一个个细节肢解,但掌握构建过程和细节对于工作很有帮助。

1、uboot原料

booltoader已经被各家SOC、CPU厂商做的高度碎片化,简单理解为只有一个事物就是错误的。

比如三星的4段B,BL0=ROM boot,BL1=三星加密启动代码一般叫XXX.bl1.bin,BL2=自己编写代码(itop_4412_android_config),通过mkbl2工具生成(取BL3部分14336byte),用于初始化的、校验u-boot-spl.bin(14K去掉BL1),BL3=真正的官方的uboot源码编译生成。

比如NXP的2段bootloader,头部是uboot.imx主要包含IVT header、 Boot data、DCD header,尾段是uboot剩下的部分。

Android uboot引导后有两个三个选择——recovery、OS、fastboot。

2、Uboot编译和烧录

一般编译都是写一个shell脚本调用makefile、uboot.lds(链接文件)实现,烧录的方法更加碎片化如三星的通过制作TF卡、NXP特殊的MFGTools等。

3、uboot与内核源码里的设备树

设备树本属于内核源码一部分,可是内核不想集成进去想单独生成一个设备硬件描述文件好修改,但是一旦从内核独立开来又要uboot做参数传导。一般通过R2寄存器传递设备dtb文件地址。

4、设备树与内核

在内核启动后一系列复杂的动作已经开始了,内核通过unflatten_device_tree()函数来解析dtb文件,构建一个由device_node结构连接而成的单向链表。

5、设备树信息准备好了,等待驱动注册时通过它与设备match

驱动的写法比较合乎常规就是module_init()、初始化驱动的设备树信息、注册驱动时寻找匹配的设备,匹配成功引发probe。在probe中会注册设备,此时主次设备号、设备操作函数都绑定好了提供给应用层调用。

6、内核的编译

Makefile里面的条件编译是由.config中的宏决定的,而.config中的宏是否被注释又是有make menuconfig中选择决定的,而make menuconfig中的是否存在这个配置选项则是由Kconfig决定的,由此串联起来了四者的关系。

这句话高度概括了内核配置。

编译内核又要写一个shell脚本调用makefile实现。连带将设备树也编好。

7、应用层调用

每一个注册成功设备都会在dev文件夹里生成一个设备文件,让应用层可以像引用文件一样操作设备。

8、构建根文件系统时对dev文件夹的操作

这个因为与内核设备驱动挂钩因此要通过mknod一个个创建设备文件(拿到设备名、主次设备号)或者自动生成。

mknod 的标准形式为:       mknod DEVNAME {b | c}  MAJOR  MINOR

9、驱动调试

内核驱动调试非常困难。首先要在下位机内核启用kgdb,上位机准备gdb和内核非压缩二进制文件(vmlinux),然后通过串口调试。这里还要改造uboot,就是加入kgdb支持参数。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值