第四期 第六讲 Linux设备树详解 第七讲 设备树下的LED驱动实验

第六讲 Linux设备树详解

一、什么是设备树

1、uboot启动内核用到zImage,imx6ull-alientek-emmc.dtb。bootz 80800000 – 83000000.

2、设备树:设备和树。

3,在单片机驱动里面比如W25QXX,SPI,速度都是在.c文件里面写死。板级信息都写到.c里面,导致linux内核臃肿。因此 将板子信息做成独立的格式,文件扩展名为.dts。一个平台或者机器对应一个.dts。

二、DTS、DTB和DTC的关系

.dts相当于.c,就是DTS源码文件。

DTC工具相当于gcc编译器,将.dts编译成.dtb。

.dtb相当于bin文件,或可执行文件。

通过make dtbs编译所有的dts文件。如果要编译指定的dtbs

make imx6ull-alientek-emmc.dtb

三、DTS基本语法

1、设备树也有头文件,扩展名为.dtsi。可以将一款SOC他的其他所有设备/平台的共有的信息提出来,作为一个通用的.dtsi文件。

1、DTS也是’/’开始

2,从/根节点开始描述设备信息

3,在/根节点外有一些&cpu0这样的语句是“追加“。

4,节点名字,完整的要求

node-name@unit-address

unit-address一般都是外设寄存器的起始地址,有时候是I2C的设备地址,或者其他含义,具体节点具体分析。设备树里面常常遇到如下所示节点名字:

*intc: interrupt-controller@00a01000*

:前面是标签label,后面才是名字。intc,完整的名字是interrupt-controller@00a01000。&intc

四、创建小型的设备树模板

五、设备树在系统中的体现

系统启动以后可以在根文件系统里面看到设备树的节点信息。在/proc/device-tree/目录下存放着设备树信息。

内核启动的时候会解析设备树,然后在/proc/device-tree/目录下呈现出来。

六、特殊节点

1,aliases

2,chosen节点,主要目的就是将uboot里面bootargs环境变量值,传递给Linux内核作为命令行参数,cmd line。uboot里面bootargs值为:

bootargs=console=ttymxc0,115200 rw root=/dev/nfs nfsroot=192.168.1.249:/home/zzk/linux/nfs/rootfs ip=192.168.1.50:192.168.1.249:192.168.1.1:255.255.255.0::eth0:off

linux内核cmdline值为:

Kernel command line: console=ttymxc0,115200 rw root=/dev/nfs nfsroot=192.168.1.249:/home/zzk/linux/nfs/rootfs ip=192.168.1.50:192.168.1.249:192.168.1.1:255.255.255.0::eth0:off

uboot是如何向kernel传递bootargs。

经过查看发现chosen节点中包含bootargs属性,属性值和uboot的bootargs一致。

uboot接触过dtb,最终通过bootz 80800000 – 83000000 来启动内核。经过分析判断uboot拥有bootargs环境变量和dtb,因此最有可能“作案”。

最终发现在uboot的fdt_chosen函数中会查找chosen节点,并且在里面添加bootargs属性,属性值为bootargs变量值。

七、特殊的属性

1、compatible属性,值是字符串。

根节点/下面的compatible。内核启动的时候会检查是否支持此平台,或机器。

不使用设备树的时候通过machine id来判断内核是否支持此机器。

#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")

/* Maintainer: Freescale Semiconductor, Inc */

.atag_offset = 0x100,

.map_io = mx35_map_io,

.init_early = imx35_init_early,

.init_irq = mx35_init_irq,

.init_time = mx35pdk_timer_init,

.init_machine = mx35_3ds_init,

.reserve = mx35_3ds_reserve,

.restart = mxc_restart,

MACHINE_END

展开以后:

static const struct machine_desc mach_desc_MX35_3DS used

attribute((section(".arch.info.init"))) = {

*.nr* *= MACH_TYPE_MX35_3DS,* *//**机器I****D***

.name = "Freescale MX35PDK",

.atag_offset = 0x100,

.map_io = mx35_map_io,

.init_early = imx35_init_early,

.init_irq = mx35_init_irq,

.init_time = mx35pdk_timer_init,

.init_machine = mx35_3ds_init,

.reserve = mx35_3ds_reserve,

.restart = mxc_restart,

};

使用设备树的时候不使用机器ID,而是使用根节点/下的compatible。

#define DT_MACHINE_START(_name, _namestr) \

static const struct machine_desc _mach_desc##_name \

__used \

attribute((section(".arch.info.init"))) = { \

.nr = ~0, \

.name = _namestr,

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

展开以后就是:

static const struct machine_desc mach_desc_IMX6UL used

attribute((section(".arch.info.init"))) = {

*.nr* *= ~0,*

.name = "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,*

};

八、Linux内核的OF操作函数

1、驱动如何获取到设备树中节点信息。在驱动中使用OF函数获取设备树属性内容。

2,驱动要想获取到设备树节点内容,首先要找到节点。

第七讲 设备树下的LED驱动实验

一、设备树LED驱动原理

二、修改设备树文件

设备节点最好添加到好区分的地方,1级节点是最好的地方。

三、编写驱动

四、运行测试

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值