eMMC ext4综述【转】

本文转载自:https://blog.csdn.net/lieye_leaves/article/details/78214410

eMMC ext4综述
一.系统的引导启动
1.1系统的引导启动
https://javigon.com/2012/08/24/from-poweron-to-android-the-boot-sequence/

 

通常,引导设备的块0包含着主引导记录(MasterBoot Record MRB),这个块包含着设备分区表(partition table)的信息。

当设备加电启动的时候,第一个阶段的bootloader放在特定的块上,该阶段执行后会找到下个阶段的bootloader,该过程可以理解为使用了低层的地址块的,即这些地址块用的是硬编码,找到它的时候是采用直接的物理块的,而不是分区,即bootloader和内核的定位是在分区表(partition table)之外的。

使用dd, fdisk, fastboot可以生成MRB和partitiontable,烧写内核和ramdisk。Fdisk和fastboot比dd要更友好和快速。ODROID-A4的分区表如下:




当系统启动的时候,处理器会从一个指定的地方读取并执行代码,这个地址通常是内部ROM,它初始化板上的部件,并引导设备,有的平台是一小段称之为BL0的代码,不同的处理器和开发板有不同。

如果bootloader的第一步执行的时候,比如BL1,它会被复制到内部的RAM中,初始化时钟,SDRAM,加载剩余的bootloader(BL2),不同的平台都类似,如下图所示:




在bootloader(BL0 BL1 BL2)初始化板上的设备后,将kernel加载进RAM中。

1.2 引导方式实例1
Uboot启动以后的一种引导方式,仅做参考(作者,围补):

setenv loadaddr 0x10800000

setenv bootargs_base 'setenvbootargsconsole=ttymxc0,115200'

setenv bootargs_mmc 'setenvbootargs${bootargs} root=/dev/mmcblk0p1 rootwait rwvideo=mxcfb1:dev=ldb,LDB-XGA,if=RGB666video=mxcfb0:dev=hdmi,1920x1080M@60,if=RGB24ip=dhcp'

setenv bootcmd_mmc 'run bootargs_base bootargs_mmc;mmcdev 1;mmc read ${loadaddr} 0x800 0x2000;bootm'

setenv bootcmd 'run bootcmd_mmc'

saveenv

run bootcmd

rw是声明启动权限,即以读写方式启动;rootwait是指等待设备/dev/mmcblk0p1设备就绪后才尝试挂载rootfs。如果没有此参数,linux内核启动时可能会在存储设备尚未就绪是就尝试挂载rootfs,此时肯定挂载失败,那么启动也就失败了。

mmc dev 1,意思是将dev 1设置为当前设备

mmc read0x10800000 0x800 0x2000即将存储设备上从块号0x800开始的0x2000个存储块的东西拷贝到内存0x10800000开始的空间内。

1.3引导方式实例2
http://blog.csdn.net/u014645605/article/details/52061034

sprd:

Boot1:u-boot-spl-16k.bin

Boot2:u-boot.bin

RPMB:未使用(指纹相关)

UDA:剩余的烧写文件

高通:

BOOT1:bootloader

BOOT2:boot.img

RPMB:未用(指纹相关)

UDA:剩余文件



1.4引导实例3
下图为exynos4412的启动流程:



二EMMC分区
http://blog.sina.com.cn/s/blog_5c401a150101jcos.html

大家所最为熟知的分区方式同时也是最主流的主要有两种:MBR(Master Boot Record)和GPT(GUID PartitionTable)。前者应用于绝大多数使用BIOS引导的PC设备(苹果使用EFI的方式),而后者主要是针对MBR的一些缺点进行了改进同时还可以兼容MBR并且支持2TB以上的存储(MBR不支持2TB以上的存储设备)。      

Android 2.x.x 版本上使用的是MBR,4.0版本以后就是使用的GPT分区方式。注意,不管是MBR还是GPT,他们的分区都是指“逻辑上”的!!!即通过软件实现的,文件系统级别的。而我现在要说明的是eMMC本身自己的分区,即物理上的,不是通过软件就能实现的分区。

