Chinaunix首页 | 论坛 | 博客
  • 博客访问: 10625
  • 博文数量: 6
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 30
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-24 21:13
文章分类

全部博文(6)

文章存档

2017年(4)

2014年(2)

我的朋友

分类: LINUX

2017-01-14 11:31:06

am335x中固化的rom code支持从mmc/sd card启动,bbb black上使用的就是这种启动模式。
硬件连接:
am335x含有两个mmc高速接口mmc0和mmc1。这两个mmc接口对外部的容量有不同限制。
1、mmc0支持从mmc/sd card cage启动,同时也支持从容量不超过4GB的eMMC/eSD/managed NAND memory启动;
2、mmc1支持从大于4GB的eMMC/eSD/managed NAND memory启动。
启动模式:
1、raw模式
在这种模式下,rom code直接从mmc/sd card的user area读取数据。根据BBB_SRM.PDF文档。raw模式下,booting file只能存储在下列位置0x0 / 0x20000 (128 KB) / 0x40000 (256 KB) / 0x60000 (384 KB)。由此可见,booting file的大小不能超过128KB。这些地址对应的sector分别为#0, #256, #512, #768.(每个sector的大小为512B)。
在raw模式下,booting file必须包含一个TOC header和GP header。
这两个结构体的详细内容可以参考trm的26.1.7.5.5 MMC/SD Read Sector Procedure in Raw Mode小节。
2、fat模式
这是介绍的重点。
支持fat12/fat16/fat32文件系统,在bb black上使用的fat32文件系统。
bb black上的emmc挂在mmc1下,分为两个区:boot和rootfs。boot为fat32文件系统,rootfs为ext4文件系统。
boot分区通过mkfs.vfat -F 32 -n "boot" ${DRIVE}p1格式化;
rootfs分区通过mkfs.ext4 -L "rootfs" ${DRIVE}p2格式化。详细的流程可以参考debrick.sh脚本。
在uboot下也可以使用mmc part或者part list mmc 1命令查看详细的分区。
U-Boot# mmc dev 1 //切换mmc1下的emmc为当前有效的 device
switch to partitions #0, OK
mmc1(part 0) is current device
U-Boot# mmc part //查看mmc上的分区信息
Partition Map for MMC device 1 -- Partition Type: DOS
Part Start Sector Num Sectors UUID Type
1 63 144522 00000000-01 0c Boot
2 160650 7309575 00000000-02 83
根据上面的信息可以看出分区1的文件类型为0xc,即fat32文件系统。起始sector为63,有144522个sector。
rom code在fat模式下的处理流程如下图:
a)判断一个sector是否为MBR的第一个sector
b)判断一个sector是否为FAT12/16/32的第一个sector
c)找到booting file(即MLO)的第一个cluster
d)如何缓存booting file相关的FAT entry
由于rom code是固化在CPU内部的,余下部分的代码是参考的uboot,但原理和处理的流程大致相似。
对于FAT32系统,MBR包含4个partition entry,rom code只会在primary partition分区中查找booting file,不会在extended partition分区中查找。此外,rom code只支持8.3格式的文件名,不支持LFN(long file name).
MBR结构体的主要内容如下表:
根据trm文档,MBR的检测流程如下;
从读出的数据可以看出偏移地址为0X1FE的数据为0xaa55,等于Table 26-22中Signature的值。包含两个Partition Entry。
在uboot下,读取emmc上第一个 sector中的内容:
U-Boot# mmc dev 1
switch to partitions #0, OK
mmc1(part 0) is current device
U-Boot# mmc read 0x84000000 0 1
MMC read: dev # 1, block # 0, count 1 ... 1 blocks read: OK
U-Boot# md.b 0x84000000 0x200
84000000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000040: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000050: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000060: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000070: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000080: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000090: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840000a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840000b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840000c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840000d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840001a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 80 01 ................
840001c0: 01 00 0c fe 3f 08 3f 00 00 00 8a 34 02 00 00 00 ....?.?....4....
840001d0: 01 0a 83 fe 7f d0 8a 73 02 00 07 89 6f 00 00 00 .......s....o...
840001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa ..............U.
根据MBR的数据,可以看到MBR中包含两个partiton entry.其数值分别为:
80 01 01 00 0c fe 3f 08 3f 00 00 00 8a 34 02 00
00 00 01 0a 83 fe 7f d0 8a 73 02 00 07 89 6f 00
在找到MBR后,再获取分区信息,查看是否有active的分区,流程如下;
Partition Entry的格式如下:
Partition Type的格式如下:
partition entry 80 01 01 00 0c fe 3f 08 3f 00 00 00 8a 34 02 00对应的详细信息如下
Partition State 0x80--active
Partition Start Head 0x01
Partition Start Cylinder and Sector 0x00, 0x01
Partition Type 0x0c--FAT32
Partition End Head 0xfe
Partition End Cylinder and Sector 0x3f
LBAs 0x0000003f
Number of sectors in partition 0x0002348a
从上面的信息可以得出,有一个active的分区,type为0xc,起始sector为0x3f,即为fat32的boot sector。
partition entry 00 00 01 0a 83 fe 7f d0 8a 73 02 00 07 89 6f 00 对应的详细信息如下:
Partition State 0x00--inactive
Partition Start Head 0x00
Partition Start Cylinder and Sector 0x0a, 0x01
Partition Type 0x83--Linux
Partition End Head 0xfe
Partition End Cylinder and Sector 0x7f
LBAs 0x0002738a
Number of sectors in partition 0x006f8907
从上述信息可以看出,emmc上包含两个分区,第一个为FAT32文件系统,第二个为Linux文件系统。
FAT32文件系统的第一个sector是0x3f.
uboot中对应的结构体为:
typedef struct dos_partition {
unsigned char boot_ind; /* 0x80 - active */
unsigned char head; /* starting head */
unsigned char sector; /* starting sector */
unsigned char cyl; /* starting cylinder */
unsigned char sys_ind; /* What partition type */
unsigned char end_head; /* end head */
unsigned char end_sector; /* end sector */
unsigned char end_cyl; /* end cylinder */
unsigned char start4[4]; /* starting sector counting from 0 */
unsigned char size4[4]; /* nr of sectors in partition */
} dos_partition_t;
在找到了FAT32文件系统后,就要对FAT32文件系统进行分析,根据partition entry分析得到的信息,LBA是0x3f,对于FAT32文件系统,第一个sector是boot sector。
Boot Sector的格式如下:


