3.5.1.196. of_compat_cmp
#define of_compat_cmp(s1, s2, l) strcasecmp((s1), (s2))
of_compat_cmp
用于对比device-node的compatible属性字符串是否相同
3.5.1.197. _OF_DECLARE
#if defined(CONFIG_OF) && !defined(MODULE)
#define _OF_DECLARE(table, name, compat, fn, fn_type) \
static const struct of_device_id __of_table_##name \
__used__section(__##table##of_table) \
= {.compatible = compat, \
.data = (fn == (fn_type)NULL) ? fn : fn}
#else
#define _OF_DECLARE(table, name, compat, fn, fn_type) \
static const struct of_device_id __of_table_##name \
__attribute__((unused)) \
= {.compatible = compat,
.data = (fn == (fn_type)NULL) ? fn : fn}
#endif
_OF_DECLARE
用于定义个DTS compatible表,宏定义了一个struct of_devie_id结构,并将该数据结构存储在私有section内,
宏为数据结构提供了compat和fn两个初始参数
3.5.1.198. of_fdt_device_is_available
static bool of_fdt_device_is_available(const void *blob, unsigned long node)
{
const char *status = fdt_getprop(blob, node, "status", NULL);
if(!status)
return true;
if(!strcmp(status, "ok") || !strcmp(status, "okay"))
return true;
return false;
}
of_fdt_device_is_available
检查节点的”status”属性值是否为”okay”或”ok”
3.5.1.199. of_fdt_is_compatible
//blob: 指向dtb
//node: device-node在dtb devicetree structure内的偏移
//compat: 需要查找节点的compatible
static int of_fdt_is_compatible(const void *blob, unsigned long node, const char *compat)
{
const char *cp;
int cplen;
unsigned long l, score = 0;
//获取节点的compatible值
cp = fdt_getprop(blob, node, "compatible", &cplen);
if(cp == NULL)
return 0;
//循环对比节点的compatible属性值是否包含参数compat
while(cplen > 0) {
score++;
if(of_compat_cmp(cp, compat, strlen(compat)) == 0)
return score;
l = strlen(cp) + 1;
cp += l;
cplen -= l;
}
return 0;
}
of_fdt_is_compatible
用于检查节点的compatible属性值是否与参数compat相同
3.5.1.200. of_flat_dt_is_compatible
int __init of_flat_dt_is_compatible(unsigned long node, const char *compat)
{
return of_fdt_is_compatible(initial_boot_params, node, compat);
}
of_flat_dt_is_compatible
用于判断节点的compatible属性是否包含compat参数
3.5.1.201. of_flat_dt_match_machine
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;
//获取dts根节点在dtb devicetree structure区域内的偏移
dt_root = of_get_flat_dt_root();
//获取machine对应的compatible属性
while((data = get_next_compat(&compat))) {
//对比machine提供的compatible与dtb根节点的compatible是否相同
score = of_flat_dt_match(dt_root, compat);
if(score > 0 && score < best_score) {
//如果相同则将best_data设置为data
best_data = data;
best_score = score;
}
}
//如果best_data为0,那么dtb不是有效的dtb
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;
}
return best_data;
}
of_flat_dt_match_machine
用于对比dtb根节点的compatible属性值与machine_desc数据结构中dt_compat成员是否相同
3.5.1.202. of_get_flat_dt_prop
const void * __init of_get_flat_dt_prop(unsigned long node, const char *name, int *size)
{
return fdt_getprop(initial_boot_params, node, name, size);
}
of_get_flat_dt_prop
用于从dtb中获得device-node name参数对应的属性值
3.5.1.203. of_get_flat_dt_root
unsigned long __int of_get_flat_dt_root(void)
{
return 0;
}
of_get_flat_dt_root
用于获得dts根节点在dtb devicetree structure中的偏移,root的偏移为0
3.5.1.204. of_scan_flat_dt
int __init of_scan_flat_dt(int (*it)(unsigned long node, const char *uname, int depth, void *data), void *data)
{
const void *blob = initial_boot_params;
const char *pathp;
int offset, rc = 0, depth = -1;
if(!blob)
return 0;
for(offset = fdt_next_node(blob, -1, &depth);
offset >= 0 && depth >= 0 && !rc;
offset = fdt_next_node(blob, offset, &depth)) {
pathp = fdt_get_name(blob, offset, NULL);
if(*pathp == '/')
pathp = kbasenname(pathp);
rc = it(offset, pathp, depth, data);
}
return rc;
}
fdt_scan_flat_dt
用于遍历dtb中所有节点