EMMC的分区有一些是AP不能修改的(如BOOT1、BOOT2和RPMB分区),有一些是可以通过特定的命令和寄存器就可以修改的(如Enhanced Partition和GPAP)。

1.BOOT Area Partition

2.BOOT Area Partition

3.RPMB

4.User Data Area

5.Vender private area



2.1Boot 1 & Boot 2   
这两个分区是由厂家在生产过程中配置好了的,并且其大小是不能由AP进行配置的,当然,如果你的公司够牛,量足够大,并且也有这个需求的时候可以去要求厂家重新配置此区域大小,给你专门供货。        

Boot 1 和Boot 2这两个区域在存储的稳定性、可靠性及擦除次数上都远比UDA要好(至于原因请往后看),所以很多chipset上都会使用这两个区域来存放一下关键数据,如boot image,default配置参数等等。当然不同的chipset的配置方法也不尽相同。这个可以找chipset的工程师询问。据笔者所知:以大陆市占最大的两家chipset为例,MTK使用UDA来存放boot data,而使用boot area来存放配置参数;Qualcomm则使用Boot 1来存放boot data,boot 2来存放配置参数。

另外,不同的eMMC版本一般对Boot area和RPMB的容量大小需求也不同,如下作一个简单的参考:



2.2RPMB  
RPMB是Replay Protected Memory Block的缩写,他的存在目的是用来给系统存放一些特殊的、需要进行访问授权的数据;他的请求及回应类型如下所:

据笔者所知,目前大陆的手机及平板厂商还没有一家使用到此区域的。

2.3UDA 
User Data Area就是AP及用户可以进行读写存储的区域,通常其大小为整块EMMC表示大小的93%左右,即4GB的eMMC UDA的区域只有4GB*93%=3809MB。

之前说的BOOT1&2、RPMB和UDA区域我们都可以认为他们在物理上是独立的(当然都是存在于同一块die上)。即他们各自的物理起始地址都是0x0。这个在出厂的时候就会设置完成。下面我们就来说两种可以在物理上进行独立分区的方式:



a) GPAP
GPAP即General Purpose Area Partitions,eMMC的spec上定义每个eMMC最多可以通过配置寄存器来定义4个GPAP:

GPAP配置定义完成之后每一个GPAP的起始地址都为0x0;即可以相应地将其认为是独立的一块区域。只是在存放数据的时候会需要从新根据他的起始地址进行计算然后再存储数据。这样必然会增加一定的工作量;据笔者所知,目前大陆的手机及平板几乎没有用到这个功能。都是使用一整块的UDA,然后通过文件系统去进行逻辑上的分区使用。

我想肯定会有读者想问那这个功能到底有什么用呢?我想说eMMC是一个通过的存储设备,并不止是为手机和平板使用。当一个设备有多个CPU的时候并且他们的功能还不同时,这个时候使用GPAP这个功能就非常方便了。

b) Enhanced Partition
Enhanced Partition这也是一个在手机及平板上使用较少的功能。为什么通过配置原本的UDA就可以变成“Enhanced”的呢?既然这么有用,为什么不将整个UDA配置成为”Enhanced”的呢?别着急,我来一一作答。

我们知道eMMC只是指他的接口标准,而他真正的存储介质还是NAND Flash,而NAND又分为SLC、MLC和TLC(详细区别请参考我之前的文章),他们的稳定性、可靠性和擦除次数又有很大区别,当然中国厂商最关心的成本也相差很大;目前市场上主流的eMMC还是以MLC的NAND存储介质为主,而TLC的eMMC也在逐渐的增加。其中以Samsung的TLC的emmc最为成熟市占率也最高。我们这里先以MLC的EMMC来进行介绍:

以现在市面上最先进的NAND制程20nm的MLC为例,擦除次数大概在3000~5000cycle。而SLC的擦除次数则在25000~40000cycle。很明显SLC要比MLC性能更好,数据存储更稳定。

而我们这里介绍的Enhanced Partition的主要功能就是将MLC配置成为SLC。现在大家明白他为什么被称之为“Enhanced”的了!是相对于MLC(也就是default storage media)来说的。

