一、内核获取DTB文件
1、bootloader启动内核时,会设置r0,r1,r2三个寄存器:
r0一般设置为0;
r1一般设置为machine id (在使用设备树时该参数没有被使用);
r2一般设置ATAGS或DTB的开始地址
2、通过head.S head-common.S处理,获得dtb文件指针__atags_pointer
bl __lookup_processor_type //使用汇编指令读取CPU ID, 根据该ID找到对应的proc_info_list结构体(里面含有这类 CPU 的初始化函数、信息)
bl __vet_atags //判断是否存在可用的ATAGS或DTB
bl __create_page_tables //创建页表, 即创建虚拟地址和物理地址的映射关系
b __enable_mmu //使能MMU, 以后就要使用虚拟地址了
ldr r13, =__mmap_switched //上述函数里将会调用__mmap_switched
3、//r9 = processor ID
__mmap_switched:
//缓存 r1 r2
mov r7, r1
mov r8, r2
__mmap_switched_data:
.long processor_id @ r0
.long __machine_arch_type @ r1
.long __atags_pointer @ r2
adr r4, __mmap_switched_data //将存储变量的地址赋给r4
4、//将u-boot传递给内核的参数r0 r1 r2 分别赋给C变量 processor_id、__machine_arch_type、__atags_pointer
ldmia r4, {r0, r1, r2, r3}
str r9, [r0] @ Save processor ID
str r7, [r1] @ Save machine type
str r8, [r2] @ Save atags pointer
二、内核解析dtb文件匹配单板
内核支持很多单板,每个单板在内核中都有一个machine_desc来描述,而在dtb文件中,在根节点以compatible这个属性描述这个单板。所以内核匹配单板的过程就是machine_desc中dt_compat与dtb中根节点compatible匹配的过程。
1、以jz2440这块单板为例:
dtb文件:
compatible = "samsung,smdk2440";
//arch/arm/mach-s3c24xx/mach-smdk2440.c
static const char *const smdk2440_dt_compat[] __initconst = {
"samsung,s