宋牧春: Linux裝置樹檔案結構與解析深度分析(2)
作者簡介
宋牧春,linux核心愛好者,喜歡閱讀各種開原始碼(uboot、linux、ucos、rt-thread等),對於優秀的程式碼框架及其痴迷。現就職於一家手機研發公司,任職Android BSP開發工程師。
正文開始
前情提要:
6. platform_device和device_node繫結
經過以上解析,DeviceTree的資料已經全部解析出具體的struct device_node和struct
property結構體,下面需要和具體的device進行繫結。首先講解platform_device和device_node的繫結過程。在arch/arm/kernel/setup.c檔案中,
圖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結構體,並向平臺裝置匯流排註冊裝置資訊。如果第一級node的compatible屬性值等於“simple-bus”、“simple-mfd”或者"arm,amba-bus"的話,kernel會繼續為當前node的第二級包含compatible屬性的node建立platform_device結構體,並註冊裝置。Linux系統下的裝置大多都是掛載在平臺匯流排下的,因此在平臺匯流排被註冊後,會根據of_root節點的樹結構,去尋找該匯流排的子節點,所有的子節點將被作為設備註冊到該總線上。
7. i2c_client和device_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_client的name。例如:compatible = “maxim,ds1338”,則i2c_client->name =“ds1338”。
8. Device_Tree與sysfs
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核心移植 part2:uboot裝置樹--生成過程分析
本文從裝置樹軟體控制相關程式碼進行分析,進而理清裝置樹相關的知識。 先放一個裝置樹在記憶體中的結構圖: 分析來源為$(tree)/lib/fdtdec_test.c 一、資料結構 1.1 檔案頭 每個dtb都包含如下結構的檔案頭,用來表示裝
Linux核心移植 part2:uboot 裝置樹--基本概念和原始碼介紹
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開始引入裝置樹的概念,用於實現驅動程式碼與裝置資訊相分離。在裝置樹出現以前,所有關於裝置的具體資訊都要寫在驅動裡,一旦外圍裝置變化,驅動程式碼就要重寫。引入了裝置樹之後,驅動程式碼只負責處理驅動的邏輯,而關於裝置的具體資訊存放到裝置樹檔案中,