当然,从MLC配置为SLC不是没有代价的,这个代价自然就是容量变小,会变多小呢?容量只有原来的一半!!!原本1GB的MLC通过配置成SLC就只剩下512MB了,你说谁会愿意这样去大容量地转换呢?

据笔者所知,目前使用过这个功能的就只有台湾的HTC,他们是用来存储boot data。另外,大陆也有一家大厂正在尝试使用Enhanced Partition来做为swap虚拟内存使用。

2.4 Vender Private Area
在eMMC里面除了AP能操作(即可识别并且可以通过地址进行访问)的boot 1&2、RPMB和UDA之外,其实还有一小部分区域是AP看不见也不能进行操作的。这部分区域是由生产厂家预留的,他主要是用来存放这样一些内容: eMMC的FW(想知道是什么请参考我之前的文章),eMMC在boot的时候的code,FTL(Flash Transilation Layer)以及在厂家生产过程中产生的坏块等等。

PS: 不是所有厂家的eMMC都支持Enhanced Partition这个功能,但是只要这个eMMC是支持这个功能的那么他的BOOT Area和RPMB就必须就Enhanced storage media。

三.制作EXT4文件系统
http://blog.csdn.net/zuoyioo7/article/details/74529255

用户目录下新建目录rootfs_tmp文件,用于临时挂载文件系统:
mkdir -p rootfs_tmp
制作一个128M(128x1024=131072)的ext4空白文件:
dd if=/dev/zero of=rootfs.ext4 bs=1024 count=131072
再将新建的rootfs.ext4文件格式化为ext4格式:
sudo mkfs.ext4 rootfs.ext4
将rootfs.ext4文件挂载到前面我们新建的临时目录rootfs_tmp,注意这里我们要使用mount –o loop的属性,表示我们要把rootfs.ext4当作硬盘分区挂载到rootfs_tmp:
sudo mount -o loop rootfs.ext4 ./rootfs_tmp

给rootfs.ext4填充内容了。执行如下指令拷贝文件系统内容:

cd./rootfs_tmp

cp -avrf../busybox_rootfs/* ./
拷贝完后,卸载挂载的rootfs.ext4文件,即完成了文件系统的制作:

sudo umount./rootfs_tmp

这样就完成ext4格式的rooffs文件系统的制作。

 

四.在EMMC上分区,及烧写内核,根文件系统
4.1 通过uboot的烧写方法
http://blog.csdn.net/sinat_36184075/article/details/56049044

 

分区原则:每个分区的大小要大于等于要存储的镜像文件的大小。
EMMC:'nandflash+ 控制电路'
一种分区配置:(该种分区方法是否是UDA中的分区,因为上文提到的两个boot分区出厂后无法再分配的,下文烧写的时候用的是物理扇区地址,有点疑问)
0--------1M---------65M------------819M---------------8192M
扇区:0-------0x800-----0x20800--------0x199800---------0x1000000
|--uboot--|----linux----|-----rootfs-----|--------appfs---------|

/* 分区命令:*/
#:fdisk 2 3 0x100000:4000000 4100000:0x2f200000 33300000:0


 

烧写内核
#:tftp 48000000 uImage
#:mmc write 48000000 0x800 0x3000      //写入的地址是物理上的地址
0x48000000:源数据地址
0x800:要写入的位置(单位是扇区,十进制512)
0x3000:要写入的数据长度(单位是扇区,十进制512)

在上文中已经制作了EXT4根文件系统rootfs.ext4,下面就烧写到eMMC中去,
#:tftp 48000000 rootfs.ext4
#:mmc write 48000000 20800 0x32000
#:setenv bootargs root=/dev/mmcblk0p2 rootfstype=ext4 console=ttySAC0,115200
root:根文件系统所在设备文件的名称
rootfstype:根文件系统的类型
console:控制台,ttySAC0,uart0控制器


4.2fdisk分区EMMC操作

http://blog.chinaunix.net/uid-20698826-id-5767254.html

Emmc在/dev下的设备文件是mmcblk0,用fdisk对emmc进行分区;


