当前位置: 首页 > news >正文

Linux驱动开发笔记(五)——设备树(中)——节点的标准属性

一、标准属性

视频:第6.6讲 Linux设备树详解-设备树中的标准属性_哔哩哔哩_bilibili

对应《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81.pdf》43.3.3部分

英文资料可见04、参考资料/Power_ePAPR_APPROVED_v1.12.pdf的2.3部分

1.1 compatible

        每一个具体的设备节点下都有compatible属性,其内容是字符串类型,用于描述设备的兼容性。

        格式为:

"manufacturer,model" 

        其中manufacturer为厂商,model一般是模块对应的驱动名字。

        一般驱动程序文件都会有一个OF兼容性列表,保存着可以兼容的属性,如果其他设备节点的compatible值和OF列表中有相同的字符串,就表示设备可以使用这个驱动。

1.2 model

        也是一个字符串,描述模块信息、名字等。

1.3 status

        也是字符串,描述设备的状态信息

        一般在头文件dtsi文件中都是默认disabled,使用时在dts中追加修改为okay。

1.4 #address-cells 和  #size-cells 和 reg

       #address-cells:32位unsigned int,决定了子节点reg属性中地址信息所占用的字长(32位),

       #size-cells:32位unsigned int,决定了子节点reg属性中长度信息所占的字长(32位)。

       reg属性一般都是和地址有关的内容,reg属性的格式为:

reg = <address1 length1 address2 length2 address3 length3……> 

        比如imx6ull.dtsi中:

// 837行:
aips1: aips-bus@02000000 {    // 首地址为0x02000000compatible = "fsl,aips-bus", "simple-bus";#address-cells = <1>;#size-cells = <1>;reg = <0x02000000 0x100000>;    // 首地址为0x02000000,长度为0x100000ranges;…………
// 939行:i2c1: i2c@021a0000 {    // 首地址为021a0000#address-cells = <1>;#size-cells = <0>;compatible = "fsl,imx6ul-i2c", "fsl,imx21-i2c";reg = <0x021a0000 0x4000>;    // 首地址为0x021a0000,长度为0x4000interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clks IMX6UL_CLK_I2C1>;status = "disabled";};};

        aips1中的address-cells和size-cells规定的是它的子节点,也就是i2c1的reg属性,而不是aips1自己的reg属性,表示i2c1中的reg。                                                                                                  同理,i2c1的address-cells和size-cells规定的是i2c1的子节点reg属性,而不是i2c1自己的reg属性,其addres=0,表示没有length的值,相当于设置了起始地址,而没有设置地址长度。

       如果父节点中#address-cells = <2>,#size-cells = <1>,然后子节点的reg = <a b c d e f>(这里用字母代指),那么<a b>为地址,c为地址长度,<d e>为地址,f为长度,依然是地址、长度交替。

        那么这里i2c1并没有子节点,为什么要写#address、#size呢?因为还有&,在imx6ull-alientek-emmc.dts中搜索&i2c1就可以找到:

&i2c1 {…………mag3110@0e {reg = <0x0e>;…………};fxls8471@1e {reg = <0x1e>;…………};
};

1.5 rag

        合并到1.4一块写了。

1.6 ranges

       ranges格式为(child-bus-address,parent-bus-address,length),也可以为空。ranges是一个地址映射/转换表,ranges属性每个项目由子地址、父地址和地址空间长度这三部分组。

        child-bus-address:子总线地址空间的物理地址,由父节点的#address-cells确定此物理地址 所占用的字长。         parent-bus-address:父总线地址空间的物理地址,由父节点的#address-cells确定此物理地址所占用的字长。         length:子地址空间的长度,由父节点的#size-cells确定此地址长度所占用的字长。

        如果ranges属性值为空值,说明子地址空间和父地址空间完全相同,不需要进行地址转换。

1.7 name

        name属性用于指定节点名称,字符串类型。

        此属性已弃用,自己写设备树的时候可以不加name,但是老版本的代码还是能看到这个东西。

1.8 device_type

        device_type属性在IEEE 1275中用于描述设备的FCode编程模型。由于ePAPR没有FCode,因此该属性的已被弃用。为了与IEEE 1275衍生的设备树兼容,只在cpu和memory节点上能看到这个东西。

1.9 根节点的 compatible

第6.7讲 Linux设备树详解-根节点下的compatible属性作用_哔哩哔哩_bilibili

        1.1中提到每一个具体的设备节点下都有compatible属性,用来找驱动。但是根节点下也能见到compatible属性,用于判断内核是否支持这个设备。

        内核只能在指定的板子上运行。Linux内核启动时会通过根节点的compoatible属性查看是否支持此设备,如果支持的话设备就会启动Linux内核。

        1.9.1 没有设备树

        (这部分不重要,直接看有设备树的部分就行)

       在那个没有设备树的年代,uboot会向Linux内核传递一个叫做machine id的值,也就是设备ID。内核针对每个支持的设备,都用MACHINE_START和MACHINE_END来定义一个machine_desc结构体来描述这个设备。

        for example,在/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/arch/arm/mach-imx/mach-mx35_3ds.c中能看到:

MACHINE_START(MX35_3DS, "Freescale MX35PDK")/* Maintainer: Freescale Semiconductor, Inc */.atag_offset = 0x100,…………
MACHINE_END

        其中 MACHINE_START 和 MACHINE_END 定义在linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/arch/arm/include/asm/mach/arch.h:

#define MACHINE_START(_type,_name)            \
static const struct machine_desc __mach_desc_##_type    \__used                            \__attribute__((__section__(".arch.info.init"))) = {    \.nr        = MACH_TYPE_##_type,        \.name        = _name,#define MACHINE_END                \
};

