娇小w搡bbbb搡bbb,《第一次の人妻》,中国成熟妇女毛茸茸,边啃奶头边躁狠狠躁视频免费观看

【IMX6ULL學習筆記】十四、Linux調用設備樹

發布者:HarmoniousCharm最新更新時間:2025-02-28 來源: cnblogs關鍵字:Linux 手機看文章 掃描二維碼
隨時隨地手機看文章

一、設備樹在系統中的體現

Linux 內核啟動的時候會解析設備樹中各個節點的信息,并且在根文件系統的 /proc/device/tree 目錄下根據節點名字創建不同文件夾,如圖所示:

image

上圖就是目錄/proc/device-tree 目錄下的內容,/proc/device-tree 目錄下是根節點“/”的所有屬性和子節點。


1、根節點“/”各個屬性

根節點屬性屬性表現為一個個的文件(圖中細字體文件),如圖中的“#address-cells”、“#size-cells”、“compatible”、“model”和“name”這 5 個文件,它們在設備樹中就是根節點的 5 個屬性。可以輸入 cat 命令來查看 model 和 cat compatible 這兩個文件的內容:


cat model

cat compatible

image

2、根節點“/”各子節點

圖中各個文件夾(圖中粗字體文件夾)就是根節點“/”的各個子節點,比如 “aliases”、“backlight”、“chosen”和“clocks”等等。

/proc/device-tree 目錄就是設備樹在根文件系統中的體現,同樣是按照樹形結構組織的,進入/proc/device-tree/soc 目錄就可以看到 soc 節點的所有子節點:

image

和根節點“/”一樣,上圖中的所有文件分別為 soc 節點的屬性文件和子節點文件夾。


二、特殊節點

在根節點“/”中有兩個特殊的子節點:aliases 和 chosen


1、aliases 子節點

打開 imx6ull.dtsi 文件,aliases 節點內容如下所示:


aliases {

    can0 = &flexcan1;

    can1 = &flexcan2;

    ethernet0 = &fec1;

    ethernet1 = &fec2;

    gpio0 = &gpio1;

    gpio1 = &gpio2;

......

    spi0 = &ecspi1;

    spi1 = &ecspi2;

    spi2 = &ecspi3;

    spi3 = &ecspi4;

    usbphy0 = &usbphy1;

    usbphy1 = &usbphy2;

};

單詞 aliases 的意思是“別名”,因此 aliases 節點的主要功能就是定義別名,定義別名的目的就是為了方便訪問節點。不過一般會在節點命名的時加上label,然后通過 &label 來訪問節點,這樣也很方便,而且設備樹里面大量的使用 &label 的形式來訪問節點。


2、chosen 子節點

chosen 并不是一個真實的設備,chosen 節點主要是為了 uboot 向 Linux 內核傳遞數據,重點是 bootargs 參數。一般 .dts 文件中 chosen 節點通常為空或者內容很少,imx6ull-alientek-emmc.dts 中 chosen 節點內容如下所示:


chosen {

    stdout-path = &uart1;

};

從示例代碼中可以看出,chosen 節點僅僅設置了屬性“stdout-path”,表示標準輸

出使用 uart1。但是當我們進入到 /proc/device-tree/chosen 目錄里面,會發現多了 bootargs 這個屬性,如圖所示:

image

輸入 cat 命令查看 bootargs 這個文件的內容,結果如圖所示:


image

從圖可以看出,bootargs 這個文件的內容為“console=ttymxc0,115200……”,這個就是在 uboot 中設置的 bootargs 環境變量的值。

現在有兩個疑點:

①、我們并沒有在設備樹中設置 chosen 節點的 bootargs 屬性,那么圖中 bootargs 這個屬性是怎么產生的?

②、為何 bootargs 文件的內容和 uboot 中 bootargs 環境變量的值一樣?它們之間有什么關系?

前面講解 uboot 的時候說過,uboot 在啟動 Linux 內核的時候會將 bootargs 的值傳遞給 Linux 內核,bootargs 會作為 Linux 內核的命令行參數,Linux 內核啟動的時候會打印出命令行參數(也就是 uboot 傳遞進來的 bootargs 的值),如圖所示:

image

既然 chosen 節點的 bootargs 屬性不是我們在設備樹里面設置的,那么只有一種可能,那就是 uboot 自己在 chosen 節點里面添加了 bootargs 屬性!并且設置 bootargs 屬性的值為 bootargs 環境變量的值。因為在啟動 Linux 內核之前,只有 uboot 知道 bootargs 環境變量的值,并且 uboot 也知道.dtb 設備樹文件在 DRAM 中的位置。