4.2.1、对emmc进行分区
# fdisk /dev/mmcblk0
Device contains neither a valid DOS partition table, nor Sun, SGI, OSF or GPTdisklabel
Building a new DOS disklabel. Changes will remain in memory only,
until you decide to write them. After that the previous content
won't be recoverable.

The number of cylinders for this disk is set to 238592.
There is nothing wrong with that, but this is larger than 1024,
and could in certain setups cause problems with:
1) software that runs at boot time (e.g., old versions of LILO)
2) booting and partitioning software from other OSs
(e.g., DOS FDISK, OS/2 FDISK)

Command (m for help):

4.2.2、使用m命令,获取fdisk使用帮助
Command (m for help): m
Command Action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition
l list known partition types
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)

Command (m for help):

4.2.3、使用n命令,添加一个新的分区
Command (m for help): n
Command action
e extended
p primary partition (1-4)
选择p,添加主分区

4.2.4、选择分区号,选择1,
Partition number (1-4): 1 // 选择分区号
First cylinder (1-238592, default 1): Using default value 1 // 选择分区的第一个柱面,选择1
Last cylinder or +size or +sizeM or +sizeK (1-238592, default 238592): Usingdefault value 238592 // 选择最后一个柱面

可以使用同样的方式添加第二、第三等分区。

4.2.5、是用p命令,显示分区信息
Command (m for help): p

Disk /dev/mmcblk0: 7818 MB, 7818182656 bytes
4 heads, 16 sectors/track, 238592 cylinders
Units = cylinders of 64 * 512 = 32768 bytes

Device Boot Start End Blocks Id System
/dev/mmcblk0p1 1 238592 7634936 83 Linux

4.2.6、使用t命令,设置分区格式
Command (m for help): t
Selected partition 1
Hex code (type L to list codes): l

0 Empty 1b Hidden Win95 FAT32 9f BSD/OS
1 FAT12 1c Hidden W95 FAT32 (LBA) a0 Thinkpad hibernation
4 FAT16 <32M 1e Hidden W95 FAT16 (LBA) a5 FreeBSD
5 Extended 3c Part.Magic recovery a6 OpenBSD
6 FAT16 41 PPC PReP Boot a8 Darwin UFS
7 HPFS/NTFS 42 SFS a9 NetBSD
a OS/2 Boot Manager 63 GNU HURD or SysV ab Darwin boot
b Win95 FAT32 80 Old Minix b7 BSDI fs
c Win95 FAT32 (LBA) 81 Minix / old Linux b8 BSDI swap
e Win95 FAT16 (LBA) 82 Linux swap be Solaris boot
f Win95 Ext'd (LBA) 83 Linux eb BeOS fs
11 Hidden FAT12 84 OS/2 hidden C: drive ee EFI GPT
12 Compaq diagnostics 85 Linux extended ef EFI (FAT-12/16/32)
14 Hidden FAT16 <32M 86 NTFS volume set f0 Linux/PA-RISC boot
16 Hidden FAT16 87 NTFS volume set f2 DOS secondary
17 Hidden HPFS/NTFS 8e Linux LVM fd Linux raid autodetect
Hex code (type L to list codes): 83

4.2.7、使用w命令,保存配置
Command (m for help): w
The partition table has been altered.
Calling ioctl() to re-read partition table

4.2.8、使用对应文件系统工具对分析进行格式化
# mkfs.ext4 /dev/mmcblk0p1
mke2fs 1.41.11 (14-Mar-2010)
Filesystem label=
OS type: Linux
Block size=4096 (log=2)
Fragment size=4096 (log=2)
Stride=0 blocks, Stripe width=0 blocks
477664 inodes, 1908734 blocks
95436 blocks (5.00%) reserved for the super user
First data block=0
Maximum filesystem blocks=1954545664
59 block groups
32768 blocks per group, 32768 fragments per group
8096 inodes per group
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632

Writing inode tables: done
Creating journal (32768 blocks):
done
Writing superblocks and filesystem accounting information: done

This filesystem will be automatically checked every 24 mounts or
180 days, whichever comes first. Use tune2fs -c or -i to override.

posted @ 2018-12-18 14:58  请给我倒杯茶  阅读(1254)  评论(0编辑  收藏  举报