Linux驅動開發筆記(五)——設備樹(上)

內容詳見《【正點原子】I.MX6U嵌入式Linux驅動開發指南》四十三章

開發板:imx6ull mini

虛擬機:VMware17

ubuntu:ubuntu20.04

一、什么是設備樹

視頻:第6.1講 Linux設備樹詳解-什么是設備樹?_嗶哩嗶哩_bilibili

對應《指南》43.1部分

????????uboot啟動時需要內核zImage 和 .dtb文件,其中dtb便是由設備樹文件dts(Device Tree Source)轉換而來。dts文件用樹形結構來描述板級信息,即開發板上的設備信息,如CPU數量、 內存基地址、IIC接了哪些設備等等。

? ? ? ? bootcmd命令中,80800000就是zImage在RAM中的存放起始地址,83000000就是設備樹在RAM中的存儲地址。

tftp 80800000 zImage;tftp 83000000 imx6ull-alientek-emmc.dtb;bootz 80800000 - 83000000

????????沒有設備樹以前,設備的板級信息等都在.c文件中進行配置,最后會被編碼到內核里面,又臭又長。因此引入了設備樹,用一個專用的文件格式.dts來描述板級信息,將這些玩意與linux分離。

????????如果不同的板子有相同的信息,就可以將這部分提取出來作為一個通用文件.dtsi,其他的.dts文件直接引用就可以。

? ? ? ? 一般.dts描述板級信息,.dtsi描述SOC級信息。

二、DTS文件

視頻:第6.2講 Linux設備樹詳解-DTS文件以及組織形式_嗶哩嗶哩_bilibili

對應《指南》43.2~3部分

2.1 編譯為dtb

命令:

# 進入到Linux源碼根目錄下
make all     # 全部編譯,包括zImage、.ko文件等等
make dtbs    # 將當前內核里所有.dts文件編譯為.dtb
make XXX.dtb # 將指定的dts文件編譯為dtb

示例:?

cd …………/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/
make dtbs
cd arch/arm/boot/dts/
ls *.dtb     # 此時應當可以看到一大堆的dts文件

?2.2 dts語法

????????打開兩個文件:linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/arch/arm/boot/dts下的imx6ull-alientek-emmc.dts和imx6ull.dtsi。

? ? ? ? 打開兩個文檔:(4、參考資料)中的Devicetree SpecificationV0.2.pdf和Power_ePAPR_APPROVED_v1.12.pdf

/dts-v1/;

首先在imx6ull-alientek-emmc.dts開頭可以看到:

/dts-v1/;

(解釋在power_ePAPR_APPROVED_v1.12.pdf的96頁:)
????????The /dts-v1/; shall be present to identify the file as a version 1 DTS (dts files?without this tag will be treated by dtc as being in the obsolete version 0, which?uses a different format for integers in addition to other small but incompatible?changes).
????????/dts-v1/; 必須寫上,將文件標識為版本1 DTS(沒有此標簽的DTS文件將被dtc視為過時的版本0,而舊格式在整數的表示方式等方面與版本1不兼容)

節點命名規則

(Power_ePAPR_APPROVED_v1.12.pdf 15頁)

《指南》43.3.2部分

????????節點名完整寫法為:node-name@unit-address。其中node-name為設備名,unit-address一般是外設寄存器的起始地址,但也不一定,比如下面的例子。需要具體分析。