把他俩合起来,再把MACHINE_START(MX35_3DS, "Freescale MX35PDK")代入可得:

#define MACHINE_START(_type,_name)            \
static const struct machine_desc __mach_desc_MX35_3DS __used__attribute__((__section__(".arch.info.init"))) = {.nr        = MACH_TYPE_MX35_3DS,     // 替换_type   这个就是machine id.name        = "Freescale MX35PDK",  // 替换_name.atag_offset = 0x100,…………
};

        MACH_TYPE_MX35_3DS在哪里定义?在/home/for/linux/imx6ull/linux/linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/include/generated/mach-types.h中可以找到,里面罗列了所有内核支持的设备,有匹配项则表示内核可以在该设备上运行:

        1.9.2 有设备树

        linus说要有设备树,于是便有了设备树。有了设备树以后就不再使用machine id了,而是根节点下的compatible。

// 定义于linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/arch/arm/mach-imx/mach-imx6ul.c
DT_MACHINE_START(IMX6UL, "Freescale i.MX6 Ultralite (Device Tree)").map_io		= imx6ul_map_io,.init_irq	= imx6ul_init_irq,.init_machine	= imx6ul_init_machine,.init_late	= imx6ul_init_late,.dt_compat	= imx6ul_dt_compat,    // 定义了内核支持的设备
MACHINE_END

和MACHINE_START相比,DT_MACHINE_START只是修改了.nr这一行,表示不再使用.nr:

// 定义于linux-imx-rel_imx_4.1.15_2.1.0_ga_alientek/arch/arm /include/asm/mach/arch.h
#define DT_MACHINE_START(_name, _namestr)		\
static const struct machine_desc __mach_desc_##_name	\__used							\__attribute__((__section__(".arch.info.init"))) = {	\.nr		= ~0,				\.name		= _namestr,

arch/arm/mach-imx/mach-imx6ul.c中可以看到:

static const char *imx6ul_dt_compat[] __initconst = {"fsl,imx6ul","fsl,imx6ull",NULL,
};

        说明该内核支持"fsl,imx6ul"、"fsl,imx6ull",现在看看arch/arm/boot/dts/imx6ull-alientek-emmc.dts的compatible:

        非常的巧啊,这个内核能在imx6ull上跑起来。如果你改掉这个compatible,再编译为dtb,再cp到tftproot下,重启板子,就会发现板子卡在starting kernel了。

http://www.dtcms.com/a/301358.html

相关文章:

  • 益莱储:明智地投资测试仪器
  • S7-1500 与 S7-1200 存储区域保持性设置特点详解
  • 电子板原理功能区解析与PlantUML图示
  • 3,Windows11安装docker保姆级教程
  • 轻量化多模态文档处理利器SmolDocling:技术原理与场景落地引言:文档智能处理的范式革命
  • 数据结构基础内容(第六篇:二叉搜索与平衡二叉树)
  • MySQL锁机制与MVCC原理剖析
  • 直播带货工具About v1.5.10 免费版
  • GEO优化实战:如何在DeepSeek、豆包等AI平台抢占推荐位?
  • MOE架构详解:原理、应用与PyTorch实现
  • 计算圆周率(π)代码实现【c++】
  • Java中排序规则详解
  • cJSON在STM32单片机上使用遇到解析数据失败问题
  • 计算柱状图中最大的矩形【单调栈】
  • Dify 本地化部署深度解析与实战指南
  • 蜣螂优化算法的华丽转身:基于Streamlit的MSIDBO算法可视化平台
  • 【ESP32设备通信】-W5500与ESP32 /ESP32 S3集成
  • MySQL - 性能优化
  • Java面试实战:电商高并发与分布式事务处理
  • maven optional 功能详解
  • Java进阶7:Junit单元测试
  • 数据结构基础内容(第九篇:最短路径)
  • OpenCv中的 KNN 算法实现手写数字的识别
  • 电子电路设计学习
  • git回退版本教程
  • Java validation
  • Java学习第八十部分——Freemarker
  • Linux c网络专栏第三章DPDK
  • Petalinux驱动开发
  • Linux驱动开发笔记(五)——设备树(下)——OF函数