亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

aliases節點解析

2019-11-09 16:57:05
字體:
來源:轉載
供稿:網友


轉自http://www.cnblogs.com/pengdonglin137/p/5252348.html

在設備樹中有一個叫做aliases的節點:

   1: / {
   2:     ... ...
   3:  
   4:     chosen {
   5:         stdout-path = "/serial@13800000";
   6:         bootargs = "root=/dev/ram0 rw rootfstype=ext4 console=ttySAC0,115200 ethmac=1C:6F:65:34:51:7E init=/linuxrc";
   7:     };
   8:  
   9:     aliases {
  10:         spi0 = "/spi@13920000";
  11:         spi1 = "/spi@13930000";
  12:         spi2 = "/spi@13940000";
  13:         i2c0 = "/i2c@13860000";
  14:         i2c1 = "/i2c@13870000";
  15:         i2c2 = "/i2c@13880000";
  16:         i2c3 = "/i2c@13890000";
  17:         ... ...
  18:     };
  19: ... ...
  20: };

在Linux內核啟動的時候會解析這個節點:

start_kernel    ---> setup_arch            ---> unflatten_device_tree                    ---> of_alias_scan

在of_alias_scan中會掃描這個節點:

of_alias_scan:

   1: void of_alias_scan(void * (*dt_alloc)(u64 size, u64 align))
   2: {
   3:     struct PRoperty *pp;
   4:  
   5:     of_aliases = of_find_node_by_path("/aliases"); // 找到/aliases節點對應的device_node
   6:     of_chosen = of_find_node_by_path("/chosen"); // 找到/chosen節點對應的device_node
   7:     if (of_chosen == NULL) // 如果沒有/chosen的話,就找/chosen@0節點
   8:         of_chosen = of_find_node_by_path("/chosen@0");
   9:  
  10:     if (of_chosen) {
  11:         /* linux,stdout-path and /aliases/stdout are for legacy compatibility */
  12:         const char *name = of_get_property(of_chosen, "stdout-path", NULL);
  13:         if (!name)
  14:             name = of_get_property(of_chosen, "linux,stdout-path", NULL);
  15:         if (IS_ENABLED(CONFIG_PPC) && !name)
  16:             name = of_get_property(of_aliases, "stdout", NULL);
  17:         if (name)
  18:             of_stdout = of_find_node_opts_by_path(name, &of_stdout_options);
  19:     }
  20:  
  21:     if (!of_aliases)
  22:         return;
  23:  
  24:     for_each_property_of_node(of_aliases, pp) { // 遍歷/aliases節點的屬性,以屬性i2c2 = "/i2c@13880000";為例
  25:         const char *start = pp->name; // 屬性的名字,如"i2c2"
  26:         const char *end = start + strlen(start); // 名字的結尾,*end是'/0'
  27:         struct device_node *np;
  28:         struct alias_prop *ap;
  29:         int id, len;
  30:  
  31:         /* 不處理名字是name、phandle、linux,phandle的屬性 */
  32:         if (!strcmp(pp->name, "name") || 
  33:             !strcmp(pp->name, "phandle") ||
  34:             !strcmp(pp->name, "linux,phandle"))
  35:             continue;
  36:  
  37:         np = of_find_node_by_path(pp->value); 
  38:         /*
  39:             根據屬性的值(如"/i2c@13880000")獲得這個值對應的節點
  40:             i2c@13880000 {
  41:                 #address-cells = <0x1>;
  42:                 #size-cells = <0x0>;
  43:                 compatible = "samsung,s3c2440-i2c";
  44:                 reg = <0x13880000 0x100>;
  45:                 interrupts = <0x0 0x3c 0x0>;
  46:                 clocks = <0x7 0x13f>;
  47:                 clock-names = "i2c";
  48:                 pinctrl-names = "default";
  49:                 pinctrl-0 = <0x22>;
  50:                 status = "disabled";
  51:             };        
  52:         */
  53:         if (!np)
  54:             continue;
  55:  
  56:         /* walk the alias backwards to extract the id and work out
  57:          * the 'stem' string */
  58:         while (isdigit(*(end-1)) && end > start) //對于"i2c2",end最終會指向字符'2'的地址
  59:             end--;
  60:         len = end - start; // 獲得"i2c"的長度(不包含結尾的數字2),就是3
  61:  
  62:         if (kstrtoint(end, 10, &id) < 0) // 將end指向的字符'2'轉化為數字2,賦值給id
  63:             continue;
  64:  
  65:         /* Allocate an alias_prop with enough space for the stem */
  66:         ap = dt_alloc(sizeof(*ap) + len + 1, 4); // 分配內存,多分配的"len+1"用于存放stem的名字
  67:         if (!ap)
  68:             continue;
  69:         memset(ap, 0, sizeof(*ap) + len + 1);
  70:         ap->alias = start; // ap->alias指向字符串"i2c2"
  71:         of_alias_add(ap, np, id, start, len);
  72:     }
  73: }