在 uboot 源碼中全局搜索“chosen”這個字符串,在 common/fdt_support.c 文件中發現了“chosen”的身影,fdt_support.c 文件中有個 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: %sn', fdt_strerror(err));

        return err;

    }


    /* find or create '/chosen' node. */

    nodeoffset = fdt_find_or_add_subnode(fdt, 0, 'chosen');

    if (nodeoffset < 0)

        return nodeoffset;


    str = getenv('bootargs');

    if (str) {

        err = fdt_setprop(fdt, nodeoffset, 'bootargs', str,

        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);

}

第 14 行:調用函數 fdt_find_or_add_subnode 從設備樹(.dtb)中找到 chosen 節點,如果沒有找到的話就會自己創建一個 chosen 節點。

第 18 行:讀取 uboot 中 bootargs 環境變量的內容。

第 20 行:調用函數 fdt_setprop 向 chosen 節點添加 bootargs 屬性,并且 bootargs 屬性值就是環境變量 bootargs 的內容。

整個流程是如圖所示:

image

圖中框起來的部分就是函數 do_bootm_linux 函數的執行流程,也就是說

do_bootm_linux 函數會通過一系列復雜的調用,最終通過 fdt_chosen 函數在 chosen 節點中加入了 bootargs 屬性。而我們通過 bootz 命令啟動 Linux 內核的時候會運行 do_bootm_linux 函數。


三、Linux 內核解析 DTB 文件

Linux 內核在啟動的時候會解析 DTB 文件,然后在 /proc/device-tree 目錄下生成相應的設備樹節點文件。接下來我們簡單分析一下 Linux 內核是如何解析 DTB 文件的,流程如圖所示:

image

從圖中可以看出,在 start_kernel 函數中完成了設備樹節點解析的工作,最終實際工作的函數為 unflatten_dt_node。


關鍵字:Linux 引用地址:【IMX6ULL學習筆記】十四、Linux調用設備樹

上一篇:【IMX6ULL學習筆記】十五、設備樹DTS操作函數
下一篇:【IMX6ULL學習筆記】十三、DTS語法

推薦閱讀最新更新時間:2025-03-26 13:26

