
作者簡介
宋牧春,linux核心愛好者,喜歡閱讀各種開源代碼(uboot、linux、ucos、rt-thread等),對于優秀的代碼架構及其癡迷。現就職于一家手機研發公司,任職Android BSP開發工程師。
正文開始
前情提要:
<a href="http://mp.weixin.qq.com/s?__biz=MzAwMDUwNDgxOA==&mid=2652662213&idx=1&sn=54eb6bbb9cd2d2df81774818f451a7b2&chksm=810f2f58b678a64e4cc3fd427c73714c5ead185f5af55bd01b391648520b5bf79d6eaf0691c3&scene=21#wechat_redirect" target="_blank">宋牧春: Linux裝置樹檔案結構與解析深度分析(1)</a>
征稿和征稿獎勵名單:
<a href="http://mp.weixin.qq.com/s?__biz=MzAwMDUwNDgxOA==&mid=2652662198&idx=1&sn=67ff825cb0554077ebf5addc22753b4f&chksm=810f2f2bb678a63d74d9d177a9e6d113c44ab61bc3cfe89bdb4acaf63fece9c33ee9f579e2a1&scene=21#wechat_redirect" target="_blank">Linuxer-"Linux開發者自己的媒體"第二月稿件錄取和贈書名單</a>
<a href="http://mp.weixin.qq.com/s?__biz=MzAwMDUwNDgxOA==&mid=2652662089&idx=1&sn=0ddc01757432a9d503e44e0b4e06da92&chksm=810f2fd4b678a6c23608dc9c936b96716998cb73992f3a13e47b4d9f94a910ad87bea013143c&scene=21#wechat_redirect" target="_blank">Linuxer-"Linux開發者自己的媒體"首月稿件錄取和贈書名單</a>
經過以上解析,DeviceTree的資料已經全部解析出具體的struct device_node和struct property結構體,下面需要和具體的device進行綁定。首先講解platform_device和device_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 platform_device *dev;
const char *bus_id = NULL;
void *platform_data = NULL;
/* 隻有包含"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))
/* 遞歸調用節點解析函數,為子節點繼續生成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);
of_node_set_flag(bus, OF_POPULATED_BUS);
總的來說,當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節點的樹結構,去尋找該總線的子節點,所有的子節點将被作為裝置注冊到該總線上。
經過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”。
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屬性就是一個二進制屬性檔案。
本文轉自張昺華-sky部落格園部落格,原文連結:http://www.cnblogs.com/sky-heaven/p/8177032.html,如需轉載請自行聯系原作者