of_flat_dt_match_machine的其余部分代碼都是出錯處理及打印,現(xiàn)在我們看of_flat_dt_match的實現(xiàn),該函數(shù)僅僅是直接調(diào)用of_fdt_match而已,不同的是增加了initial_boot_params參數(shù)(還記得我們說過前邊說過的這個變量的初始化吧,其實這就是內(nèi)核中的一個簡單封裝而已)。
685 /**
686 * of_flat_dt_match - Return true if node matches a list of compatible values
687 */
688 int __init of_flat_dt_match(unsigned long node, const char *const *compat)
689 {
690 return of_fdt_match(initial_boot_params, node, compat);
691 }
of_fdt_match函數(shù)從142行開始遍歷compat數(shù)組的每一個字符串,然后通過of_fdt_is_compatible函數(shù)計算匹配度(以最小的數(shù)值作為最終的結果)。代碼到這個地方已經(jīng)很好理解了,compat中的數(shù)據(jù)來自內(nèi)核的.arch.info.init段,這個段表示內(nèi)核支持的平臺,blob是設備樹其實地址,通過node節(jié)點指定根節(jié)點的compatible屬性,然后計算匹配度。還記得我們前邊說過的 compatible屬性包含多個字符串,從前向后范圍越來越大,優(yōu)先匹配前邊的,這個地方代碼計算分數(shù)(score變量)就是這個目的。
131 /**
132 * of_fdt_match - Return true if node matches a list of compatible values
133 */
134 int of_fdt_match(const void *blob, unsigned long node,
135 const char *const *compat)
136 {
137 unsigned int tmp, score = 0;
138
139 if (!compat)
140 return 0;
141
142 while (*compat) {
143 tmp = of_fdt_is_compatible(blob, node, *compat);
144 if (tmp && (score == 0 || (tmp < score)))
145 score = tmp;
146 compat++;
147 }
148
149 return score;
150 }
繼續(xù)看of_fdt_is_compatible函數(shù)的實現(xiàn),第97行已經(jīng)看到找該節(jié)點下的"compatible"屬性了。
80 /**
81 * of_fdt_is_compatible - Return true if given node from the given blob has
82 * compat in its compatible list
83 * @blob: A device tree blob
84 * @node: node to test
85 * @compat: compatible string to compare with compatible list.
86 *
87 * On match, returns a non-zero value with smaller values returned for more
88 * specific compatible values.
89 */
90 int of_fdt_is_compatible(const void *blob,
91 unsigned long node, const char *compat)
92 {
93 const char *cp;
94 int cplen;
95 unsigned long l, score = 0;
96
97 cp = fdt_getprop(blob, node, "compatible", &cplen);
98 if (cp == NULL)
99 return 0;
100 while (cplen > 0) {
101 score++;
102 if (of_compat_cmp(cp, compat, strlen(compat)) == 0)
103 return score;
104 l = strlen(cp) + 1;
105 cp += l;
106 cplen -= l;
107 }
108
109 return 0;
110 }
關于根節(jié)點的"compatible"屬性我們就說到這,一句話總結下就是內(nèi)核通過"compatible"屬性找到對應的平臺描述信息,按照范圍從小到大盡量匹配范圍最小的,如果匹配不到,那么說明內(nèi)核不支持該平臺,系統(tǒng)將在初始化的時候就出錯。
根節(jié)點還可能包含的屬性為#address-cells和#size-cells,規(guī)范中說明這兩個屬性是必須的,實際應用時是可選的,還記得屬性那一節(jié)說這兩個屬性如果沒有都是有默認值的,#address-cells默認值為2,#size-cells默認值為1。根節(jié)點下必須包含的子節(jié)點為 cpus和memory,后邊會說明cpus下邊還有每個cpu的子節(jié)點,memory節(jié)點下邊定義的就是memory的起始地址及大小,所以根節(jié)點的#address-cells和#size-cells屬性實際上說明的就是從cpu角度看系統(tǒng)總線的地址長度和大小。
規(guī)范中還寫根節(jié)點下邊必須有一個epapr-version屬性用來描述設備樹的版本,實際上在linux中根本不用這個屬性。
2015職稱計算機考試書PowerPoint2007中 .. 定價:¥45 優(yōu)惠價:¥42 更多書籍 | |
2015年全國職稱計算機考試教材(2007模 .. 定價:¥225 優(yōu)惠價:¥213 更多書籍 |