FDT是ARM
Linux最新的设备驱动程序信息表,使用FDT的内核,就不用像过去的内核那样,一个板子加一个mach的C文件,所有的设备信息可以记录在一个树状信息文件里面。
目前这方面资料比较少,我以AM335x处理器为例概括一下FDT的使用:
FDT仅仅是一个信息的目录和参数表,要使用某个功能内核中还必明枯须有相应的驱动程序代码
FDT的源文件位置在:arch/arm/boot/dts,例如,TI的Beagle bone black,源文件是arch/arm/boot/dts/am335x_boneblack.dts
FDT在make ARCH=arm的时候就会自动生成,也可用make ARCH=arm
dtbs来生成,例如TI的Beagle bone black生成的文件是arch/arm/boot/dts/am335x_boneblack.dtb,这是一个二进制文件
要想新增你自定义的FDT,请修改arch/arm/boot/dts/Makefile,并在相应的Kconfig中增加config选项,例如,TI的Beagle
bone black,Kconfig的位置在arch/arm/mach-omap2/Kconfig
FDT的dtb文件由u-boot传递给内核,u-boot必须把这个文件拷贝到内核解压地址之后的某个位置,确保内核解压的时候不会覆盖,然后使用“bootm
[内核地址] - [dtb地址]”来启动内核
如果dtb文件不正确,对于3.10以上的内核,可能什么显示都没有,3.8内核,可能就显示到Uncompressing kernel......done
FDT的编写规则说明在Documentation/devicetree/bindings,不同的设备有相应的txt文件说明,其中的“compatible”可以作为关键字搜索驱动程序的源文件,例如,AM335x的GPIO,用“ti,omap4-gpio”为关键字,可以找到其代码位于drivers/gpio/gpio-omap.c
FDT可以包含子文件,比如am335x_boneblack.dts就包含了am33xx.dtsi,am335x-bone-common.dtsi
以一个例子来说明编写规则,我的板子上,I2C0上挂了一个音频CODEC,其地址是0x18,型号是TLV320AIC3104IRHBT。
先找到i2c0节点的位置,这在arch/arm/boot/dts/am33xx.dtsi中:
i2c0: i2c@44e0b000
{
compatible =
"ti,omap4-i2c"
#address-cells =
<1>
#size-cells =
<0>
ti,hwmods =
"i2c1"
reg = <0x44e0b000
0x1000>
interrupts =
<70>
status =
"disabled"
}
要芦绝在这个节点上挂东激哗洞西,可以直接在am33xx.dtsi中挂,可以写成这样:
i2c0: i2c@44e0b000
{
compatible =
"ti,omap4-i2c"
#address-cells =
<1>
#size-cells =
<0>
ti,hwmods =
"i2c1"
reg = <0x44e0b000
0x1000>
interrupts =
<70>
status =
"okay"
tlv320aic3x: tlv320aic3x@18 {
compatible = "ti,tlv320aic3x"
reg = <0x18>
status = "okay"
AVDD-supply = <&ldo4_reg>
IOVDD-supply = <&ldo4_reg>
DRVDD-supply = <&ldo4_reg>
DVDD-supply = <&ldo4_reg>
}
}
其中compatible字串“ti,tlv320aic3x”是在Documentation/devicetree/bindings里面全文搜索“tlv320aic”获得的,“tlv320aic3x:
tlv320aic3x@18”遵循的是“标识符:名称@地址”的格式,前面的“i2c0:
i2c@44e0b000”也是这个格式。这里的标识符可以在包含这个文件的文件或这个文件的其他位置引用,因此,可以使用arch/arm/boot/dts/am335x-boneblack.dts包含arch/arm/boot/dts/am33xx.dtsi,然后在am335x-boneblack.dts里写:
&i2c0 {
status = "okay"
tlv320aic3x: tlv320aic3x@18 {
compatible = "ti,tlv320aic3x"
reg = <0x18>
status = "okay"
AVDD-supply = <&ldo4_reg>
IOVDD-supply = <&ldo4_reg>
DRVDD-supply = <&ldo4_reg>
DVDD-supply = <&ldo4_reg>
}
}
&i2c0表示引用了i2c0这个标识符,然后把括号里的内容挂载到标识符下,如果属性的名字相同,例如status出现两次,前面是“disabled”后面是“okay”,以后面的为准,引用标识符的次数不受限制。
也许一开始会觉得FDT的工作过程很神秘,但你只要用compatible的字串去全文搜索一下C文件,然后仔细阅读一下,就会发现很简单,没过几分钟你就可以自定义FDT节点的属性了。反倒是这些 *** 作过程我没找到什么文档说,比较头痛,所以我把这些写出来,希望能给大家帮助。
下面说说initrd,initrd的用处是给内核一个初始的基本文件系统,用来加载内核模块之类的东西。很多人觉得嵌入式系统不需要initrd,也可以把initrd作为最终的根文件系统。我用initrd是用来校验真正的根文件系统,因为在嵌入式设备上,无法预测用户到底什么时候关机,可能会造成文件系统问题。
initrd可以用buildroot,像制作正常文件系统一样做,最后把根下的linuxrc换成一个例如下面这样的文件:
#!/bin/sh
/bin/echo Now Check SD Card
/sbin/fsck.ext4 /dev/mmcblk0p5
虽然Documentation/initrd.txt里面说,内核会执行initrd里面的/sbin/init,但在我用的linux-3.8.13上,init/do_mounts_initrd.c里面,执行的是/linuxrc,不知道是不是文档没有更新过来。具体的调用顺序是,kernel_init(init/main.c)
>kernel_init_freeable(init/main.c)
>prepare_namespace(init/do_mounts.c)
>initrd_load(init/do_mounts_initrd.c) >handle_initrd
(init/do_mounts_initrd.c)。
在使用initrd的时候有几点需要注意的:
不建议在initrd上挂载别的东西,会引起未知的问题,貌似看到个文章说这个,找不到了
因为上面的这条,而且在initrd的时候,内核还没有挂载devtmpfs,因此建议使用静态设备节点,以AM335x为例(内核参数console=/dev/ttyO0,115200n8),必须的节点有:
/dev/null
/dev/console
/dev/ttyO0
这些节点可以用fakeroot之后mknod在buildroot的output/target/dev里创建,除了/dev/console,buildroot会自己创建,其他也可以写到buildroot的system/device_table.txt里面让buildroot自动创建:
#
/dev/null
c 6660 0
1 3
-
-
-
/dev/ttyO0c 600
0 0 250
0
-
-
-
如果你用的是Atmel的处理器,上面的ttyO0可能是ttyS0,如果是三星的,可能是ttySAC0,而且major和minor也会不一样,请自行解决。如果你像我一样要检验SD卡,那就还必须加上SD卡的分区对应的节点。
/linuxrc可以是个程序也可以是个脚本,脚本的话,命令写绝对路径,而且记得把/linuxrc的mode改为755
使用initrd只需要用u-boot把buildroot制作的文件系统映像拷贝到内存里,然后传递initrd=[地址],[容量]这样的参数给内核,例如initrd=0x81300000,8M,最终的root参数可以不变,例如root=/dev/mmcblk0p5,这表示最终的root是SD卡上扩展分区中的第一个逻辑分区。给两个内核参数的例子:
console=ttyO0,115200n8 root=/dev/mmcblk0p5 initrd=0x81300000,8M vram=16M
consoleblank=0
console=ttyO0,115200n8 initrd=0x81300000,8M root=/dev/nfs rw
nfsroot=192.168.5.226:/home/cdu/nfsroot
ip=192.168.5.222:192.168.5.226:192.168.5.1:255.255.255.0:core335x:eth0:off
vram=16M consoleblank=0
第一个不解释了,第二个表示使用initrd,同时使用nfsroot。
最后啰嗦一句,使用initrd需要在内核配置里打开支持,这个网上的资料太多了,我就不说在哪里了。
用FORMAT命令对磁盘(或逻辑盘)进行格式化的时候,就已经为整个硬盘建立了一个根目录FDT。在根目录下,用户可以用DOS命令"MD"再创建不同的各个子目录,以及子目录下的子目录。根目录以及各级子目录都有自己的FDT。
在具体 *** 作中,系统规定用字母C-Z代表逻辑盘符,所以DOS简单地用“[盘符:]\”表示在根目录下。根目录的作用是分配根目录下的所有文件和子目录的存储空间(逻辑扇区号),并且通过设备驱动程凯祥滑序接口确定有效的最大目录项。
1.根目录中的FDT
根目录的作用是分配根目录下的所有文件和子目录的存储空间(逻辑扇区号),并通过设备驱动程序接口确定有效的最大目录项。
根目录下的所有文件及其子目录在根目录的文件目录表(FDT)中都有一个“目录登记项”或简称为“目录项”。每个目录登记项占用32个字节,分为8个区域,提供有关文件或子目录的信息。其中包括了DOS的系统文件(IO.SYS、MSDOS.SYS、和COMMAND.COM)的目录项。
常用软盘的根目录(FDT)所在逻辑扇区如下:
360KB:5--11扇区,共7个扇区
1.2MB:15--28扇区,共14个扇区
1.44MB:19--32扇区,共14个扇区
在硬盘中,各逻辑盘的根FDT的起始逻辑扇区由分区容量确定。在FAT16中,其大小总是32(20H)个扇区。FAT32中的根FDT大小与其逻辑盘容量有关。
下面是用DEBUG读出1.44MB软盘逻辑13H扇区开始的14个扇区内容的例子。
C>DEBUG
-L 00 0 13 E
-D 00
0DE5:0000 49 4F 20 20 20 20 20 20-53 59 53 27 00 00 00 00 IO SYS'....
0DE5:0010 00 00 00 00 00 00 C0 32-BF 1C 1D 00 46 9F 00 00 ......2...F.....
0DE5:0020 4D 53 44 4F 53 20 20 20-53 59 53 27 00 00 00 00 MSDOS SYS'....
0DE5:0030 00 00 00 00 00 00 C0 32-BF 1C 6D 00 FA 94 00 00 .......2 ..m...
0DE5:0040 43 4F 4D 4D 41 4E 44 20-43 4F 4D 20 00 00 00 00 COMMAND COM..
0DE5:0050 00 00 00 00 00 00 C0 32-BF 1C B8 00 75 D5 00 00 .......2 ..u...
2.FDT中的目录项
根目录下的所有文件及其子目录在根目录的文件目录表(FDT)中都有一个“目录登记项”或简称为“目录项”。
由于每个文件的目录羌窍钫加?2个字节,用作目录的一个扇区(512字节)最多只能装入512/32=16个文件。因盯腊此,在常用磁盘的根目录下最多可建文件或子目录数如下:
360 KB: 共7个扇区, 7*16=112个文件或子目录。
1.2 MB: 共14个扇区,14*16=224个文件或子目录。
1.44MB: 共14个扇区,14*16=224个文件或子目录。
硬盘逻辑盘:共32个扇区,16*32=512个文件或子目录。
在FDT中,每个目录登记项占用32个字节,分为8个宴让区域,提供有关文件或子目录的信息,包括DOS的系统文件IO.SYS、MSDOS.SYS的目录项。
在FAT16文件系统中,一个文件目录登记项32个字节中个字节的内容及含义如表6-6所示。
表6-6 FAT16文件目录项内容及含义表
字节位置 内 容 及 含 义 第0--7字节 表示文件名 第8--10字节 表示文件的扩展名 第11字节
表
示
文
件
属
性
00H(读写) 01H(只读) 02H(隐藏) 04H(系统) 08H(卷标) 10H(子目录) 20H(归档——只要完成了写 *** 作并已关闭,则该位置1) 第12--21字节 保留未用 第22--23字节 表示文件的创建时间 第24--25字节 表示文件的创建日期 第26--27字节 表示文件的起始簇号(首簇号) 第28--31字节 表示文件的字节数
FAT16文件系统对每个文件来说其数据结构是一个单项簇链表,而文件在文件目录表FDT中占一个文件目录项,每个文件的首簇号就存放在该文件的目录项中,一个文件目录项占32个字节。对FDT中一个文件目录项的几个参数值作如下说明:
(1)文件名
FAT16文件系统中,FDT的文件目录项中第0-7字节为文件名(若有剩余字节则用空白符20H填充)。其中,第1字节又表明了该文件的状态,它有如下3种取值方式:
·00H目录项的空表目。
·E5表示该目录项曾经使用过,但文件已被删除。
·2E表示该项为子目录项。
其它任何字符表示一个文件名(或子目录名)的第一个字符的ASCII码值。
(2)文件属性
第11字节为文件属性字节,按位规定如下:
b7 b6 b5 b4 b3 b2 b1 b0
未用
未用
归档
子目录
卷标
系统
隐藏
只读
(3)文件创建(修改)时间
·(第22字节0--4位)以2秒为增量的二进制树
·(23字节0--2位)+(22字节5--7位)为分钟
·(第23字节3--7位)为小时
(4)文件创建(修改)日期
·(第24字节0--4位)为日期1--31
·(25字节0位)+(24字节5--7位)为月份1--12
·(第25字节1--7位)为年号0--119(1980--2099)
(5)文件首簇号
第26、27 字节存放该文件的首簇号。系统根据FAT中该文件的单链表即可找到它的全部内容。
要注意区分文件目录表(FDT)和FDT中的目录登记项这两个概念。
目录登记项是一个32字节长的数据块,它记录了一个文件或子目录的有关信息。FDT是由若干目录登记项组成的一个表。根目录区是盘卷上的一个固定区域,根目录及各子目录都有各自的FDT。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)