// imx6ull.dtsi 1096行
i2c4: i2c@021f8000 {    // i2c為name,021f8000為i2c4寄存器起始絕對地址…………
};// imx6ull-alientek-emmc.dts 245行
&i2c1 {mag3110@0e {    // 這里mag3110并不是IMX6ULL的外設,而是一個IIC外設,// 因此0e也不是外設寄存器起始地址,而是一個IIC地址…………};
};// imx6ull.dtsi 94行
intc: interrupt-controller@00a01000 {  //↑這里有個冒號,冒號前面是一個標簽label,后面才是節點名// 這樣可以通過 &label 來訪問該節點,如&intc就可以訪問interrupt-controller@00a01000節點// 比如上面的&i2c1,就可以在imx6ull.dtsi 939行找到“i2c1: i2c@021a0000”// &定義的節點內容如果沒有則追加,如果已存在則替換,比如&i2c1里的內容就會替換原本i2c1: i2c@021a0000的內容…………
};

層級結構

Power_ePAPR_APPROVED_v1.12.pdf 14頁

?????????“/”表示設備樹文件的根節點,每個設備樹文件只有一個根節點。

????????imx6ull.dtsi和imx6ull-alientek-emmc.dts這兩個文件都有一個“/”根節點,這兩個“/”根節點的內容會合并成一個根節點。

2.3 設備樹在系統中的體現

第6.4講 Linux設備樹詳解-設備樹在根文件系統中的體現以及添加自定義節點_嗶哩嗶哩_bilibili

? ? ? ? 系統啟動后可以在根文件系統里看到設備樹的節點信息。

? ? ? ? 內核啟動時會解析設備樹文件,并在/proc/device-tree目錄下生成相應的設備樹節點文件,存放設備樹信息。cd到該路徑下使用ls命令,可以看到很到諸如chosen、memory、reserved-memory、backlight等文件。

????????這與imx6ull-alientek-emmc.dts中的結構一致:

? ? ? ? cat查看model的內容:

? ? ? ? 這與imx6ull-alientek-emmc.dts中model的屬性一致:

? ? ? ? cd到soc/aips-bus@02100000/i2c@021a0000下,可以看到這些文件:

? ? ? ? 但是imx6ull.dtsi的939行下只能看到:

? ? ? ? clock-frequency、fxls8471@1e、mag3110@0e、name、printrl-0、printrl-names是從哪來的?用&追加的。在imx6ull-alientek-emmc.dts的245行可以找到:

? ? ? ? 其中還修改了status,使用cat status可以看到status被覆蓋為了okay。

2.4 其他特殊節點

第6.5講 Linux設備樹詳解-設備樹特殊節點_嗶哩嗶哩_bilibili

《指南》43.6部分

2.4.1?aliases

在imx6ull.dtsi的開頭可以看到:

/ {aliases {can0 = &flexcan1;can1 = &flexcan2;…………};
};

同時,/soc/下定義了flexcan1:

/ {soc {flexcan1: can@02090000{……}……};……
};?

? ? ? ? 那么,can0 = &flexcan1; 等價于?can0 = &{/soc/can@02090000}; 或?can0 = "/soc/can@02090000";

????????aliases節點的主要功能就是定義別名,以方便訪問節點。不過一般會在節點命名的時候會加上label,然后通過&label來訪問節點。

2.4.2?chosen

? ? ? ? 主要目的是將uboot里的bootargs環境變量的值傳給linux內核作為命令行參數cmd line

? ? ? ? 在串口cd /proc/device-tree/chosen,可以看到bootargs、name、stdout-path三個。

但是imx6ull-alientek-emmc.dts中的chosen節點只定義了stdout-path一個:

	chosen {stdout-path = &uart1;};

????????所以bootargs是從來的?(name先不管)當執行bootcmd中的bootz 80800000 - 83000000這句時,bootz層層調用,最終fdt_chosen函數讀取bootargs的值并傳給/chosen節點,供內核使用:

在alientek_uboot/common/fdt_common下可以找到fdt_chosen:

int fdt_chosen(void *fdt){int   nodeoffset;int   err;char  *str;		/* used to set string properties */err = fdt_check_header(fdt);if (err < 0) {printf("fdt_chosen: %s\n", fdt_strerror(err));return err;}/* find or create "/chosen" node.  如果存在子節點/chosen,則返回其偏移nodeoffset,否則創建并返回nodeoffset*/nodeoffset = fdt_find_or_add_subnode(fdt, 0, "chosen");  // fdt為指向設備樹文件的指針,0表示根節點, chosen為要查找的子節點名稱if (nodeoffset < 0)	// 失敗return nodeoffset;str = getenv("bootargs");  // 從uboot的環境變量中讀取bootargs的值if (str) {  // 如果bootargs不為空err = fdt_setprop(fdt, nodeoffset, "bootargs", str,  // 通過fdt_setprop向/chosen節點添加或修改bootargs屬性strlen(str) + 1);if (err < 0) {  // 失敗printf("WARNING: could not set bootargs %s.\n",fdt_strerror(err));return err;}}return fdt_fixup_stdout(fdt, nodeoffset);
}

2.4 修改節點

2.4.1添加自定義節點

????????為方便查看,直接在imx6ull-alientek-emmc.dts的根節點下添加自定義節點:

	// 自定義節點。添加到imx6ull-alientek-emmc.dts的148行mytestnode: mytest@0101 {};
# VSCODE終端
cd .../linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek  # 到內核根目錄下
make dtbs    # 編譯
cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb .../tftpboot/ -f  # 復制到自己存放zImage和dtb文件的目錄下,如果忘了哪個路徑就用vi /etc/default/tftpd-hpa命令看看# 串口
reboot    # 重啟開發板ls /proc/device-tree/   # 此時應當能看到mytest@0101

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?(打錯字了↓)?

2.4.2 使用&進行追加

????????在imx6ull-alientek-emmc.dts文件最末尾添加:

&intc{mytestnode{};
};
// 追加給imx6ull.dtsi 94行的intc
# VSCODE終端
cd .../linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek  # 到內核根目錄下
make dtbs    # 編譯
cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb .../tftpboot/ -f  # 復制到自己存放zImage和dtb文件的目錄下,如果忘了哪個路徑就用vi /etc/default/tftpd-hpa命令看看# 串口
reboot    # 重啟開發板cd /proc/device-tree/interrupt-controller@00a01000/
ls        # 此時能看到mytestnode

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/90823.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/90823.shtml
英文地址,請注明出處:http://en.pswp.cn/web/90823.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【QT入門到晉級】window opencv安裝及引入qtcreator(包含兩種qt編譯器:MSVC和MinGW)

前言 本文主要分享QT的兩種編譯器環境&#xff08;MSVC和MinGW&#xff09;下&#xff0c;安裝及引入opencv的方法。 編譯器區別 特性????MSVC????MinGW????編譯器類型??微軟專有編譯器&#xff08;cl.exe&#xff09;基于GCC的開源工具鏈??平臺支持??僅Wi…

字節跳動Coze Studio開源了!架構解析

Coze Studio 是字節跳動推出的一款 AI 應用開發平臺&#xff0c;專注于幫助開發者快速構建、測試和部署基于大語言模型的智能應用。其整體架構圍繞“低代碼開發 AI 應用”的核心目標設計&#xff0c;融合了模型能力、工具集成、流程編排和多端部署等功能。以下是其整體架構的詳…

Claude 4.0 終極編程指南:模型對比、API配置與IDE集成實戰

Claude 4.0 終極編程指南&#xff1a;模型對比、API配置與IDE集成實戰 基于官方文檔及可驗證數據源&#xff08;2025年7月更新&#xff09; 1 Claude 4.0 技術解析&#xff1a;對比競品的核心優勢與局限 1.1 官方性能數據&#xff08;來源&#xff1a;Anthropic技術白皮書&…

優化:Toc小程序猜你喜歡功能

引言&#xff1a;來自自創的小程序中熱點接口&#xff0c;本小程序專為在校學生自提點餐使用 一、功能描述 該功能作為一個推薦的職責&#xff0c;根據用戶最近行為給用戶推薦用戶可能喜歡去吃的店鋪&#xff0c;可能比較簡潔&#xff0c;但是需要設計的方面挺多的&#xff0c…

Datawhale AI 夏令營:讓AI理解列車排期表 Notebook(Baseline拆解)

Step1、讀取數據 import pandas as pd import requests import re import json from tqdm import tqdm# 讀取數據 data pd.read_excel(data/info_table.xlsx) data data.fillna(無數據) dataStep2、注冊硅基流動https://cloud.siliconflow.cnQwen/Qwen3-8B 模型可以免費使用&…

vue寫的app設置角標

原生App角標&#xff08;UniApp示例&#xff09;調用plus.runtime.setBadgeNumber方法設置安卓/iOS角標&#xff1a;javascriptCopy Code// 設置角標 plus.runtime.setBadgeNumber(99); // 清除角標&#xff08;部分平臺需特殊處理&#xff09; plus.runtime.setBadgeNumber(0)…

GAN/cGAN中到底要不要注入噪聲

MelGAN論文MelGAN針對的是從mel譜生成語音&#xff0c;里面說當條件很強的時候&#xff0c;隨機噪聲就沒啥用了&#xff0c;因此沒將noise注入到生成器中&#xff1b;運用的判別器也僅有1個輸入&#xff0c;不是cGAN的形式image-to-image translation with conditional adversa…

備份一下我的 mac mini 的環境變量配置情況

export PATH“/opt/homebrew/bin:$PATH” #THIS MUST BE AT THE END OF THE FILE FOR SDKMAN TO WORK!!! export SDKMAN_DIR“HOME/.sdkman"[[?s"HOME/.sdkman" [[ -s "HOME/.sdkman"[[?s"HOME/.sdkman/bin/sdkman-init.sh” ]] && so…

JVM學習日記(十)Day10

G1回收器 這一篇是詳細說明G1回收器的&#xff0c;因為他相對來說確實是個縫合怪&#xff0c;上篇的內容又太多了所不清楚&#xff0c;所有這一篇進行詳細的說明&#xff0c; 第一個呢就是其實G1是兼顧并行和并發的&#xff0c;簡單來說就是既可以并行也可以并發&#xff0c;…

使用IP掃描工具排查網絡問題

隨著企業的發展&#xff0c;網絡中會新增各類設備&#xff0c;從臺式機、服務器到物聯網設備和虛擬機&#xff08;VMs&#xff09;&#xff0c;所有這些設備都通過復雜的子網和虛擬局域網&#xff08;VLAN&#xff09;相連。 這種復雜性給 IT 團隊帶來了壓力&#xff0c;他們需…

Wireshark TS | 發送數據超出接收窗口

前言 來自于測試中無意發現到的一個接收窗口滿的案例&#xff0c;特殊&#xff0c;或者可以說我以前都沒在實際場景中見過。一開始都沒整太明白&#xff0c;花了些精力才算是弄清楚了些&#xff0c;記錄分享下。 問題說明 在研究擁塞控制的慢啟動階段時&#xff0c;通過 packet…

C語言自定義數據類型詳解(四)——聯合體

好的&#xff0c;接下來我們來學習最后一個自定義數據類型——聯合體。 一、什么是聯合體&#xff1a; 聯合體又叫共用體&#xff0c;用關鍵字union來進行定義。又因為所有的成員變量共用同一段內存空間&#xff08;關于這一點&#xff0c;我們不久就會加以驗證&#xff09;&…

[python][flask]Flask-Login 使用詳解

1. 簡介Flask-Login 是 Flask 的一個擴展&#xff0c;專門用于處理用戶認證相關的功能。它提供了用戶會話管理、登錄/注銷視圖、記住我功能等常見認證需求&#xff0c;讓開發者能夠快速實現安全的用戶認證系統。2. 安裝與基礎配置首先&#xff0c;需要安裝 Flask-Login&#xf…

【WebGPU學習雜記】WebAssembly中的relaxed_madd指令到底做了什么?

relaxed_madd 這條指令到底做了什么核心&#xff1a;relaxed_madd 是一個分量級別 (Component-wise) 的操作 首先&#xff0c;最重要的一點是&#xff1a;v128.relaxed_madd<f32>(a, b, c) 不是矩陣乘法。它是一個在三個向量 a, b, c 之間進行的、逐個分量的、并行的融合…

【全新上線】境內 Docker 鏡像狀態監控

境內 Docker 鏡像狀態監控&#xff1a;您的 Docker 加速伴侶 在當今云計算和容器化技術飛速發展的時代&#xff0c;Docker 已成為開發者不可或缺的工具。然而&#xff0c;對于身處國內的用戶而言&#xff0c;訪問境外 Docker Hub 等鏡像倉庫時常會遭遇網絡延遲和連接不穩定的困…

Visual Studio中部署PaddleOCRv5 (借助ncnn框架)

PaddleOCRv5_ncnn PaddleOCRv5 在Visual Studio中進行圖片OCR檢測&#xff08;ncnn框架open-mobile實現)&#xff0c;嘗試對nihui的ncnn-android-ppocrv5檢測算法的剝離與移植。 本項目Github鏈接如下&#xff1a;PaddleOCRv5_ncnn 寫在前面 本倉庫代碼是基于nihui的ncnn-a…

中級全棧工程師筆試題

解釋ACID特性&#xff0c;如何在node.js中實現事務操作針對React單頁應用&#xff0c;請提供至少5種性能優化方案&#xff0c;并解釋其原理&#xff1a; 減少首屏加載時間優化渲染性能資源加載策略狀態管理優化代碼分割方案 如何防止以下攻擊&#xff1a; JWT令牌挾持Graph QL查…

Windows---動態鏈接庫Dynamic Link Library(.dll)

DLL的“幕后英雄”角色 在Windows操作系統的生態中&#xff0c;有一類文件始終扮演著“幕后英雄”的角色——它們不像.exe文件那樣直接呈現為用戶可見的程序窗口&#xff0c;卻支撐著幾乎所有應用程序的運行&#xff1b;它們不單獨執行&#xff0c;卻承載著系統與軟件的核心功…

深入分析計算機網絡傳輸層和應用層面試題

三、傳輸層面試題&#xff08;Transmission Layer&#xff09;傳輸層位于 OSI 七層模型的第四層&#xff0c;它的核心任務是為兩個主機之間的應用層提供可靠的數據傳輸服務。它不僅承擔了數據的端到端傳輸&#xff0c;而且還實現了諸如差錯檢測、數據流控制、擁塞控制等機制&am…

【RH134 問答題】第 2 章 調度未來任務

目錄crontab 文件中的用戶作業時間格式怎么解釋&#xff1f;如果需要以當前用戶身份計劃周期性作業&#xff0c;在上午 8 點到晚上 9 點之間每兩分鐘一次輸出當前日期和時間&#xff0c;該作業只能在周一到周五運行&#xff0c;周六或周日不能運行。要怎么做&#xff1f;要計劃…