1 设备树是如何被编译的?—TBD
2 设备树是如何被uboot加载并被Linux使用的?—TBD
3 设备树如何反编译? —TBD
设备树如何被内核找到的?
设备树(Flat Device Tree)是在Linux3.0 被引入的。起因是Linux忍受不了ARM驱动程序需要编写platform device部分的代码。
这里不得不提引导程序,一般情况下,Linux使用 U-Boot作为bootloader,那么uboot必然承担这初始化Linux运行需要的环境条件的责任。在设备启动的过程中,通常会使用gpio的组合或者不同的电阻来标明设备的不同版本或者不同的产品形态。那么如果设备文件中存在多个dtb文件的时候,则会根据硬件的不同版本选择对应的dtb文件。
U-Boot 传递给内核参数的方法有很多种,这里说的方法是通过寄存器传递的方式。dtb文件的地址就是通过寄存器r2来进行传递的。
//把dtb的地址传到r2寄存器里
theKernel (0, bd->bi_arch_number, of_flat_tree);
U-Boot 通过环境变量存储启动Linux的信息,在uboot启动的最后阶段会调用run_main_loop()函数。此函数中会调用bootm_find_other函数来找到dtb文件。此处也有说法是找到ramdisk 此处需要再考证下。
那么现在第一个问题出现了:前面讲到可以通过硬件版本号找到设备的dtb文件和前面说的找到dtb文件好像是存在矛盾的。
此处简单补充下dts,dtc,dtb三者之间的关系,简单讲就是dtc可以将dts编译成dtb文件,也可以将dtb文件反编译生成dts文件。
了解上面这些,下面就可以来看一下dtb文件中的内容是如何被内核解析的了。
设备树如何被内核解析的
ARM64架构的内核的入口是标号_head,直接跳转到stext。在stext中会读取引导程序传递的四个参数,并且保存在boot_args中。并且设置处理器一场级别,创建页表映射,并调用函数_cpu_setup ,为开启处理器的内存管理单元做准备,初始化处理器。调用函数_primary_switch为主处理器开启内存管理单元,搭建c语言执行环境,进入c语言部分的入口函数_start_kernel。
cpu初始化过程中会通过cpu_read_enable_method获取cpu的信息并初始化。