of_alias_add:

   1: static void of_alias_add(struct alias_prop *ap, struct device_node *np,
   2:              int id, const char *stem, int stem_len)
   3: {
   4:     ap->np = np; // np是"/i2c@13880000"對應的節點device_node
   5:     ap->id = id; // id的值是2
   6:     strncpy(ap->stem, stem, stem_len); // 由于stem_len是3,所以ap->stem被賦值為"i2c"
   7:     ap->stem[stem_len] = 0;
   8:     list_add_tail(&ap->link, &aliases_lookup); // 將這個ap加入到全局aliases_lookup鏈表中
   9:     pr_debug("adding DT alias:%s: stem=%s id=%i node=%s/n",
  10:          ap->alias, ap->stem, ap->id, of_node_full_name(np));
  11: }

使用:

在drivers/i2c/i2c-core.c中:

   1: int i2c_add_adapter(struct i2c_adapter *adapter)
   2: {
   3:     struct device *dev = &adapter->dev;
   4:     int id;
   5:  
   6:     if (dev->of_node) {
   7:         id = of_alias_get_id(dev->of_node, "i2c");
   8:         if (id >= 0) {
   9:             adapter->nr = id;
  10:             return __i2c_add_numbered_adapter(adapter);
  11:         }
  12:     }
  13:     ... ...
  14: }

第7行調用of_alias_get_id獲得與這個device_node(即/i2c@13880000節點)對應的alias_prop的id,如果以/i2c@13880000節點為例,這里得到的id就是2。

of_alias_get_id:

   1: int of_alias_get_id(struct device_node *np, const char *stem)
   2: {
   3:     struct alias_prop *app;
   4:     int id = -ENODEV;
   5:  
   6:     mutex_lock(&of_mutex);
   7:     list_for_each_entry(app, &aliases_lookup, link) { // 遍歷全局鏈表aliases_lookup
   8:         if (strcmp(app->stem, stem) != 0) // 找到 stem 是 "i2c" 的alias_prop
   9:             continue;
  10:  
  11:         if (np == app->np) { // 判斷這個alias_prop指向的device_node是不是跟傳入的匹配
  12:             id = app->id;  // 獲得 id,2
  13:             break;
  14:         }
  15:     }
  16:     mutex_unlock(&of_mutex);
  17:  
  18:     return id;
  19: }

 

從上面的分析就可以知道alias節點的作用了:

比如SoC上有如果多個i2c控制器,alias的相當於給每個i2c控制器分配一個唯一的編號,如上面的i2c@13880000對應的alias是i2c2,那麼這個編號就是2,將來就可以在/dev下看到名爲i2c-2的設備節點。

在內核中可以看到很多地方都會調用of_alias_get_id,他的作用就是根據傳入的device node,在alias中找到對應的唯一編號,如:

of_alias_get_id(pdev->dev.of_node, "spi")

of_alias_get_id(node, "fimc")

of_alias_get_id(pdev->dev.of_node, "serial")

of_alias_get_id(pdev->dev.of_node, "uart")

of_alias_get_id(dev->of_node, "gpio")

... ...

