dts文件解析

本文详细介绍了Linux内核中设备树的解析过程及基于设备树的驱动加载流程,包括dtb文件解析生成资源列表、设备节点展示、总线注册、mdio总线驱动注册与绑定等关键步骤。
AI助手已提取文章相关产品:

1. dtb文件解析,生成资源单项列表
-------------------------------------------------------------------
start_kernel() --> setup_arch() --> unflatten_device_tree()
该函数可以解析dtb文件,构建一个由device_node结构连接而成的单项链表。如下在此函数执行过后,在内存中会存在一个如下的链表

后面所有的函数,如果需要从of tree结构上读取设备资料的,都将从这个链表中遍历并读取。



2. 将allnodes显示在/proc/device-tree目录下
-------------------------------------------------------------------
linux-2.6.26
start_kernel() -->
#ifdef CONFIG_PROC_FS
proc_root_init(); -->
#endif
#ifdef CONFIG_PROC_DEVICETREE
proc_device_tree_init(); -->
#endif
proc_device_tree_add_node(root, proc_device_tree);

此时将在/proc/device-tree目录下生成设备节点
# ls -al /proc/device-tree



3.of_platform_bus_type的注册/初始化
-------------------------------------------------------------------
linux2.6.28/arch/powerpc/kernel/of_platform.c
struct bus_typeof_platform_bus_type= {
.uevent = of_device_uevent,
};
EXPORT_SYMBOL(of_platform_bus_type);

static int __init of_bus_driver_init(void)
{
return of_bus_type_init(&of_platform_bus_type, "of_platform");
}
postcore_initcall(of_bus_driver_init);

of_platform_bus_type总线注册完毕。
此时/sys/bus/目录下将会有of_platform


4. 将allnodes设备节点添加到总线of_platform_bus_type
-------------------------------------------------------------------
arch/powerpc/platform/83xx/mpc831x_rdb.c
machine_device_initcall(mpc831x_rdb, declare_of_platform_devices);

declare_of_platform_devices() -->
of_platform_bus_probe(NULL, of_bus_ids, NULL)

arch/powerpc/kernel/of_platform.c
遍历第一步中在内存中生成链表的所有soc的子节点,将所有的soc子节点设备添加到of_platform总线。

of_platform_bus_probe()-->
of_platform_device_create()-->
of_device_register() -->
device_add()

of_platform总线上的所有设备添加完毕,e0024000.ethernet,e0024520.mdio等设备现在都在总线上。至此设备节点将出现在/sys/devices/platform/

3 mdio总线的注册
--------------------------------------------
/driver/net/phy_device.c

subsys_initcall(phy_init)
phy_init --> mdio_bus_init --> bus_register(&mdio_bus_type)

总线注册后,在总线上注册了一个默认的phy的驱动 genphy_driver:

.phy_id = 0xffffffff,
.phy_id_mask = 0xffffffff,
.name = "Generic phy",

mdio总线注册完毕。
/sys/bus/mdio


5 mdio总线上驱动的添加
--------------------------------------------

/driver/net/phy/marvell.c
module_init(marvell_init)
marvell_init() -->
phy_driver_register(&marvell_drivers[i]) -->
driver_register()

前面第三步,注册mdio总线后,已经添加了一个默认的phy的驱动,现在要将所有的phy驱动添加到总线上,这里将所有的marvell的phy都添加。

这步过后,内核的/sys/bus/mdio/driver里面就有了各种phy的驱动,但这时还没有和具体的设备绑定。


6 of_platform总线上mdio设备驱动(该驱动的目的是在mdio总线上添加phy设备)的添加,并绑定设备:e0024520.mdio和e0025520.mdio

/driver/net/fsl_pq_mdio.c
module_init(fsl_pq_mdio_init)
fsl_pq_mdio_init --> of_register_platform_driver(&fsl_pq_mdio_driver) --> of_register_driver --> driver_register --> bus_add_driver --> driver_attach

遍历整个of_platform总线,寻找与之相匹配的设备,找到e0024520.mdio
driver_attach --> __driver_attach --> driver_match_device
将driver的match_table里的信息和dev_nod中的做比较,若符合就进入driver的probe,也就是fsl_pq_mdio_probe。

现在of_platform总线上的设备e0024520.mdio和e0025520.mdio已经绑定了驱动。



7 mdio总线上的设备的添加,寻找并绑定相应的驱动。
/driver/net/fsl_pq_mdio.c
fsl_pq_mdio_probe --> of_mdiobus_register --> phy_device_register --> device_register(&phydev->dev) --> device_add --> bus_probe_device --> device_attach -->bus_for_each_drv
扫描mdio总线上的所有的驱动,若找到匹配的,就绑定,并probe。
__device_attach --> driver_probe_device --> really_probe --> phy_probe

将所有的phy和tbi-phy的设备都添加到mdio总线上,并且两个phy设备和两个tbi-phy设备都会根据其自己的phyID找到各自的驱动

您可能感兴趣的与本文相关内容

Linux DTS(Device Tree Source)文件是设备树源码文件,其内容解析可从以下方面入手: ### 基本符号含义 - `/` 表示根节点,是设备树的起始节点。 - `@` 若设备有地址,则用此符号指定,如 `node-name@unit-address` 。 - `&` 用于引用节点。 - `:` 冒号前的 `label` 是为方便引用给节点起的别名,一般使用 `&label` 来引用。 - 属性名称中可以包含逗号,如 `compatible` 属性的名字组成方式为 `[manufacturer], [model]` ,加入厂商名是为了避免重名,自定义属性名中通常也要有厂商名,并以逗号分隔。 - `#` 并不表示注释,如 `#address-cells` ,`#size-cells` 用来决定 `reg` 属性的格式。 - 空属性并不一定表示没有赋值,如 `interrupt-controller` 一个空属性用来声明这个 node 接收中断信号。 - `""` 引号中的为字符串,字符串数组可表示为 `"strint1","string2","string3"` 。 - `< >` 尖括号中的为 32 位整形数字,整形数组可表示为 `<12 3 4>` 。 - `[ ]` 方括号中的为 32 位十六进制数,十六机制数据可表示为 `[0x11 0x12 0x13]` ,其中 `0x` 可省略 [^3]。 ### 常见属性解析 - `compatible` 属性:用于设备和驱动的匹配,其格式为 `"[manufacturer], [model]"` ,内核会根据此属性来寻找合适的驱动程序。 - `reg` 属性:格式为 `reg = <address1 length1 address2 length2 …>` ,`address` 一般用来表示起始地址,`length` 一般表示持续长度 [^5]。 ### 解析示例 以下是一个简单的 DTS 文件示例及解析: ```dts /dts-v1/; / { model = "My Device Model"; compatible = "mycompany,mydevice"; my_node: my_node@1234 { compatible = "mycompany,mychilddevice"; reg = <0x1234 0x100>; }; }; ``` - 根节点 `/` 下有两个属性: - `model` 属性指定了设备的型号。 - `compatible` 属性用于匹配根设备的驱动。 - `my_node` 节点: - `my_node` 是节点的 `label` ,方便后续引用。 - `my_node@1234` 表示该节点有地址 `0x1234` 。 - `compatible` 属性用于匹配该子设备的驱动。 - `reg` 属性指定了设备的起始地址为 `0x1234` ,长度为 `0x100` 。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值