1. 程式人生 > >宋牧春: Linux裝置樹檔案結構與解析深度分析(2)

宋牧春: Linux裝置樹檔案結構與解析深度分析(2)

作者簡介

宋牧春,linux核心愛好者,喜歡閱讀各種開原始碼(uboot、linux、ucos、rt-thread等),對於優秀的程式碼框架及其痴迷。現就職於一家手機研發公司,任職Android BSP開發工程師。

正文開始

前情提要:

6. platform_devicedevice_node繫結

經過以上解析,DeviceTree的資料已經全部解析出具體的struct device_nodestruct property結構體,下面需要和具體的device進行繫結。首先講解platform_devicedevice_node的繫結過程。在arch/arm/kernel/setup.c檔案中,

customize_machine()函式負責填充struct platform_device結構體。函式呼叫過程如圖8所示。

8 platform_device生成流程圖

程式碼分析如下:

const struct of_device_id  of_default_bus_match_table[] = {

    {  .compatible = "simple-bus", },

    {  .compatible = "simple-mfd", },

#ifdef CONFIG_ARM_AMBA

    {  .compatible = "arm,amba-bus", },

#endif /* CONFIG_ARM_AMBA */

    {}  /* Empty terminated list */

};

int of_platform_populate(struct  device_node *root,

           const  struct of_device_id *matches,

           const  struct of_dev_auxdata *lookup,

           struct  device *parent)

{

    struct  device_node *child;

    int  rc = 0;

    /*  

獲取根節點 */

    root  = root ? of_node_get(root) : of_find_node_by_path("/");

    if  (!root)

       return  -EINVAL;

    /*  為根節點下面的每一個節點建立platform_device結構體 */

    for_each_child_of_node(root,  child) {

       rc  = of_platform_bus_create(child, matches, lookup, parent, true);

       if  (rc) {

           of_node_put(child);

           break;

       }

    }

    /*  更新device_node flag標誌位 */

    of_node_set_flag(root,  OF_POPULATED_BUS);

    of_node_put(root);

    return  rc;

}

static int of_platform_bus_create(struct  device_node *bus,

                const struct of_device_id *matches,

                const struct of_dev_auxdata *lookup,

                struct device *parent, bool strict)

{

    const  struct of_dev_auxdata *auxdata;

    struct  device_node *child;

    struct  platform_device *dev;

    const  char *bus_id = NULL;

    void  *platform_data = NULL;

    int  rc = 0;

    /*  只有包含"compatible"屬性的node節點才會生成相應的platform_device結構體 */

    /*  Make sure it has a compatible property */

    if  (strict && (!of_get_property(bus, "compatible", NULL))) {

       return  0;

    }

    /*  省略部分程式碼 */

    /*  

     *針對節點下面得到status = "ok"或者status = "okay"或者不存在status屬性的

     *節點分配記憶體並填充platform_device結構體

     */

    dev  = of_platform_device_create_pdata(bus, bus_id, platform_data, parent);

    if  (!dev || !of_match_node(matches, bus))

       return  0;

    /*  遞迴呼叫節點解析函式,為子節點繼續生成platform_device結構體,前提是父節點

     *“compatible” = “simple-bus”,也就是匹配of_default_bus_match_table結構體中的資料

     */

    for_each_child_of_node(bus,  child) {

       rc  = of_platform_bus_create(child, matches, lookup, &dev->dev, strict);

       if  (rc) {

           of_node_put(child);

           break;

       }

    }

    of_node_set_flag(bus,  OF_POPULATED_BUS);

    return  rc;

}

總的來說,當of_platform_populate()函式執行完畢,kernel就為DTB中所有包含compatible屬性名的第一級node建立platform_device結構體,並向平臺裝置匯流排註冊裝置資訊。如果第一級nodecompatible屬性值等於“simple-bus”、“simple-mfd”或者"arm,amba-bus"的話,kernel會繼續為當前node的第二級包含compatible屬性的node建立platform_device結構體,並註冊裝置。Linux系統下的裝置大多都是掛載在平臺匯流排下的,因此在平臺匯流排被註冊後,會根據of_root節點的樹結構,去尋找該匯流排的子節點,所有的子節點將被作為設備註冊到該總線上。

7. i2c_clientdevice_node繫結

