tags: linux driver
由于目前关于linux driver的书中很少有写platform driver以及dts的(我看到的只有宋宝华的书里面写过),所以以前一直没研究这块……现在有需要,所以花了点时间研究一下,这里主要是记录整体思路和过程,至于细节没时间记录了,而且已经有人写的比较详细了,所以就不再记录。
首先记录几篇网上相关的文章,主要细节都在这几篇文章里面:
Linux设备树语法详解
高通平台中简单了解DTB
Linux3.x后的fdt 机制x
Linux内核很吊之 module_init解析 (下)
linux驱动 之 module_init解析 (上)
Linux Platform驱动模型(三) _platform+cdev
反正上面这些只是看看,主要还是要去看kernel代码,并且上板子跑,在一些关键点加些打印信息可以更直观的研究这部分内容
前面列的文章都是针对某平台,或者是arm的,但是arm64的居然跟这些又不一样……emmmmm……所以做下记录
使用的平台是高通820的一个开发板,跑的android7.x,linux kernel版本是3.x
arm64对于device tree的加载过程域arm不同,但最终具体执行加载所调用的函数依然相同
在创建platform device时,arm64直接调用的arm64_device_init(),没有调用init_machine,这点跟网上说的很不一样,也可能是不是开发板的原因?
dts文件为板级设备描述文件,被编译后为dtb,由bootloader读入,并作为参数传递给linux kernel,入口地址为__fdt_pointer,定义在汇编文件head.S (arch\arm64\kernel)中
linux加载device tree过程如下(由于csdn不支持markdown的序列图,所以是后期重新截图,看起来字体比较小……):
setup_machine_fdt()把dtb传入的数据入口地址设置给了initial_boot_params
unflatten_device_tree()根据initial_boot_params创建了device_node树
of_platform_populate()根据device_node树创建了platform_device树
最终:
of_platform_populate()->of_platform_bus_create()->of_platform_device_create_pdata()->of_device_add()->device_add()
并通过device_add()函数实现设备的注册,在device_add()源码的注释中有写明该函数为设备注册的第二步,一个设备若要注册,则该函数或者device_register()函数只允许将其中的一个函数调用1次。
同时,device_add()函数中还调用了bus_probe_device(),对驱动进行匹配探测。
关于arch_initcall_sync()的相关调用及原理见Linux内核很吊之 module_init解析 (下)及linux驱动 之 module_init解析 (上)
其中涉及到链接脚本(arch/mips/kernel/vmlinux.lds),这个东西暂时还未深入研究……