完。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
九九热精品视频国产| 成人久久久久久| wwwwwwww亚洲| 欧美另类高清videos| 亚洲国产古装精品网站| 2018中文字幕一区二区三区| 欧美日韩国产999| 最近2019年中文视频免费在线观看| 国内精品久久久久久中文字幕| 久久亚洲成人精品| 欧美韩国理论所午夜片917电影| 日本成人精品在线| 国产精品久久久久久久久久小说| 国产一区二区三区在线观看网站| 欧美特黄级在线| 97成人超碰免| 91麻豆国产语对白在线观看| 欧美激情二区三区| 国产一区二区三区毛片| 久久久久久久久91| 精品动漫一区二区三区| 国产精自产拍久久久久久| 色七七影院综合| 日韩精品免费在线视频| 亚洲欧美日韩国产中文专区| 九九热这里只有精品6| 一区二区在线视频| 精品呦交小u女在线| 欧美激情精品久久久久久免费印度| 日韩美女福利视频| 亚洲人成在线播放| 久久精品亚洲国产| 久久久久久久久久久免费| 亚洲日本中文字幕免费在线不卡| 国产精品久久久久免费a∨大胸| 日本免费一区二区三区视频观看| 国产精品久久久av久久久| 久久久久久久亚洲精品| 亚州精品天堂中文字幕| 川上优av一区二区线观看| 久久成人一区二区| 久久久这里只有精品视频| 国内精品一区二区三区| 国色天香2019中文字幕在线观看| 亚洲国产美女久久久久| 91精品国产乱码久久久久久久久| 欧美日韩在线视频观看| 26uuu另类亚洲欧美日本老年| 欧美中文在线观看| 欧美在线视频网站| 亚洲高清福利视频| 欧美巨乳在线观看| 日韩亚洲欧美中文高清在线| 国产成人综合一区二区三区| 亚洲激情视频在线观看| 亚洲自拍小视频免费观看| 亚洲精品久久久久久久久久久| 色综合久久悠悠| 亚洲欧美国产日韩中文字幕| 精品久久久久久久久久久久久| 81精品国产乱码久久久久久| 国产v综合ⅴ日韩v欧美大片| 欧美另类交人妖| 欧美日韩中文字幕综合视频| 国产男女猛烈无遮挡91| 亚洲欧美日韩爽爽影院| 亚洲少妇激情视频| 午夜欧美不卡精品aaaaa| 国产一区二区黄| 丝袜一区二区三区| 日韩av在线网| 国产日韩欧美成人| 亚洲图片在区色| 欧美激情视频免费观看| 日韩美女视频中文字幕| 中文字幕日韩有码| 亚洲精品电影在线| 成人免费观看网址| 亚洲精品www久久久久久广东| 成人a级免费视频| 国产亚洲视频在线| 亚洲精品国产拍免费91在线| 欧美性猛交xxxx免费看| 欧美激情精品久久久久久| www.色综合| 久久久精品久久久久| 97香蕉超级碰碰久久免费软件| 亚洲精品乱码久久久久久按摩观| 日韩av色在线| 欧美精品videos另类日本| 亚洲美女中文字幕| 精品中文字幕在线2019| 亚洲一区二区中文| 亚洲欧美另类在线观看| 久久99视频免费| 草民午夜欧美限制a级福利片| 高清欧美电影在线| 成人日韩在线电影| www.亚洲人.com| 日本一本a高清免费不卡| 久久国产精品久久久久久| 国产精品毛片a∨一区二区三区|国| 亚洲国产精品电影在线观看| 91精品国产高清自在线| 正在播放欧美一区| 亚洲综合一区二区不卡| 91精品91久久久久久| 成人免费看黄网站| 91免费看片在线| 欧美电影免费观看网站| 欧美最猛性xxxxx(亚洲精品)| 精品久久久久久久大神国产| 中国china体内裑精亚洲片| 欧美精品免费在线观看| 久久精品视频中文字幕| 日韩免费在线观看视频| 日韩av在线一区二区| 国产精品久久久久久久电影| 久久精品视频99| 不卡av在线网站| 久久精品99无色码中文字幕| 日韩中文字幕国产精品| 亚洲аv电影天堂网| 亚洲xxxx18| 午夜精品在线观看| 欧美大肥婆大肥bbbbb| 日韩精品视频在线| 日本成熟性欧美| 国产视频综合在线| 成人免费午夜电影| 中文字幕精品网| 日韩美女视频中文字幕| 久久这里有精品视频| 亚洲精品永久免费| 国产精品视频自在线| 精品国产成人在线| 欧美性生交xxxxxdddd| 久久精品国产99国产精品澳门| 国产欧美精品va在线观看| 日韩av大片在线| 精品无人国产偷自产在线| 精品视频久久久| 国产福利精品视频| 91九色国产视频| 色哟哟亚洲精品一区二区| 国产精品久久久久久av下载红粉| 成人免费黄色网| 久久影院模特热| 日本一本a高清免费不卡| 一本色道久久综合亚洲精品小说| 91精品久久久久久久久不口人| 亚洲免费福利视频| 国产精品男女猛烈高潮激情| 亚洲精品不卡在线| 在线激情影院一区| 91久久精品日日躁夜夜躁国产| 日本成熟性欧美| 国产精品爽爽ⅴa在线观看| 日韩欧美aⅴ综合网站发布| 欧美国产日产韩国视频| 色樱桃影院亚洲精品影院| 亚洲aa中文字幕| 欧美在线播放视频| 亚洲乱码av中文一区二区|