linux内核设备树及编译( 三 )

  • ② boot_jump_linux

linux内核设备树及编译

文章插图
 
以上是boot_jump_linux的片段代码,可以看出:若使用DTB,则原先用来存储ATAG的寄存器R2,将会用来存储.dtb镜像地址 。
boot_jump_linux最后将调用kernel_entry,将.dtb镜像地址传给内核 。
下面我们来看下内核的处理部分:
在arch/arm/kernel/head.S中,有这样一段:
linux内核设备树及编译

文章插图
 
_vet_atags定义在
/arch/arm/kernel/head-common.S中,它主要对DTB镜像做了一个简单的校验 。
linux内核设备树及编译

文章插图
 
真正解析处理dbt的开始部分,是setup_arch->setup_machine_fdt 。这部分的处理在第五部分的machine_mdesc中有提及 。
linux内核设备树及编译

文章插图
 
如图,是setup_machine_fdt中的解析过程 。
  • 解析chosen节点将对boot_command_line进行初始化 。
  •  解析根节点的{size,address}将对dt_root_size_cells,dt_root_addr_cells进行初始化 。为之后解析memory等其他节点提供依据 。
  •  解析memory节点,将会把节点中描述的内存,加入memory的bank 。为之后的内存初始化提供条件 。
  •  解析设备树在函数unflatten_device_tree中完成,它将.dtb解析成device_node结构(第五部分有其定义),并构成单项链表,以供OF的API接口使用 。
下面主要结合代码分析:/drivers/of/fdt.c
linux内核设备树及编译

文章插图
 

linux内核设备树及编译

文章插图
 

linux内核设备树及编译

文章插图
 

linux内核设备树及编译

文章插图
 

linux内核设备树及编译

文章插图
 

linux内核设备树及编译

文章插图
 

linux内核设备树及编译

文章插图
 
总的归纳为:
① kernel入口处获取到uboot传过来的.dtb镜像的基地址
② 通过early_init_dt_scan()函数来获取kernel初始化时需要的bootargs和cmd_line等系统引导参数 。
③ 调用unflatten_device_tree函数来解析dtb文件,构建一个由device_node结构连接而成的单向链表,并使用全局变量of_allnodes保存这个链表的头指针 。
④ 内核调用OF的API接口,获取of_allnodes链表信息来初始化内核其他子系统、设备等 。




推荐阅读