分析内核源码,设备树

U-Boot需要将设备树在内存中的存储地址传给内核。该树主要由三大部分组成:头(Header)、结构块(Structure block)、字符串块(Strings block)。

设备树在内存中的存储布局图如下


1.1 头(header


1.2 结构块(struct block

 扁平设备树结构块是线性化的树形结构,和字符串块一起组成了设备树的主体,以节点形式保存目标板的设备信息

  在结构块中,节点起始标志为32位常值宏OF_DT_BEGIN_NODE,节点结束标志为宏OF_DT_END_NODE

  子节点定义在节点结束标志前。一个节点的基本结构如下所示:

 (1). 节点起始标志OF_DT_BEGIN_NODE(即0x0000_0001);
 (2). 节点路径或者节点单元名(version < 3以及节点路径表示,version > 16时以节点单元名表示);
 (3). 填充字节保证四字节对齐;
 (4). 节点属性。

  每个属性以常值宏OF_DT_PROP 开始,后面依次为属性值的字节长度、属性名在字符串块中的偏移值,属性值及字节对齐填充段;

 (5). 如果存在子节点,则定义子节点

 (6). 节点结束标志OF_DT_END_NODE(即0x0000_0002)。

归纳起来,一个节点可以概括为以OF_DT_BEGIN_NODE开始,节点路径、属性列表、子节点列表以及OF_DT_END_NODE结束的序列,每一个子节点自身也是类似的结构。

1.3 字符串块(Strings block)

为了节省空间,对于那些属性名,尤其是很多属性名是重复冗余出现的,提取出来单独存放到字符串块。这个块中包含了很多有结束标志的属性名字符串。 在设备树的结构块中存储了这些字符串的偏移地址,因为可以很容易的查找到属性名字符串。字符串块的引入节省嵌入式系统较为紧张的存储空间。

1.4 设备树源码 DTS 表示

       设备树源码文件(.dts)以可读可编辑的文本形式描述系统硬件配置设备树,支持 C/C++方式的注释,该结构有一个唯一的根节点“/”,每个节点都有自己的名字并可以包含多个子节点。设备树的数据格式遵循了 Open Firmware IEEE standard 1275。这个设备树中有很多节点,每个节点都指定了节点单元名称。每一个属性后面都给出相应的值。以双引号引出的内容为 ASCII 字符串,以尖括号给出的是 32 位的16进制值。这个树结构是启动 Linux 内核所需节点和属性简化后的集合,包括了根节点的基本模式信息、CPU 和物理内存布局,它还包括通过/chosen 节点传递给内核的命令行参数信息。

1.5 machine_desc结构

      内核提供了一个重要的结构体struct machine_desc ,这个结构体在内核移植中起到相当重要的作用,内核通过machine_desc结构体来控制系统体系架构相关部分的初始化。machine_desc结构体通过MACHINE_START宏来初始化,在代码中, 通过在mian->setup_arch中调用setup_machine_fdt来获取。



1.6 设备节点结构体


1.7 属性结构体


三、设备树初始化及解析

分析Linux内核的源码,可以看到其对扁平设备树的解析流程如下

(1)首先在内核入口处将从u-boot传递过来的镜像基地址。
(2)通过调用early_init_dt_scan()函数来获取内核前期初始化所需的bootargs,cmd_line等系统引导参数。
(3)根据bootargs,cmd_line等系统引导参数进入start_kernel()函数,进行内核的第二阶段初始化。
(4)调用unflatten_device_tree()函数来解析dtb文件,构建一个由device_node结构连接而成的单项链表,并使用全局变量 of_allnodes 指针来保存这个链表的头指针。
(5)内核调用OF提供的API函数获取of_allnodes链表信息来初始化内核其他子系统、设备等
源码如下
在init目录下的main.c中的start_kernel函数中

进入这个setup_arch
其余代码先省略


查看setup_machine_fdt函数

这里调用了early_init_dt_scan_nodes函数


来看看这个函数


看看这个fdt_next_node函数


上面还有一个很重要的地方


这里,这里对这个initial_boot_parems进行赋值,这里这个指针指向了设备树的虚拟起始地址


在这里进行偏移,详细信息看这里的代码


chosen属性

chosen 节点并不代表一个真实的设备,只是作为一个为固件和操作系统之间传递数据的地方,比如引导参数。chosen 节点里的数据也不代表硬件。通常,chosen 节点在.dts 源文件中为空,并在启动时填充。在我们的示例系统中,固件可以往 chosen 节点添加以下信息:
chosen {
    bootargs = "root=/dev/nfs rw nfsroot=192.168.1.1 console=ttyS0,115200"; //节点属性
    linux,initrd-start = <0x85500000>; //节点属性
    linux,initrd-end = <0x855a3212>; //节点属性
};

1.2 根节点"/"
       设备树有且仅有一个根节点,即“/”,根节点下包含很多子节点,例入下图,根节点为"/",根节点的子节点为"chosen",根节点的属性包含"compatible","#address-cells","#size-cells","interrupt-parent"等。属性model指明了目标板平台或模块的名称,属性compatible值指明和目标板为同一系列的兼容的开发板名称。对于大多数32位平台,属性#address-cells和#size-cells的值一般为1。#address-cells = <1>; 1表示地址32位,2表示地址64位。#size-cells = <1>;1表示rangs的每部分占一个cell,依此类推 
 {
    compatible = "sprd,spx15";
    #address-cells = <1>;
    #size-cells = <1>;
    interrupt-parent = <&gic>;


    chosen {
        bootargs = "loglevel=8 console=ttyS1,115200n8 init=/init root=/dev/ram0 rw";
        linux,initrd-start = <0x85500000>;
        linux,initrd-end = <0x855a3212>;
    };
}
所以本函数就是读取根节点的"#address-cells","#size-cells"属性

1.3 memory节点
      memory节点用于描述目标板上物理内存范围,一般称作/memory节点,可以有一个或多个。当有多个节点时,需要后跟单元地址予以区分;只有一个单元地址时,可以不写单元地址,默认为0。此节点包含板上物理内存的属性,一般要指定device_type(固定为"memory")和reg属性。其中reg的属性值以<起始地址 空间大小>的形式给出,如下示例中目标板内存起始地址为0x80000000,大小为0x20000000字节。 
memory {
    device_type = "memory";
    reg = <0x80000000 0x20000000>;
};



在看看解析设备树这一块




  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
linux内核源码情景分析是指对linux内核源代码进行深入研究和分析,以了解其结构、功能和运行原理的过程。这个过程通常包括以下几个方面的内容分析: 首先,需要对内核的整体结构进行分析,理解各个组件的关系和工作原理。例如,内核由进程管理、内存管理、文件系统等子系统构成,分析每个子系统的实现细节有助于对内核的整体工作原理有更深入的了解。 其次,需要对内核的主要函数和数据结构进行详细研究。内核源码中包含了大量的函数和数据结构,这些函数和数据结构是内核实现各种功能的基础。通过仔细分析这些函数和数据结构的实现方式,可以深入理解内核是如何实现各种功能的。 另外,还需要分析内核的关键算法和数据结构。内核中使用了许多常见的算法和数据结构来提高性能和效率,如链表、红黑树、哈希表等。对这些算法和数据结构的分析有助于理解内核的性能优化方案和实现原理。 此外,在分析过程中还要关注内核源码中的一些重要模块,如调度器、设备驱动、网络协议栈等,这些模块是内核实现各种功能的关键部分。深入了解这些模块的实现原理有助于掌握内核的核心功能和特性。 总体而言,linux内核源码情景分析需要对内核的整体结构、函数与数据结构、算法与数据结构、重要模块等进行深入研究和分析,以加深对内核实现原理和工作机制的理解。这对于深入理解操作系统和进行内核开发都具有重要的意义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值