IoT之嵌入式Linux設備樹機制
Part 01
● Linux設備樹機制的介紹 ●
1.1 概念
設備樹(device tree)是一種描述硬件資源的數據結構,起源于Open Firmware(OF:開源固件)。在Linux kernel v2.6之前的版本,關于ARM架構的板級硬件資源均通過.c和.h文件寫“死”在arch/arm/plat-xxx和arch/arm/mach-xxx目錄下,在開發一款設備時,Linux kernel中充斥著許多無用的硬件信息,不利于閱讀和維護。在Linux ARM kernel v3.x之后正式引入設備樹機制,主要是為減少這類無用的硬件板級信息被寫入Linux kernel中污染內核,有了設備樹,則可通過它來將所需的硬件信息傳遞給Linux kernel。
1.2 組成
設備樹主要包含dts(device tree source,源文件)、dtc(device tree compiler,編譯工具)和dtb(device tree blob,二進制文件)。
dts 是設備樹描述的源文件,在ARM架構下,一個dts對應一個設備,一般位于arch/arm(64)/boot/dts目錄下,該文件一般會有包含對應名稱的.dtsi文件,類似于c語言的頭文件,主要是一些SOC的宏定義共性部分。
dtc 是設備樹的編譯工具,類似于gcc等編譯器,但與gcc不同的是dtc無需外部安裝,是由內核自帶的。可以將.dts文件編譯成.dtb文件。
dtb 是設備樹二進制文件,可被Linux kernel識別解析,也可被bootloader解析。
dtbo 是overlay編譯出來的二進制文件。
dts、dtc和dtb三者間的關系如下圖:
Part 02
● 設備樹框架和dts文件語法格式 ●
2.1 設備樹基本框架
設備樹文件基本結構主要有以下幾部分,其形式有點類似xml文件。
- 單根節點(root):/
- 節點名稱:圖中的"node1"和"node2"
- 子節點:"child-node1"和"child-node2"
- 節點地址:node@xxx
- 屬性(property):是一組鍵值對,包括屬性名稱(property name)和屬性值(property value)
- 標簽(label,可選項)
??https://elinux.org/Device_Tree_Usage#Basic_Data_Format??
值得注意的是,“/”是根節點,每個設備樹文件僅有一個,當在設備樹中發現有多個根節點時,在編譯過程中這些根節點會合并成一個。
2.2 dts文件語法格式
與c語言類似,dts同樣支持頭文件,其頭文件擴展名為.dtsi,一般通過#include xxx來引用。
例如,以全志H616這款芯片為例,基于Linux v4.9版本的orangepi開發板的時鐘節點(部分)如下:
上述中,特別重要的compatible屬性,它可以以“,”格式指定名稱的優先選擇。設備樹中每個代表設備的節點都要有一個compatible屬性,它是OS用于決定綁定到設備驅動的關鍵特征。
Part 03
● 設備樹的修改與內核編譯安裝 ●
在編寫模塊的驅動程序時,為不影響內核結構,通常在外部目錄下建立一個用于存放編寫的驅動源碼和編譯生成的.ko的文件夾,生成的.ko可以在系統啟動后單獨加載運行,且無需和內核一起編譯,方便更新。其流程一般為:makefile文件編寫,接著進行驅動源碼編寫(可找優秀的架構進行修改,填充細節,如compatible,讀、寫操作等),然后編譯生成.ko文件,進一步修改與單板相關的設備樹文件(.dts),在.dts文件中添加或刪除相應的設備節點信息,最后編譯整個內核文件,當內核編譯完成后,使用如下命令卸載舊版本的內核與安裝新版本內核:
重啟單板后,用uname -a 命令查看內核信息,在新編譯的內核上,用insmod 命令將生成的.ko模塊加載上,cat 命令查看設備節點信息。
需要注意的是,設備樹的使用需要在編譯kernel時做好對應的配置,還需bootloader支持,否則也無法將數據結構傳參給kernel。