当使用compatible属性跟machine_desc中的dt_compat比较时,按照上述的优先级进行匹配。 那么代码是如何实现的呢?请看如下函数的调用过程:
这里需要强调下arch_get_next_mach()函数,取出一个machine_desc,返回其中的dt_compat成员,每调用一次arch_get_next_mach()函数,返回下一个machine_desc的dt_compat成员。 内核中有多个machine_desc,这些结构体有一个段属性值,在编译的时候,会将多个machine_desc结构体放在一起,如下示意图。 取出的machine_desc的dt_compat成员用来跟设备树中的compatible进行比较匹配,
MACHINE_START(DAVINCI_DM365_EVM, "DaVinci DM365 EVM") .atag_offset = 0x100, .map_io = dm365_evm_map_io, .init_irq = dm365_init_irq, .init_time = dm365_init_time, .init_machine = dm365_evm_init, .init_late = davinci_init_late, .dma_zone_size = SZ_128M, MACHINE_END下面的__section__(".arch.info.init")为段属性 段属性等于这个值的所有的结构体都会放在一起(见上示意图)
/* * Set of macros to define architecture features. * This is built into a table by the linker. */ #define MACHINE_START(_type, _name) \ static const struct machine_desc __mach_desc_##_type \ __used \ __attribute__((__section__(".arch.info.init"))) = { \ .name = _name, #define MACHINE_END \ };get_next_compat(&compat)取出一个machine_desc的成员dt_compat 来跟根节点中的compatible的值进行比较(查看of_flat_dt_match(dt_root, compat);)得到他们的score,这score是如何而来呢,见如下dts根节点,按顺序跟"samsung,smdk2440"匹配成功就是1,依次+1。score的值越小,匹配度越高。
/ { model = "SMDK24440"; compatible = "samsung,smdk2440", "samsung,smdk2410", "samsung,smdk24xx"; ................................... }; /** * of_flat_dt_match_machine - Iterate match tables to find matching machine. * * @default_match: A machine specific ptr to return in case of no match. * @get_next_compat: callback function to return next compatible match table. * * Iterate through machine match tables to find the best match for the machine * compatible string in the FDT. */ const void * __init of_flat_dt_match_machine(const void *default_match, const void * (*get_next_compat)(const char * const**)) { const void *data = NULL; const void *best_data = default_match; const char *const *compat; unsigned long dt_root; unsigned int best_score = ~1, score = 0; dt_root = of_get_flat_dt_root(); while ((data = get_next_compat(&compat))) { score = of_flat_dt_match(dt_root, compat); if (score > 0 && score < best_score) { best_data = data; best_score = score; } } if (!best_data) { const char *prop; int size; pr_err("\n unrecognized device tree list:\n[ "); prop = of_get_flat_dt_prop(dt_root, "compatible", &size); if (prop) { while (size > 0) { printk("'%s' ", prop); size -= strlen(prop) + 1; prop += strlen(prop) + 1; } } printk("]\n\n"); return NULL; } pr_info("Machine model: %s\n", of_flat_dt_get_machine_name()); return best_data; }根据韦东山的学习视频《linux设备树详解》中对设备树中平台信息的处理(选择machine_desc)的一节的学习整理