鋒影
email:[email protected]
如果你認爲本系列文章對你有所幫助,請大家有錢的捧個錢場,點擊此處贊助,贊助額0.1元起步,多少隨意
一.系統的引導啓動
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.