Linux设备树在内核中的作用

内核head.S对dtb的处理

1、bootloader启动内核时,会设置r0,r1,r2三个寄存器,

r0一般设置为0;
r1一般设置为machine id (在使用设备树时该参数没有被使用);
r2一般设置ATAGS或DTB的开始地址

2、machine id在kernel中的使用

在这里插入图片描述

3、内核hend.S的主要处理事项

a. __lookup_processor_type : 使用汇编指令读取CPU ID, 根据该ID找到对应的proc_info_list结构体(里面含有这类CPU的初始化函数、信息)
b. __vet_atags : 判断是否存在可用的ATAGS或DTB
c. __create_page_tables : 创建页表, 即创建虚拟地址和物理地址的映射关系
d. __enable_mmu : 使能MMU, 以后就要使用虚拟地址了
e. __mmap_switched : 上述函数里将会调用__mmap_switched
f. 把bootloader传入的r2参数, 保存到变量__atags_pointer中
g. 调用C函数start_kernel
head.S/head-common.S :
把bootloader传来的r1值, 赋给了C变量: __machine_arch_type
把bootloader传来的r2值, 赋给了C变量: __atags_pointer // dtb首地址

4、machine_desc结构体使用流程

(1)、在设备树dts里面的根目录指定了compatible = “samsung,smdk2440”;
(2)、当uboot将sts的首地址传递给内核后。
(3)、内核去这个地址去读取这些字符串。
(4)、然后内核在和machine_desc这个结构体里面的板卡初始化函数去比较。
(5)、如果找到相应的compatible 字符串则调用这个板卡的初始化函数。
(6)、按compatible 中的顺序找,找到后就不在找了。

5、dts中的compatible定义

在这里插入图片描述

6、kernel中machine_desc的定义

在这里插入图片描述

7、machine_desc被放到内存中的某个段中

在这里插入图片描述

8、kernel调用machine_desc的过程

函数调用过程:
// init/main.c
start_kernel 
  // arch/arm/kernel/setup.c
  setup_arch(&command_line);  
	 //分析uboot传来的dts首地址  arch/arm/kernel/devtree.c
     mdesc = setup_machine_fdt(__atags_pointer); 
	   // 判断是否有效的dtb,判断dtb的头部,drivers/of/ftd.c
        early_init_dt_verify(phys_to_virt(dt_phys)  
	       //保存dts首地址
           initial_boot_params = params;
		       // 找到最匹配的machine_desc, drivers/of/ftd.c
               mdesc = of_flat_dt_match_machine(mdesc_best, arch_get_next_mach);  
                    //一个一个的取出machine_desc来做判断
					while ((data = get_next_compat(&compat))) {
    
    
						score = of_flat_dt_match(dt_root, compat);
						if (score > 0 && score < best_score) {
    
    
							best_data = data;
							best_score = score;
						}
                    }            
        machine_desc = mdesc;

猜你喜欢

转载自blog.csdn.net/qq_18077275/article/details/108850445