天天看點

系統對 Device Tree Overlays 的支援方式

系統對 Device Tree Overlays 的支援方式

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 檔案進核心的?

  1. uboot 加載的?
  2. 核心加載的?
  3. 作業系統加載的?

Device Tree Overlays 是怎麼運作的?

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 的調用位置
  1. 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);

  2. 查找到 of_overlay_create 被 drivers/of/configfs.c 使用。

    configfs.c 最後一行 late_initcall(of_cfs_init) 标記 of_cfs_init 加入到 核心 .init 段。

  3. .init 段被調用位置

    start_kernel -->rest_init() -->kernel_init() --> kernel_init_freeable() -->do_basic_setup() -->do_initcalls()

    注意: kernel_init_freeable() 是 kernel_init() 第一行。

    kernel_init 在完成一系列初始化之後啟動第一個使用者程序。核心啟動過程就結束了。

  4. 調用 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

  1. 通過啟動日志看。uboot 有對 dtb 進行操作。

    加載 /boot/uEnv.txt 對啟用的 *.dtbo 檔案進行處理。

  2. 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 -h Display help on an overlay

    dtoverlay -h

    .. Or its parameters

    where is the name of an overlay or 'dtparam' for dtparams

    Options applicable to most variants:

    -d Specify an alternate location for the overlays

    (defaults to /boot/overlays or /flash/overlays)

    -v Verbose operation

Adding 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