设备树的传输和设备树的内核解析
U-Boot将设备树加载到内存中的指定位置后,ARM内核的SoC通过通用寄存器r2传输内存中dtb的地址。内核获得地址后,进一步处理dtb文件。
设备树的传输
使用bootm加载内核镜像时(bootz是bootm的封装和功能扩展,本质上是一样的)。U-Boot跳转到内核的入口函数是boot_jump_linux
该功能的c文件在arch/arm/lib下,说明传输设备树的方式与SoC架构有关。这个函数在不同的SoCs被调出时特别重要,它是U-Boot和内核之间连接和交换信息的关键API。在执行了U-Boot的这个功能之后,CPU的控制权就完全交给了内核。
/*子命令:GO */静态void boot _ jump _ Linux(bootm _ headers _ t * images,int标志)
{。
调试(# # #将控制权转移到Linux(地址为lx)
"。
",(ulong)kernel _ entry);
bootstate _ mark(bootstate _ ID _ RUN _ OS);
notify _ and _ clean up(假);
if(IMage _ ENABLE _ OF _ LIFDT images-> > ft _ len)
r2=(无符号长)图像-】ft _ addr;
其他
R2=GD-〉BD-〉bi _ boot _ params;
}
R2作为存储设备树地址的寄存器,有两种方式获取其值,即实例化BOOM _ Header _ T数据结构的ft_addr,使用U-Boot的板级启动参数作为设备树地址。
Bootm_header_t模式
bootm_header_t的数据结构定义如下,供各种内核的SoC使用。每个制造商根据自己的中央处理器的特性,对每个成员进行不同的实例化。
/*
* do _ bootm()和do_bootm_ 《os》()使用的旧版和FIT格式标头
*套路。
*/typedef struct bootm_headers {。
char * ft _ addr/*平面开发树地址*/
ulong ft _ len/*扁平设备树的长度*/。
} bootm _ headers _ t;
在bootm_header_t模式下,U-Boot需要支持设备树,文件不为空。
ft_len和ft_addr属于bootm_header_t,这两个成员在U-Boot解析镜像文件时被实例化。函数调用堆栈如下:
do_bootz(struct cmd_tbl *cmdtp,int标志,int argc,char *const argv[])
-bootz_start()
- bootm_find_images(int标志,int argc,char *const argv[],ulong start,ulong size)
- boot_get_fdt(flag,argc,argv,IH_ARCH_DEFAULT,images,images.ft_addr,images . ft _ len);
u-boot-v 2021.04/common/image-FDT . c
Gd-> BD-> bi _ boot _ params模式
这是一种比较古老的方式,目前基本没有采用。Bi_boot_params是用于存储内核启动参数的地址,通常在板级初始化中指定。
这里执行代码的时候,可以通过打印出来,用调试工具连接,确认r2是否是期望值。
按内核解析设备树
分析分为两个阶段,第一阶段是检查和重新调整启动参数;在第二阶段,设备树被解压缩,即设备树从FDT变为美国东部时间,并创建device_node。
第一阶段的
内核启动日志中与设备树相关的第一项打印如下,即打印当前硬件设备的型号名称,“of: FDT:机器型号:v2p-ca9”
在物理CPU0x0上启动Linux
Linux版本5.4.124 (qemu@qemu) (gcc版本6 . 5 . 0(Linaro GCC 6.5-2018.12))# 3 SMP
Fri Jun 25 1502 CST 2021CPU: ARMv7 Processor [410fc090] revision 0 (ARMv7), cr=10c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT nonaliasing instruction cache
OF: fdt: Machine model: V2P-CA9
这个模型名是在设备树文件的头部定义的,定义当前设备的总体名称。
// SPDX-License-Identifier: GPL-2.0/*
* ARM Ltd. Versatile Express
*
* CoreTile Express A9x4
* Cortex-A9 MPCore (V2P-CA9)
*
* HBI-0191B
*/
/dts-v1/;
#include “vexpress-v2m.dtsi”
/ {
model = “V2P-CA9”;
。。。
}
但这并不是 kernel 对设备树第一次进行处理的地方。在此之前已有其他的操作。函数调用栈如下:
setup_arch(char **cmdline_p) arch/arm/kernel/setup.c
atags_vaddr = FDT_VIRT_BASE(__atags_pointer);
setup_machine_fdt(void *dt_virt) arch/arm/kernel/devtree.c
early_init_dt_verify()
of_flat_dt_match_machine() drivers/of/fdt.c
early_init_dt_scan_nodes();
__machine_arch_type = mdesc-》nr;
第 2 行、__atags_pointer 是 dtb 在内存中的地址,这个地址在汇编阶段(若镜像为 zImage,那么在解压缩阶段就完成了)便获取到了。由于执行到 setup_arch 时 mmu 已经使能并且 4K 的段页表也已经完成了映射,而 U-Boot 传递给 kernel 的设备树 fdt 地址属于物理地址,因此需要将物理地址转换成虚拟地址。
head-common.S
.align 2
.type __mmap_switched_data, %object
__mmap_switched_data:
#ifdef CONFIG_XIP_KERNEL#ifndef CONFIG_XIP_DEFLATED_DATA
.long _sdata @ r0
.long __data_loc @ r1
.long _edata_loc @ r2
#endif
.long __bss_stop @ sp (temporary stack in .bss)
#endif
.long __bss_start @ r0
.long __bss_stop @ r1
.long init_thread_union + THREAD_START_SP @ sp
.long processor_id @ r0
.long __machine_arch_type @ r1
.long __atags_pointer @ r2
第一阶段对设备树的配置主要包括:
A 对 dtb 文件进行 crc32 校验,检测设备树文件是否合法 early_init_dt_verify()
B early_init_dt_scan_nodes()
/* Retrieve various information from the /chosen node */
of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
/* Initialize {size,address}-cells info */
of_scan_flat_dt(early_init_dt_scan_root, NULL);
/* Setup memory, calling early_init_dt_add_memory_arch */
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
C 更新__machine_arch_type
D 更新 chosen
上面这个 chosen 信息可以在 kernel 起来后再次查看做了哪些修改。
第二阶段
第二阶段单纯的是将设备树 ABI 文件进行解压缩,由 FDT 变成 EDT,生成相应的 device_node 结点。这个阶段的函数调用栈如下:
unflatten_device_tree();
*__unflatten_device_tree()
/* First pass, scan for size */
size = unflatten_dt_nodes(blob, NULL, dad, NULL);
/* Second pass, do actual unflattening */
unflatten_dt_nodes(blob, mem, dad, mynodes);
unflatten_dt_nodes()
populate_node()
device_nodes 结点如下:
device_node 创建完成后,kernel 创建 platform_device 时依据这个阶段完成的工作情况进行对应的设备注册,供驱动代码使用。
编辑:jq
延伸 · 阅读
- 2021-07-29 14:42英特尔博锐走进校园 看看它如何发挥高校数字化建设的作用
- 2021-07-29 14:42建设高可用不间断电源供电系统的原因及解决方案
- 2021-07-29 14:42继长鑫存储之后,兆易创新宣布与Rambus签订专利授权协议
- 2021-07-29 14:42关于自动导引车安全性的七个最常见问题
- 2021-07-29 14:42华为助力山东能源打造全球清洁能源供应商
- 2021-07-29 14:42快讯:研究人员发布数据集来训练冠状病毒聊天机器人