对于Boot Sector,fat12/16和fat32的格式有较大的差异。
对应的结构体为:
typedef struct boot_sector {
__u8 ignored[3]; /* Bootstrap code */
char system_id[8]; /* Name of fs */
__u8 sector_size[2]; /* Bytes/sector */
__u8 cluster_size; /* Sectors/cluster */
__u16 reserved; /* Number of reserved sectors */
__u8 fats; /* Number of FATs */
__u8 dir_entries[2]; /* Number of root directory entries */
__u8 sectors[2]; /* Number of sectors */
__u8 media; /* Media code */
__u16 fat_length; /* Sectors/FAT */
__u16 secs_track; /* Sectors/track */
__u16 heads; /* Number of heads */
__u32 hidden; /* Number of hidden sectors */
__u32 total_sect; /* Number of sectors (if sectors == 0) */

/* FAT32 only */
__u32 fat32_length; /* Sectors/FAT */
__u16 flags; /* Bit 8: fat mirroring, low 4: active fat */
__u8 version[2]; /* Filesystem version */
__u32 root_cluster; /* First cluster in root directory */
__u16 info_sector; /* Filesystem info sector */
__u16 backup_boot; /* Backup boot sector */
__u16 reserved2[6]; /* Unused */
} boot_sector;
流程如下:
U-Boot# mmc read 0x84000000 0x3f 1
MMC read: dev # 1, block # 63, count 1 ... 1 blocks read: OK
U-Boot# md.b 0x84000000 0x200
84000000: eb 58 90 6d 6b 64 6f 73 66 73 00 00 02 01 20 00 .X.mkdosfs.... .
84000010: 02 00 00 00 00 f8 00 00 10 00 04 00 00 00 00 00 ................
84000020: 8a 34 02 00 58 04 00 00 00 00 00 00 02 00 00 00 .4..X...........
84000030: 01 00 06 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000040: 80 01 29 1d 7d 6e 58 62 6f 6f 74 20 20 20 20 20 ..).}nXboot
84000050: 20 20 46 41 54 33 32 20 20 20 0e 1f be 77 7c ac FAT32 ...w|.
84000060: 22 c0 74 0b 56 b4 0e bb 07 00 cd 10 5e eb f0 32 ".t.V.......^..2
84000070: e4 cd 16 cd 19 eb fe 54 68 69 73 20 69 73 20 6e .......This is n
84000080: 6f 74 20 61 20 62 6f 6f 74 61 62 6c 65 20 64 69 ot a bootable di
84000090: 73 6b 2e 20 20 50 6c 65 61 73 65 20 69 6e 73 65 sk. Please inse
840000a0: 72 74 20 61 20 62 6f 6f 74 61 62 6c 65 20 66 6c rt a bootable fl
840000b0: 6f 70 70 79 20 61 6e 64 0d 0a 70 72 65 73 73 20 oppy and..press
840000c0: 61 6e 79 20 6b 65 79 20 74 6f 20 74 72 79 20 61 any key to try a
840000d0: 67 61 69 6e 20 2e 2e 2e 20 0d 0a 00 00 00 00 00 gain ... .......
840000e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840000f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000160: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000170: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
84000190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840001a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840001b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840001c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840001d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840001e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
840001f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa ..............U.
根据struct boot_sector结构体解析的信息如下;
ignored: eb-58-90
system_id: mkdosfs
sector_size: 00-02
cluster_size: 01
reserved: 20
fats: 02
dir_entries: 00-00
sectors: 00-00
media: f8
fat_length: 00
secs_track: 10
heads: 04
hidden: 00
total_sect: 2348a
fat32_length: 458
flags: 00
version: 00-00
root_cluster: 02
info_sector: 01
backup_boot: 06
在找到fat文件系统后,接下来就是在根目录下查找booting file(MLO),对于fat12/16文件系统,root directory位于固定的地址。而对于fat32文件系统,是变化的。根目录的第一个扇区存储在BPB_RootClus.根目录和其他目录的不同之处在于没有日期和时间戳,也没有目录名,同时根目录下面也没有.和..两个目录项。另一个不同之处在于根目录中有一个设置了ATTR_VOLUME_ID位的文件,这个文件在整个fat卷中是唯一的。
fat文件系统的目录项格式如下:
directory entry对应的代码为:
typedef struct dir_entry {
char name[8],ext[3]; /* Name and extension */
__u8 attr; /* Attribute bits */
__u8 lcase; /* Case for base and extension */
__u8 ctime_ms; /* Creation time, milliseconds */
__u16 ctime; /* Creation time */
__u16 cdate; /* Creation date */
__u16 adate; /* Last access date */
__u16 starthi; /* High 16 bits of cluster in FAT32 */
__u16 time,date,start;/* Time, date and first cluster */
__u32 size; /* File size in bytes */
} dir_entry;
rom code会把FAT表读到缓冲区中,但对于FAT32文件系统,每个entry的大小为4字节。其格式如下
附录:
附录1:硬盘结构简介:
到目前为止, 人们常说的硬盘参数还是古老的 CHS (Cylinder/Head/Sector)参数. 那么为什么要使用这些参数, 它们的意义是什么?它们的取值范围是什么?很久以前, 硬盘的容量还非常小的时候, 人们采用与软盘类似的结构生产硬盘.
也就是硬盘盘片的每一条磁道都具有相同的扇区数. 由此产生了所谓的3D参数 (Disk Geometry). 既磁头数(Heads), 柱面数(Cylinders), 扇区数(Sectors per track),以及相应的寻址方式.
其中:磁头数(Heads) 表示硬盘总共有几个磁头,也就是有几面盘片, 最大为 256 (用 8 个二进制位存储);柱面数(Cylinders) 表示硬盘每一面盘片上有几条磁道, 最大为 1024(用 10 个二进制位存储);扇区数(Sectors per track) 表示每一条磁道上有几个扇区, 最大为63 (用 6 个二进制位存储,这里为什么是63而不是64,原因请看后面分析).每个扇区一般是 512个字节, 理论上讲这不是必须的, 但好象没有取别的值的.
所以磁盘最大容量为:256 * 1024 * 63 * 512 / 1048576 = 8064 GB ( 1M = 1048576 Bytes )
或硬盘厂商常用的单位:256 * 1024 * 63 * 512 / 1000000 = 8455 GB ( 1M = 1000000 Bytes )
在 CHS 寻址方式中, 磁头, 柱面, 扇区的取值范围分别为 0 到 Heads-1, 0 到 Cylinders-1, 1 到 Sectors per track (注意是从 1 开始,这里回答了上一段中提出的扇区数为什么是63而不是64).在 CHS 寻址方式中, 有以下几种尺寸单位:扇区 (Sector)= 512 字节 (一般情况下)磁道 (Track) = (Sectors per track) 扇区柱面 (Cylinder)= (Sectors per track) * Heads 扇区.
在老式硬盘结构中, 由于每个磁道的扇区数相等, 所以外道的记录密度要远低于内道, 因此会浪费很多磁盘空间 (与软盘一样). 为了解决这一问题, 进一步提高硬盘容量, 人们改用等密度结构生产硬盘结构. 也就是说, 外圈磁道的扇区比内圈磁道多. 采用这种结构后, 硬盘结构不再具有实际的3D参数, 寻址方式也改为线性寻址, 即以扇区为单位进行寻址.
为了与使用3D寻址的老软件兼容 (如使用BIOS Int13H接口的软件), 在硬盘控制器内部安装了一个地址翻译器, 由它负责将老式3D参数翻译成新的线性参数. 这也是为什么现在硬盘的3D参数可以有多种选择的原因 (不同的工作模式, 对应不同的3D参数, 如 LBA, LARGE, NORMAL).关于这些寻址模式的详细介绍请参考其他文档,内容较多,本文就不引述了。