Linux內核移植
實驗步驟: (1)準備工作 (2)修改頂層Makefile (3)修改falsh 分區 (4)配置編譯內核 下面以Linux2.6.30.4內核移植到gec2440為例: 一、準備工作: 建立工作目錄,下載內核源碼并解壓:linux-2.6.30.4.tar.bz2。步驟如下: Mkdir cd /root/build_kernel tar -xvf linux-2.6.30.4.tar.gz cd linux-2.6.30.4 解壓后會在當前目錄下生成一個linux-2.6.30.4 的內核源碼目錄 安裝交叉工具鏈,然后修改環境變量,添加新工具鏈的路徑信息,步驟如下: #vi /etc/bashrc 在bashrc 腳本的最后一
[單片機]
Linux設備驅動開發 - 平臺設備驅動
Linux2.6的內核中引入了一種新的設備驅動模型-平臺(platform)設備驅動,平臺設備驅動分為平臺設備(platform_device)和平臺驅動(platform_driver),平臺設備的引入使得Linux設備驅動更加便于移植。 一、平臺設備 平臺設備結構體: 1 struct platform_device { 2 const char * name; /* 設備名 */ 3 int id; 4 struct device dev; /* 設備結構體 */ 5 u32 num_resources; /* 設備資源
[單片機]
Linux移植之配置過程分析
在Linux移植之移植步驟中已經將Linux移植的過程羅列出來了,現在分析一下Linux的配置過程,將分析以下兩個配置過程: 1、make s3c2410_defconfig分析 2、make menuconfig分析 1、make s3c2410_defconfig分析 首先從頂層Makefile開始分析,找到類似smdk2410_defconfig的目標。找到了%config目標。表示后綴為config的目標遵循這個規則,config %config前面的config是一個Kconfig關鍵字,表示一個配置選項的開始。 416 config %config: scripts_basic outputmak
[單片機]
ARM Linux字符設備驅動程序
1、主設備號和次設備號(二者一起為設備號): 一個字符設備或塊設備都有一個主設備號和一個次設備號。主設備號用來標識與設備文件相連的驅動程序,用來反 映設備類型。次設備號被驅動程序用來辨別操作的是哪個設備,用來區分同類型的設備。 linux內核中,設備號用dev_t來描述,2.6.28中定義如下: typedef u_long dev_t; 在32位機中是4個字節,高12位表示主設備號,低12位表示次設備號。 可以使用下列宏從dev_t中獲得主次設備號:                    也可以使用下列宏通過主次設備號生成dev_t: MAJOR(dev_t dev); MKDEV(int major,int
[單片機]
ARM <font color='red'>Linux</font>字符<font color='red'>設備</font>驅動程序
ARM-Linux移植之(二)——Linux2.6.22內核移植
平臺:mini2440 交叉工具鏈:arm-linux-gcc-4.3.2 一、內核移植基本知識 移植內核也叫構建BSP(boardsupprot packet)。BSP的作用有兩個:一是為內核運行提供底層支持,二是屏蔽與板相關的細節。 BSP的構建分三個層次 1、體系結構層次 對一些體系結提供linux內核支持,比如說ARM,X86等芯片。這一類工作一般在arc/xxx/下面額除了palt-xxx和mach-xxx目錄的其他目錄完成。 2、SOC層次 對一些公司提供的SOC微處理器提供linux內核支持,比如說三星公司的 S3C2440。這一類工作一般在arch/
[單片機]
友善之臂Micro2440下的Embedded Linux的硬件時間設置
最近一直在做Embedded Linux下的項目,平臺是友善之臂Micro2440。不過有時會發現,因為開發板用的時間比較長了,實時時鐘的電池會沒電,于是造成系統時間設置發生錯誤。解決方法當然是要更換新的電池,可也要設置一下時間問題,主要的命令如下: #date 2012.8.27-16:05:59 #hwclock -w 第一句的意思是設置系統時間為2012.8.27-16:05:59 第二句的意思是將系統時間寫入到硬件實時時鐘中 經過上面兩句,重啟后會發現,時間初始化將成功,時鐘恢復正常。
[單片機]
從單片機步入Linux之運行地址與加載地址
01 單片機存儲分配 在玩單片機(以stm32為例)的時候會有RAM空間和ROM空間,RAM空間主要是用于數據的訪問,而ROM空間用于存放燒錄的固件,當然固件也可以直接加載到RAM中運行,只是說每次上電都需要重新加載。 如上圖所示ROM為FLASH地址,而RAM為SRAM地址,毋庸置疑生成的單片機固件會燒錄到Flash上,這樣才能保證每次上電都有可以正常運行。 對于很多初學者該有疑問了,明明全局變量等等都是分配到RAM上的呀,怎么說固件放到Flash上的呢? 其實并不矛盾,程序指令中訪問變量都是訪問變量的地址也就是內存的地址,所謂的分配到RAM上,僅僅只是說相應的變量占據了對應的RAM地址,并不能理解為這個變量存在于RAM里面
[單片機]
從單片機步入<font color='red'>Linux</font>之運行地址與加載地址
在STM32上模擬Linux自動初始化
Linux中有很多編程思想可以學習,很多大佬把這些思想、機制運用到單片機的編程上。 下文,在STM32上模擬Linux kernel自動初始化流程。 通常我們寫程序都是按照這個套路,一個函數一個函數按照順序邏輯一個一個的執行下去。 如果邏輯非常復雜,涉及的模塊比較多,那么這種順序執行的代碼就會比較臃腫,各模塊耦合非常緊密。Linux kernel 中,有各種外設驅動,想按照一個順序邏輯執行下去,幾乎是不可能的。 而kenrel 代碼能有這么大的代碼量,大而不亂,把各層次,各模塊有效的分離,而大量的代碼又有邏輯的組織在一起,和這個initcall 有至關重要的作用。 通過模仿這種方式,最后把圖片中main函數代碼清空,分離這
[單片機]
在STM32上模擬<font color='red'>Linux</font>自動初始化
小廣播
設計資源 培訓 開發板 精華推薦

最新單片機文章
何立民專欄 單片機及嵌入式寶典

北京航空航天大學教授,20余年來致力于單片機與嵌入式系統推廣工作。

 
EEWorld訂閱號

 
EEWorld服務號

 
汽車開發圈

 
機器人開發圈

電子工程世界版權所有 京ICP證060456號 京ICP備10001474號-1 電信業務審批[2006]字第258號函 京公網安備 11010802033920號 Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
主站蜘蛛池模板: 大悟县| 南通市| 沽源县| 东山县| 河池市| 湘潭市| 佳木斯市| 峡江县| 永春县| 梨树县| 台东县| 屏东县| 沛县| 泽普县| 遵义县| 高安市| 东莞市| 朝阳市| 开江县| 句容市| 宜川县| 蚌埠市| 莎车县| 娱乐| 莱芜市| 陇川县| 绥棱县| 十堰市| 班玛县| 苏尼特右旗| 山西省| 桂东县| 灵台县| 游戏| 泰顺县| 芜湖县| 金山区| 新昌县| 阜新市| 上虞市| 河曲县|