經過customize_machine()函式的初始化,DTB已經轉換成platform_device結構體,這其中就包含i2c adapter裝置,不同的SoC需要通過平臺裝置匯流排的方式自己實現i2c adapter裝置的驅動。例如:i2c_adapter驅動的probe函式中會呼叫i2c_add_numbered_adapter()註冊adapter驅動,函式流執行如圖9所示。

9 i2c_client繫結流程

of_i2c_register_devices()函式內部便利i2c節點下面的每一個子節點,併為子節點(status = disable”的除外)建立i2c_client結構體,並與子節點的device_node掛接。其中i2c_client的填充是在i2c_new_device()中進行的,最後device_register()。在構建i2c_client的時候,會對node下面的compatible屬性名稱的廠商名字去除作為i2c_clientname。例如:compatible = maxim,ds1338,i2c_client->name =ds1338”。

8. Device_Treesysfs

kernel啟動流程為start_kernel()rest_init()kernel_thread():kernel_init()do_basic_setup()driver_init()of_core_init(),在of_core_init()函式中在sys/firmware/devicetree/base目錄下面為裝置樹展開成sysfs的目錄和二進位制屬性檔案,所有的node節點就是一個目錄,所有的property屬性就是一個二進位制屬性檔案。

精彩文章

與其相忘於江湖,不如點選二維碼關注Linuxer~

相關推薦

Linux裝置檔案結構解析深度分析(2)

作者簡介 宋牧春,linux核心愛好者,喜歡閱讀各種開原始碼(uboot、linux、ucos、rt-thread等),對於優秀的程式碼框架及其痴迷。現就職於一家手機研發公司,任職Android BSP開發工程師。 正文開始 前情提要: 6. platform_device和device_node

Linux裝置檔案結構解析深度分析(1)

本文轉載自微信公眾號linuxer 作者簡介 宋牧春,linux核心愛好者,喜歡閱讀各種開原始碼(uboot、linux、ucos、rt-thread等),對於優秀的程式碼框架及其痴迷。現就職於一家手機研發公司,任職Android BSP開發工程師。 正文開始 1. Device Tree簡介 裝置樹就是描

Linux系統移植——裝置檔案編譯反編譯

