Device Tree Overlays、 dtbo、設備樹堆疊功能 ...
問題來源:
野火 iMX 6ULL 開發板資料。
https://tutorial.linux.doc.embedfire.com/zh_CN/latest/linux_basis/fire-config_brief.html
5.3. fire-config機制
一般而言,fire-config旨在提供一些常見的系統功能配置服務,在進行配置過程中, 這可能會導致/boot/uEnv.txt或者是其他各種標準的linux配置文件被自動更改了, 某些選項需要重啟才能生效,如果您修改了其中一個,fire-config 會在<Finish> 按鈕被選擇時,詢問您是否要立即重啟,如果您希望配置馬上生效,確定重啟系統即可。
5.4. Device Tree Overlays
fire-config工具集成了Device Tree Overlays機制,用來管理一些硬體資源的分配和模塊的載入, 從而緩解多個驅動程式爭用系統資源的問題。
在傳統開發模式中,這個機制通常是由設備樹來完成的:在開發之前根據項目需求, 提前確定系統中所有用到的硬體設備。在設備樹中把所有的外圍設備信息以設備樹特定的語法進行描述, 在設備樹被編譯為dtb文件後,被linux內核載入使用。
可以看到,在傳統開發過程,一旦硬體資源發生變化,就要重新修改、編譯、下載設備樹。比較極端的情況是: 當項目中要支持多種的硬體模塊,而不同模塊間往往會共用某些系統資源(如IO引腳)。 一旦系統要相容模塊任意組合使用,那麼隨著模塊數量增加,需要編譯的設備樹數量將爆炸增長。
因此,使用傳統設備樹是不利於項目的維護和擴展的。內核為瞭解決這個提出了一套新的解決方案, 那就是Device Tree Overlays,中文上可理解為”設備樹插件”。 它的核心原理是,通過擴展傳統的設備樹語法,使得各個硬體模塊的信息可以獨立地用新的設備樹語法來描述。 這樣一來,傳統的主設備樹中只需要保留最基礎的硬體信息(主要是cpu和記憶體),其他模塊單獨編譯成”設備樹插件”。 在系統實際使用時,根據實際應用情景,需要用到哪些硬體模塊就把對應的設備樹插件加入到主設備樹即可。
“設備樹插件”無疑提高了系統的可維護性和減少了大量的重覆工作,目前, 我們已經把常見的硬體模塊都編譯成了”設備樹插件”,比如LCD、HDMI、WiFi等等。 用戶可以通過fire-config工具輕鬆地實現對硬體模塊的便捷管理。
原本問題:
5.3 節 最後一句: 如果您希望配置馬上生效,確定重啟系統即可。
既然是“插件”,為什麼要重啟? 不是熱拔插的麽?
究竟在哪裡載入 overlay 文件進內核的?
- uboot 載入的?
- 內核載入的?
- 操作系統載入的?
Device Tree Overlays 是怎麼運行的?
有朋友問我 Device Tree Overlays 是什麼,怎麼沒聽說過。確實百度很少找到資料。
我給出的中文名叫 設備樹堆疊功能。不一定准確。
內核描述在 Documentation/devicetree/overlay-notes.txt
Device Tree Overlays 核心定義:
在 kernel 啟動以後系統載入時候修改或者增加部分dts,最終把整個系統需要的設備驅動全部載入進去。
用處:
動態修改設備樹。
在用戶空間配置內核對象 Device Tree。
uboot 啟動內核
從 <Device Tree Overlays 核心定義> 來看,不是uboot的操作。
bootm <uImage_addr> <initrd_addr> <dtb_addr>
內核對 dtb 文件的解析位置
start_kernel -->setup_arch(&command_line) -->setup_machine_fdt(__fdt_pointer) -->unflatten_device_tree()
overlays 的調用位置
-
drivers/of/overlay.c 核心代碼。
// Create and apply an overlay
int of_overlay_create(struct device_node *tree);
// Removes an overlay
int of_overlay_destroy(int id);
// Removes all overlays from the system
int of_overlay_destroy_all(void); -
查找到 of_overlay_create 被 drivers/of/configfs.c 使用。
configfs.c 最後一行 late_initcall(of_cfs_init) 標記 of_cfs_init 加入到 內核 .init 段。 -
.init 段被調用位置
start_kernel -->rest_init() -->kernel_init() --> kernel_init_freeable() -->do_basic_setup() -->do_initcalls()
註意: kernel_init_freeable() 是 kernel_init() 第一行。
kernel_init 在完成一系列初始化之後啟動第一個用戶進程。內核啟動過程就結束了。 -
調用 of_cfs_init 會在 /sys/kernel/config/ 目錄下創建 /sys/kernel/config/device-tree/overlay 文件(記憶體文件系統)。
configfs.c 的具體分析見參考文章
https://blog.csdn.net/liujiliei/article/details/105276551
內核啟動流程。
void __init start_kernel(void)
{
....
setup_arch(&command_line);
....
rest_init();
}
結論
/boot/overlay 目錄下的 *.dtbo 文件並不是內核啟動過程中載入和處理的。
那麼就要看是不是 UBOOT 和 操作系統init進程做的了。 稍後進行。
野火iMX 6ULL
- 通過啟動日誌看。uboot 有對 dtb 進行操作。
載入 /boot/uEnv.txt 對啟用的 *.dtbo 文件進行處理。 - fire-config 有使用到 dtoverlay 這個工具。
root@npi:/usr/bin# file dtoverlay
root@npi:/usr/bin# dtoverlay: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 3.2.0, BuildID[sha1]=47010de3c4a3ddde326dfaf701ca908ad41f34e9, not stripped
root@npi:/usr/bin# dtoverlay --help
- unknown option '--help'
Usage:
dtoverlay[= ...]
Add an overlay (with parameters)
dtoverlay -D [] Dry-run (prepare overlay, but don't apply -
save it as dry-run.dtbo)
dtoverlay -r [] Remove an overlay (by name, index or the last)
dtoverlay -R [] Remove from an overlay (by name, index or all)
dtoverlay -l List active overlays/params
dtoverlay -a List all overlays (marking the active)
dtoverlay -h Show this usage message
dtoverlay -hDisplay help on an overlay
dtoverlay -h.. Or its parameters
whereis the name of an overlay or 'dtparam' for dtparams
Options applicable to most variants:
-dSpecify an alternate location for the overlays
(defaults to /boot/overlays or /flash/overlays)
-v Verbose operationAdding or removing overlays and parameters requires root privileges.
樹莓派網站也找到 dtoverlay 的描述 2.2.10 節。
https://www.raspberrypi.org/documentation/configuration/device-tree.md
搜索 dtoverlay 找到不少使用案例,不需要重啟即可生效。
例如:
https://blog.csdn.net/qq_30968657/article/details/52044876
基本可以斷定是 dtoverlay 工具是真實使用 device tree overlay 完成的。
友善Nanopi neo core2
在該產品/boot 目錄下發現 overlay 相關內容。
分析 npi-config 使用的是 fdtput fdtget fdtdump 直接操作 /boot/*.dtb 文件。
並沒有使用到 /boot/overlay/* 目錄下的 *.dtbo (overlay文件)文件。
正確使用 device tree overlays
直接操作
通過外文網站獲取到一些內容:
device tree overlays 的實際用法是,系統啟動後 root 用戶修改dtb文件,不需要重啟!即可生效。
在 /sys/kernel/config/device-tree/overlays/ 目錄下創建目錄,創建完成後目錄內自動會有三個文件 dtbo path status
直接複製 已經編譯好的 *.dtbo 文件覆蓋 dtbo 文件.
並對 status 賦值 1 即可(好像是不需要的,cp文件覆蓋直接生效,如果 status 是只讀文件 獲取當前 dtbo 是否OK)。
root@npi:/sys/kernel/config/device-tree/overlays# mkdir test
root@npi:/sys/kernel/config/device-tree/overlays# cd test
root@npi:/sys/kernel/config/device-tree/overlays/test# ls
root@npi:/sys/kernel/config/device-tree/overlays/test# dtbo path status
root@npi:/sys/kernel/config/device-tree/overlays/test# cat status
root@npi:/sys/kernel/config/device-tree/overlays/test# unapplied
root@npi:/sys/kernel/config/device-tree/overlays/test# cp /lib/firmware/test.dtbo dtbo
root@npi:/sys/kernel/config/device-tree/overlays/test# cat status
root@npi:/sys/kernel/config/device-tree/overlays/test# applied
載入完成後,dtbo 內的設備會自動由系統安裝。可以在 /dev 看到具體內容。
工具操作
參考樹莓派的使用方式:
https://www.raspberrypi.org/documentation/configuration/device-tree.md
dtdiff dtoverlay dtparam 應該是一組工具。 這裡不再描述。
參考文章:
https://blog.csdn.net/u014135607/article/details/79949571
https://blog.csdn.net/liujiliei/article/details/105276551
https://github.com/ikwzm/dtbocfg
https://www.raspberrypi.org/documentation/configuration/device-tree.md