linux加载dts的时候会创建设备节点吗

linux加载dts的时候会创建设备节点吗,第1张

From:http://m.blog.csdn.net/blog/liliyaya/9188193

1. 在\kernel\of\fdt.c 中有如下初始化函数 注释上:展开设备树,创建device_nodes到全局变量allnodes中

void __init unflatten_device_tree(void)

{

__unflatten_device_tree(initial_boot_params, &allnodes,

early_init_dt_alloc_memory_arch)

/* Get pointer to "/chosen" and "/aliasas" nodes for use everywhere */

of_alias_scan(early_init_dt_alloc_memory_arch)

}

unflatten_device_tree函数被setup_arch函数调用,

因为我们使用得是arm平台所以存在\kernel\arch\arm\kernel\setup.c中

void __init setup_arch(char **cmdline_p)

{

unflatten_device_tree()

}

setup_arch函数在kernel启动是被调用,如下启动kernel存在\kernel\init\main.c中

asmlinkage void __init start_kernel(void)

{

setup_arch(&command_line)

}

这些工作完成解析DTS文件。保存到全局链表allnodes中。

2、在makefile中有这段话来编译dts文件:

$(obj)/A20%.dtb: $(src)/dts/A20%.dts FORCE

$(call if_changed_dep,dtc)

$(obj)/A68M%.dtb: $(src)/dts/A68M%.dts FORCE

$(call if_changed_dep,dtc)

和.c文件生成.o文件一样 回生成.dtb文件。在

/home/liyang/workspace/SZ_JB-mr1-8628-bsp-1012/out/target/product/msm8226/obj/KERNEL_OBJ/arch/arm/boot

目录下,与zimage一个目录。

3、

在 board-8226.c中有初始化函数-->启动自动掉用

void __init msm8226_init(void)

{

of_platform_populate(NULL, of_default_bus_match_table, adata, NULL)

}

of_platform_populate在kernel\driver\of\platform.c中定义,回查询

root = root ? of_node_get(root) : of_find_node_by_path("/")

for_each_child_of_node(root, child)

{

rc = of_platform_bus_create(child, matches, lookup, parent, true)

if (rc)

break

}

of_node_put(root)

在这里用到得函数of_find_node_by_path会最终调用到kernel\driver\of\base.c中得函数

struct device_node *of_find_node_by_path(const char *path)

{

遍历第1步中得allnodes找到根节点

}

of_platform_bus_create()函数中创建得内容存在了 adata中。

以下内容为转载:

(2)使用DTS注册总线设备的过程

以高通8974平台为例,在注册i2c总线时,会调用到qup_i2c_probe()接口,该接口用于申请总线资源和添加i2c适配器。在成功添加i2c适配器后,会调用of_i2c_register_devices()接口。此接口会解析i2c总线节点的子节点(挂载在该总线上的i2c设备节点),获取i2c设备的地址、中断号等硬件信息。然后调用request_module()加载设备对应的驱动文件,调用i2c_new_device(),生成i2c设备。此时设备和驱动都已加载,于是drvier里面的probe方法将被调用。后面流程就和之前一样了。

简而言之,Linux采用DTS描述设备硬件信息后,省去了大量板文件垃圾信息。Linux在开机启动阶段,会解析DTS文件,保存到全局链表allnodes中,在掉用.init_machine时,会跟据allnodes中的信息注册平台总线和设备。值得注意的是,加载流程并不是按找从树根到树叶的方式递归注册,而是只注册根节点下的第一级子节点,第二级及之后的子节点暂不注册。Linux系统下的设备大多都是挂载在平台总线下的,因此在平台总线被注册后,会根据allnodes节点的树结构,去寻找该总线的子节点,所有的子节点将被作为设备注册到该总线上。

Linux源码的arch/powerpc/boot/dts/目录下存放了很多dts文件,可以作为参考文件。另外dtc编译器在内核源码2.6.25版本之后已经被包含进去。在2.6.26版本之后,生成blob的简单规则已经加入makefile,如下命令:

$ make ARCH=powerpc canyonlands.dtb

也可以根据自己的硬件修改好dts文件后,用下面类似命令生成dtb文件。

$ dtc -f -I dts -O dtb -R 8 -S 0x3000 test.dts >mpc836x_mds.dtb

$ mkimage -A ppc -O Linux -T flat_dt -C none -a 0x300000 -e 0 -d mpc836x_mds.dtb mpc836x_mds.dtu

dtb文件作用的描述是,使用dtb可以减少linux内核版本的数量。同一份linux 内核代码可以在多个板卡上运行,每个板卡可以使用自己的dtb文件。

1,在linux内核启动过程中会解析dtb文件,根据dtb文件中设备列表进行加注各个外设的驱动模块。

2,PC机在启动时会自动扫描外设,而在嵌入式中,linux内核启动过程中只是解析dtb文件,从而加载对应的模块。

3,编译linux内核时必须选择某外设模块,并且dtb中包括该外设的信息。在linux内核启动过程中才能自动加载该模块。

要使用dtb,需要uboot启动内核时,在bootm命令中指定dtb的位置,格式为:

bootm uImage_addr ramdisk_addr dtb_addr

如果没有ramdisk,就需要写成bootm uImage_addr - dtb_addr,用“-”表示没有ramdisk


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/7390344.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-05
下一篇 2023-04-05

发表评论

登录后才能评论

评论列表(0条)

保存