diff --git a/programing-manual/dts/dts.md b/programing-manual/dts/dts.md new file mode 100644 index 0000000000000000000000000000000000000000..8fc964b13202b71f5a591431bd7a7313743ada5e --- /dev/null +++ b/programing-manual/dts/dts.md @@ -0,0 +1,92 @@ +## 一、描述 + +设备树(Device Tree)是一种描述硬件设备的数据结构,用于在嵌入式系统中描述硬件设备和其属性。它是一个中立的、可扩展的、硬件描述语言,以树状的数据结构形式表示硬件设备及其连接关系。 传统的硬件描述方法(如静态平台数据结构、板级支持包等)存在一些问题,比如不灵活、不可扩展、不易维护等。设备树的出现解决了这些问题。通过使用设备树,硬件配置信息可以从操作系统内核中分离出来,使得硬件的添加、删除、修复等操作更加灵活和容易。 设备树可以描述各种硬件设备,包括处理器、内存、外设等,并且可以描述它们之间的连接关系。设备树使用一种特定的语法进行描述,通常以.dts(设备树源文件)或者.dtb(设备树二进制文件)的形式存在。在嵌入式系统中,设备树通常被用于描述板级支持包(Board Support Package,BSP),即硬件设备的初始化和配置。 + +## 二、原理 + +![img](figure/dts_theory.png) + +利用dts描述板子的硬件信息,并使用dtc工具将dts文件转化为dtb文件。nxos代码自动识别dtb文件,将其转化为platform_device。device将与driver匹配,所携带的硬件信息也将被驱动代码所读取。 + +## 三、使用 + +dts设备树默认不启用,需要使用时,需要进入kernel目录下。 + +```C +cd kernel +make menuconfig +``` + +选中enable dts使能设备树。 + +然后需要编写dts文件,以下为dts文件的编写示例: + +![img](figure/dts_file.png) + +1. compatible属性描述了板级信息,决定了内核代码使用什么样的初始化代码,该属性将与内核代码machine_desc属性搭配使用。 +2. address-cells和size-cells是设备树中用于描述设备地址和大小编码方式的特殊属性,address-cells属性表示设备的地址的单元数。它指定了设备地址的编码方式,通常是一个整数值。例如,如果address-cells的值为2,则表示每个地址由两个32位的数值组成,即64位的地址。这个值的大小取决于硬件设备的寻址能力。size-cells属性表示设备的大小的单元数。它指定了设备大小的编码方式,也通常是一个整数值。例如,如果size-cells的值为1,则表示设备大小由一个32位的数值表示,即32位的大小。 +3. chosen节点里的bootargs为命令行参数 +4. memory节点描述了内存设备的初始化信息。 +5. 驱动节点(待添加):需要根据驱动代码编写的具体内容,来添加驱动节点的具体信息。 + +编写好设备树后,需要安装dtc工具。 + +```C +sudo apt-get install device-tree-compiler +``` + +然后使用dtc工具将dts文件编辑为dtb文件。 + +```C +dtc -I dts -O dtb -o output.dtb input.dts +``` + +## 四、接口 + +先查找设备树第一个节点compatible属性,选择合适的machine_desc,分数最高的为最佳machine_desc + +```C +static int of_fdt_is_compatible( + const void *blob, unsigned long node, const char *compat) +``` + +获取chosen节点 + +```C +of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); +``` + +获取根节点的{size,address}-cells属性值,之后才方便解析根节点的子节点的reg属性 + +```C +of_scan_flat_dt(early_init_dt_scan_root, NULL); +``` + +解析/memory节点,设置内存信息 + +```C +of_scan_flat_dt(early_init_dt_scan_memory, NULL); +``` + +将设备树信息转为device_node结构体并放入内存里 + +```C +void *__unflatten_device_tree(const void *blob, + struct device_node *dad, + struct device_node **mynodes, + void *(*dt_alloc)(NX_Size size), + bool detached) +``` + +只要是根节点下面的子节点带有compatbile属性的就认为需要转换成platform_device,后续可新增规则,比如子节点带有simple-bus的可将子节点的子节点进行platform_device的转换。 + +```C +static int of_platform_bus_create(struct device_node *bus, + struct list_head * head,bool strict) +``` + +根据compatible属性进行比较,得到最合适的platform_device结构体。 + +```C +int platform_match(struct platform_device *pdev, const struct of_device_id *matches) +``` diff --git a/programing-manual/dts/figure/dts_file.png b/programing-manual/dts/figure/dts_file.png new file mode 100644 index 0000000000000000000000000000000000000000..38b42befab54c01de04442221559a874928c4999 Binary files /dev/null and b/programing-manual/dts/figure/dts_file.png differ diff --git a/programing-manual/dts/figure/dts_theory.png b/programing-manual/dts/figure/dts_theory.png new file mode 100644 index 0000000000000000000000000000000000000000..0b07c64c4c4340b16199db35f2e3e3f316d429d2 Binary files /dev/null and b/programing-manual/dts/figure/dts_theory.png differ