裝置樹檔案編譯與反編譯 一、裝置樹編譯 有兩種方式 1、將裝置樹檔案拷貝到核心原始碼的arch/*(處理器平臺)/boot/dts/*(廠家)/目錄下,    執行make dtbs 2、dtc -I dts -O dtb  *.dts > my.dtb 二、裝置

寶華Linux裝置驅動框架裡的設計模式之——模板方法(Template Method)

本文系轉載,著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。 作者: 宋寶華 來源: 微信公眾號linux閱碼場(id: linuxdev) 前言 《設計模式》這本經典的書裡面定義了20多種設計模式,雖然都是面向物件的,似乎需要C++、Java這樣的語言才能實現,但是根據筆者前面反覆

第一課:linux裝置的引入體驗(基於linux4.19核心版本)

轉載請註明原文地址:http://wiki.100ask.org/Linux_devicetree 本套視訊面向如下三類學員: 有Linux驅動開發基礎的人, 可以挑感興趣的章節觀看; 沒有Linux驅動開發基礎但是願意學習的人,請按順序全部觀看,我會

Linux 可執行檔案結構程序結構

一、Linux可執行檔案結構 在 Linux 下,程式是一個普通的可執行檔案,以下列出一個二進位制可執行檔案的基本情況: 可以看出,此可執行檔案在儲存時(沒有調入到內容)分為程式碼區(text)、資料區(data)和未初始化資料區(bss)3 個部分。各段基本內

Linux核心之解析DTS裝置檔案並建立裝置的過程

核心之解析DTS裝置樹檔案並建立裝置的過程 在這裡,我分析的是核心原始碼來自谷歌官方Android7.1.2原始碼包經過打補丁包"SC60_Android7.1.2_Quectel_SDK_r270060_20180731.tar.gz"後得到的. 本文分析時使用的

Linux驅動開發11裝置】nanopi的PWM驅動

介紹 前兩節利用裝置樹實現了nanopi的LED驅動和按鍵驅動,這一節來實現nonapi的PWM驅動。PWM驅動在核心中也有相應的實現,因此這裡只是按照要求新增裝置樹檔案即可。這一節和之前一樣,首先修改裝置樹檔案進行測試,然後分析核心相應的軟體實現。 新增裝置樹節點 因為在s

Linux驅動開發10裝置】nanopi的按鍵驅動

介紹 這一節在nanopi上實現按鍵驅動,和LED驅動一樣,通用的按鍵驅動在linux核心中已經實現好,我們只需要按照要求寫好裝置樹即可,不用我們自己實現按鍵驅動。這一節中首先修改裝置樹並測試按鍵驅動,然後分析drivers/input/keyboard/gpio_keys.c檔案,

Linux驅動開發08裝置】MPU6050驅動和i2c驅動

介紹 上一節在nanopi裝置樹的I2C節點下增加了一個MPU6050的子節點,並在sysfs中檢視到了該節點已經被正確解析,這一節我們來修改之前的MPU6050驅動,使之能夠匹配到我們的裝置樹節點,然後再分析裝置樹節點是如何載入到i2c總線上的。 MP

Linux核心移植 part2uboot裝置--生成過程分析

本文從裝置樹軟體控制相關程式碼進行分析,進而理清裝置樹相關的知識。 先放一個裝置樹在記憶體中的結構圖: 分析來源為$(tree)/lib/fdtdec_test.c 一、資料結構 1.1 檔案頭 每個dtb都包含如下結構的檔案頭,用來表示裝

Linux核心移植 part2uboot 裝置--基本概念和原始碼介紹

arm uboot的裝置樹原始檔位於arch/arm/dts/目錄下,網路上有很多介紹Linux裝置樹概念的文章,這裡以dts相關的API為切入點,如果都懂了,裝置樹的東西就迎刃而解了。本篇文章首先記錄一些基本知識,下一篇進行原始碼分析。 一、裝置樹檔案基

寶華《Linux裝置驅動開發詳解》——sysfs檔案系統linux裝置模型(5.4.2

以下讀書筆記內容,摘自宋寶華《Linux裝置驅動開發詳解》一書。 1、sysfs檔案系統的簡介 (1)linux2.6以後的核心引進syfs檔案系統,是虛擬檔案系統; (2)產生一個包括所有系統硬體

Linux驅動開發09裝置】nanopi的LED驅動

介紹 這節通過在nanopi的裝置樹中新增LED子節點,來實現一個LED驅動。由於linux核心支援LED驅動框架並且有通用的LED驅動,因此這裡只需按照驅動要求新增裝置樹節點就可以了,不用我們自己重寫LED驅動。這一節先在裝置樹中新增一個LED節點,重新編譯

《Linux4.0裝置驅動開發詳解》筆記--第十八章ARM Linux裝置

18.1 ARM裝置樹簡介 裝置舒適一種描述印鑑的資料結構,它起源於OpenFirmware(OF) 採用裝置樹前後對比: 採用裝置樹之前:ARM架構的板極硬體細節過多的被硬編碼在arch/arm/plat-xxx和arch/arm/mach-xxx中

ARM Linux裝置

1 ARM裝置樹 DT: Device Tree FDT: Flattened DeviceTree OF: Open Firmware(開啟韌體,這個字首在後面的api中會用到) DTS : device tree souke DTSI: device tree sourc

Linux裝置語法詳解【轉】

轉自:https://www.cnblogs.com/xiaojiang1025/p/6131381.html 概念 Linux核心從3.x開始引入裝置樹的概念,用於實現驅動程式碼與裝置資訊相分離。在裝置樹出現以前,所有關於裝置的具體資訊都要寫在驅動裡,一旦外圍裝置變化,驅動程式碼就要重寫。引入了裝置樹之

編譯myzr裝置檔案

source /my-imx6/03_tools/myimx6_31452_build_env 用echo $ARCH echo $GCC_PATH echo $CROSS_COMPILE 命令可以檢視配置是否生效 make myimx6ek200-6u.dtb make m

04-Linux裝置系列-GPIO驅動實踐

1. 前言 GPIO驅動開發可能算是Linux核心裝置驅動開發中最為簡單、最常見的一個方向,對於開發板的按鍵、LED、蜂鳴器、電源控制等模組,可能都是使用GPIO實現的。Linux核心的GPIO子系統在核心不斷的演進過程中進行了多次的重構,本文的第二

Linux裝置語法詳解

概念 Linux核心從3.x開始引入裝置樹的概念,用於實現驅動程式碼與裝置資訊相分離。在裝置樹出現以前,所有關於裝置的具體資訊都要寫在驅動裡,一旦外圍裝置變化,驅動程式碼就要重寫。引入了裝置樹之後,驅動程式碼只負責處理驅動的邏輯,而關於裝置的具體資訊存放到裝置樹檔案中,