附录2:硬盘分区表简介;
计算机对硬盘的读写,处于效率的考虑,是以扇区为基本单位的。即使计算机只需要硬盘上存储的某个字节,也必须一次把这个字节所在的扇区中的512字节全部 读入内存,再使用所需的那个字节。不过,在上文中我们也提到,硬盘上面、磁道、扇区的划分表面上是看不到任何痕迹的,虽然磁头可以根据某个磁道的应有半径 来对准这个磁道,但怎样才能在首尾相连的一圈扇区中找出所需要的某一扇区呢?原来,每个扇区并不仅仅由512个字节组成的,在这些由计算机存取的数据的 前、后两端,都另有一些特定的数据,这些数据构成了扇区的界限标志,标志中含有扇区的编号和其他信息。计算机就凭借着这些标志来识别扇区。硬盘的数据结构 在上文中,我们谈了数据在硬盘中的存储的一般原理。为了能更深入地了解硬盘,我们还必须对硬盘的数据结构有个简单的了解。硬盘上的数据按照其不同的特点和 作用大致可分为5部分:MBR区、DBR区、FAT区、DIR区和DATA区。
1、MBR区
MBR(Main Boot Record 主引导记录区)位于整个硬盘的0磁道0柱面1扇区。不过,在总共512字节的主引导扇区中,MBR只占用了其中的446个字节,另外的64个字节交给了 DPT(Disk Partition Table硬盘分区表),最后两个字节“55,AA”是分区的结束标志。这个整体构成了硬盘的主引导扇区。
主引导记录中包含了硬盘的一系列参数和一段引导程序。其中的硬盘引导程序的主要作用是检查分区表是否正确并且在系统硬件完成自检以后引导具有激活标志的分 区上的操作系统,并将控制权交给启动程序。MBR是由分区程序(如Fdisk.exe)所产生的,它不依赖任何操作系统,而且硬盘引导程序也是可以改变的,从而实现多系统共存。
下面,我们以一个实例让大家更直观地来了解主引导记录:
例:80 01 01 00 0B FE BF FC 3F 00 00 00 7E 86 BB 00 在这里我们可以看到,最前面的“80”是一个分区的激活标志,表示系统可引导;“01 01 00”表示分区开始的磁头号为01,开始的扇区号为01,开始的柱面号为00;“0B”表示分区的系统类型是FAT32,其他比较常用的有 04(FAT16)、07(NTFS);“FE BF FC”表示分区结束的磁头号为254,分区结束的扇区号为63、分区结束的柱面号为764;“3F 00 00 00”表示首扇区的相对扇区号为63;“7E 86 BB 00”表示总扇区数为12289622。
2、DBR区
DBR(Dos Boot Record)是操作系统引导记录区的意思。它通常位于硬盘的0磁道1柱面1扇区,是操作系统可以直接访问的第一个扇区,它包括一个引导程序和一个被称为 BPB(Bios Parameter Block)的本分区参数记录表。引导程序的主要任务是当MBR将系统控制权交给它时,判断本分区跟目录前两个文件是不是操作系统的引导文件(以DOS为 例,即是Io.sys和Msdos.sys)。如果确定存在,就把它读入内存,并把控制权交给该文件。BPB参数块记录着本分区的起始扇区、结束扇区、文件存储格式、硬盘介质描述符、根目录大小、FAT个数,分配单元的大小等重要参数。DBR 是由高级格式化程序(即Format.com等程序)所产生的。
3、FAT区
在DBR之后的是我们比较熟悉的FAT(File Allocation Table文件分配表)区。在解释文件分配表的概念之前,我们先来谈谈簇(Cluster)的概念。文件占用磁盘空间时,基本单位不是字节而是簇。一般情况下,软盘每簇是1个扇区,硬盘每簇的扇区数与硬盘的总容量大小有关,可能是4、8、16、32、64…… 同一个文件的数据并不一定完整地存放在磁盘的一个连续的区域内,而往往会分成若干段,像一条链子一样存放。这种存储方式称为文件的链式存储。由于硬盘上保存着段与段之间的连接信息(即FAT),操作系统在读取文件时,总是能够准确地找到各段的位置并正确读出。 为了实现文件的链式存储,硬盘上必须准确地记录哪些簇已经被文件占用,还必须为每个已经占用的簇指明存储后继内容的下一个簇的簇号。对一个文件的最后一簇,则要指明本簇无后继簇。这些都是由FAT表来保存的,表中有很多表项,每项记录一个簇的信息。由于FAT对于文件管理的重要性,所以FAT有一个备份,即在原FAT的后面再建一个同样的FAT。初形成的FAT中所有项都标明为“未占用”,但如果磁盘有局部损坏,那么格式化程序会检测出损坏的簇,在相应的项中标为“坏簇”,以后存文件时就不会再使用这个簇了。FAT的项数与硬盘上的总簇数相当,每一项占用的字节数也要与总簇数相适应,因为其中需要存放 簇号。FAT的格式有多种,最为常见的是FAT16和FAT32。
 4、DIR区
DIR(Directory)是根目录区,紧接着第二FAT表(即备份的FAT表)之后,记录着根目录下 每个文件(目录)的起始单元,文件的属性等。定位文件位置时,操作系统根据DIR中的起始单元,结合FAT表就可以知道文件在硬盘中的具体位置和大小了。
 5、数据(DATA)区
数据区是真正意义上的数据存储的地方,位于DIR区之后,占据硬盘上的大部分数据空间。
阅读(2365) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~