轉載請註明文章出處和作者!
出處:http://blog.csdn.net/xl19862005
作者:大熊(Xandy)
在上一篇中簡單的說明了一下要增加recovery功能所涉及到的代碼修改部分,代碼修改成功之後並不等於所需要的功能就OK了,編譯通過燒錄到目標板之後還有一大堆的問題需要處理!
經過一天的努力bootloader及recovery添加並編譯成功了,燒錄到樣機上後首先要驗證的是bootcmd切換是否正常,這裡加入了測試用的bootcmd切換開關,如下紅色標註:
#define CONFIG_EXTRA_ENV_SETTINGS \
"loadaddr=0x82000000\0" \
"nandboot=echo Booting from nand ...; " \
"nand read ${loadaddr} 280000 500000; bootm ${loadaddr}\0" \
"bootcmd=run nandboot\0" \
"bootargs=init=/init console=ttyO2,115200n8 ip=off " \
"androidboot.console=ttyO2 mem=512M rw ubi.mtd=6,2048 " \
"rootfstype=ubifs root=ubi0:rootfs rootdelay=2 " \
"omapdss.def_disp=lcd " \
"vram=8M omapfb.vram=0:8M mpurate=1000\0" \
"android_recovery_switch=1\0"
這裡要說明一下,修改編譯uboot之後燒錄到樣機上後這裡的修改後的bootcmd是不會起作用的,原因就是在於燒錄uboot的時候是燒錄至uboot對應的分區的,而bootcmd這些系統啟動參數則是儲存在uboot-env這個分區裡的,在上一篇的分區列表裡就可以看出來!
關於如何燒錄鏡像檔案至指定分區,這裡簡單提一下,可以用TI原廠提供的Flash v1.x燒錄工具,也可以用fastboot或者其它的辦法,我這裡用的是fastboot批處理的方式!
那麼怎樣讓新的bootcmd生效呢,我們可以用
nand erase
這個命令來擦除相應分區裡的內容,但要注意的是如果你直接輸入nand erase斷行符號,那麼你的整個nand空間將會被清除,包括xloader及uboot!那麼要如想擦除指定分區呢?
需要再提到一個在uboot裡對就的config裡有類似如下的預設(default)分區列表:
#define MTDPARTS_DEFAULT"mtdparts=nand:512k(xloader),"\
"1920k(uboot),"\
"128k(ubootenv),"\
"5m(kernel),"\
"1m(cache),"\
"100m(recovery),"\
"256m(system)"
只需要在uboot的命令列裡簡單的輸入一條命令:
mtdparts default
然後再運行nand erase xx,這裡的xx可以是mtdparts裡的分區代碼,如
nand erase ubootenv
這樣就可以擦除相應的分區空間了!
當系統啟動後正常載入核心,開始解析UBI各種參數,但很有可能出現如下錯誤:
[ 1.675323] omap2-nand driver initializing
[ 1.679931] NAND device: Manufacturer ID: 0xad, Chip ID: 0xbc (Hynix )
[ 1.686767] Creating 7 MTD partitions on "omap2-nand.0":
[ 1.692321] 0x000000000000-0x000000020000 : "X-Loader"
[ 1.698944] 0x000000080000-0x000000240000 : "U-Boot"
[ 1.705902] 0x000000260000-0x0000002a0000 : "U-Boot Env"
[ 1.712554] 0x000000280000-0x000000780000 : "Kernel"
[ 1.720794] 0x000000780000-0x000000880000 : "cache"
[ 1.727325] 0x000000880000-0x000006c80000 : "recovery"
[ 1.774688] 0x000006c80000-0x000020000000 : "File System"
[ 1.946777] OneNAND driver initializing
[ 1.951416] UBI: attaching mtd5 to ubi0
[ 1.955413] UBI: physical eraseblock size: 131072 bytes (128 KiB)
[ 1.961944] UBI: logical eraseblock size: 129024 bytes
[ 1.967590] UBI: smallest flash I/O unit: 2048
[ 1.972473] UBI: sub-page size: 512
[ 1.977294] UBI: VID header offset: 512 (aligned 512)
[ 1.983367] UBI: data offset: 2048
[ 1.988586] UBI error: validate_ec_hdr: bad VID header offset 2048, expected 512
[ 1.996276] UBI error: validate_ec_hdr: bad EC header
[ 2.001556] UBI error: ubi_io_read_ec_hdr: validation failed for PEB 0
[ 2.008392] UBI error: ubi_init: cannot attach mtd5
這是因為在製作UBI檔案鏡像的時候的參數不對,這裡提示的是VID header offset有問題,那麼就按這裡提示將VID header offset參數改成512
如下紅色字串:
ubinize -o ${OUT_IMAGE_PATH}/recovery.img -m 2048 -p 128KiB -s 512 -O 512 reubinize.cfg
關於這些參數的說明可以在ubuntu下輸入ubinize -h查看相應說明(前提是你已經下載並編譯安裝了mtd-ubifs)
重新製作檔案鏡像並燒錄到機子上啟動後出現如下資訊:
[ 1.688598] omap2-nand driver initializing
[ 1.693206] NAND device: Manufacturer ID: 0xad, Chip ID: 0xbc (Hynix )
[ 1.700042] Creating 7 MTD partitions on "omap2-nand.0":
[ 1.705566] 0x000000000000-0x000000020000 : "X-Loader"
[ 1.712219] 0x000000080000-0x000000240000 : "U-Boot"
[ 1.719177] 0x000000260000-0x0000002a0000 : "U-Boot Env"
[ 1.725799] 0x000000280000-0x000000780000 : "Kernel"
[ 1.734039] 0x000000780000-0x000000880000 : "cache"
[ 1.740570] 0x000000880000-0x000006c80000 : "recovery"
[ 1.787994] 0x000006c80000-0x000020000000 : "File System"
[ 1.960144] OneNAND driver initializing
[ 1.964782] UBI: attaching mtd5 to ubi0
[ 1.968780] UBI: physical eraseblock size: 131072 bytes (128 KiB)
[ 1.975372] UBI: logical eraseblock size: 129024 bytes
[ 1.980987] UBI: smallest flash I/O unit: 2048
[ 1.985870] UBI: sub-page size: 512
[ 1.990692] UBI: VID header offset: 512 (aligned 512)
[ 1.996765] UBI: data offset: 2048
[ 2.167388] UBI: max. sequence number: 0
[ 2.187500] UBI: volume 0 ("rootfs") re-sized from 773 to 788 LEBs
[ 2.194702] UBI: attached mtd5 to ubi0
[ 2.198638] UBI: MTD device name: "recovery"
[ 2.204071] UBI: MTD device size: 100 MiB
[ 2.209259] UBI: number of good PEBs: 800
[ 2.214050] UBI: number of bad PEBs: 0
[ 2.218688] UBI: number of corrupted PEBs: 0
[ 2.223297] UBI: max. allowed volumes: 128
[ 2.228118] UBI: wear-leveling threshold: 4096
[ 2.233001] UBI: number of internal volumes: 1
[ 2.237640] UBI: number of user volumes: 1
[ 2.242248] UBI: available PEBs: 0
[ 2.246887] UBI: total number of reserved PEBs: 800
[ 2.251983] UBI: number of PEBs reserved for bad PEB handling: 8
[ 2.258209] UBI: max/mean erase counter: 1/0
[ 2.262664] UBI: image sequence number: 34986596
[ 2.267639] UBI: background thread "ubi_bgt0d" started, PID 563
可以看出對UBI的解析已經正常了,下面將進入ubifs,出現如下資訊:
[ 7.308471] UBIFS error (pid 1): validate_sb: LEB size mismatch: 126976 in superblock, 129024 real
[ 7.317840] UBIFS error (pid 1): validate_sb: bad superblock, error 1
[ 7.326354] List of all partitions:
[ 7.330047] 1f00 128 mtdblock0 (driver?)
[ 7.335296] 1f01 1792 mtdblock1 (driver?)
[ 7.340576] 1f02 256 mtdblock2 (driver?)
[ 7.345855] 1f03 5120 mtdblock3 (driver?)
[ 7.351104] 1f04 1024 mtdblock4 (driver?)
[ 7.356384] 1f05 102400 mtdblock5 (driver?)
[ 7.361663] 1f06 413184 mtdblock6 (driver?)
[ 7.366912] b300 3872256 mmcblk0 driver: mmcblk
[ 7.372467] b301 3871232 mmcblk0p1 00000000-0000-0000-0000-000000000000mmcblk0p1
[ 7.381072] No filesystem could mount root, tried: ubifs
從這裡得到的資訊提示可以看出還是製作ubifs檔案鏡像的時候出問題了,這裡提示的是超級塊(superblock)有問題,LEB size mismatch!!
LEB size mismatch繼續ubuntu下輸入mkfs.ubifs -h查看協助,看出有如下一條:
-e, --leb-size=SIZE logical erase block size
就是這個-e參數了,按這裡提示將之前的126976修改成129024,最後如下:
mkfs.ubifs -r ${RECOVERY_ROOTFS} -F -o ubifs.img -m 2048 -e 129024 -c 788
另外還有一個要說明的是ubifs.cfg這個檔案及-c參數確認的問題
如我對應的recovery的ubifs.cfg檔案如下:
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=95MiB
vol_type=dynamic
vol_name=rootfs
vol_flags=autoresize
這裡要注意的是上面紅色字串
關於這些值的計算說明如下:
Usable Size Calculation
As documented here, UBI reserves a certain amount
of space for management and bad PEB handling operations. Specifically:
- 2 PEBs are used to store the UBI volume table
- 1 PEB is reserved for wear-leveling purposes;
- 1 PEB is reserved for the atomic LEB change operation;
- a % of PEBs is reserved for handling bad EBs. The default for NAND is 1%
- UBI stores the erase counter (EC) and volume ID (VID) headers at the beginning of each PEB. 1 min I/O unit is required for each of these.
To calculate the full overhead, we need the following values:
| Symbol |
Meaning |
Value for XO test case |
| SP |
PEB Size |
128KiB |
| SL |
LEB Size |
128KiB - 2 * 2KiB = 124 KiB |
| P |
Total number of PEBs on the MTD device |
100MiB / 128KiB = 800 |
| B |
Number of PEBs reserved for bad PEB handling |
1% of P = 8 |
| O |
The overhead related to storing EC and VID headers in bytes, i.e. O = SP - SL |
4KiB |
UBI Overhead = (B + 4) * SP + O * (P - B - 4) = (8 + 4) * 128Kib + 4 KiB * (800 - 8 - 4) = 4688 KiB = 36.625 PEBs (取整數 36)
This leaves us with 800-36=764 PEBs or 97792KiB available for user data.
Note that we used "-c 788" in the above mkfs.ubifs command line to specify the maximum filesystem size, not "-c 764" The reason for this is that mkfs.ubifs operates in terms of LEB size (124 KiB), not PEB size (128Kib). 97792KiB / 124 Kib = 788.645... (取整788).
Volume size = 97792KiB (~95MiB)
這裡要說明一下的是,為什麼我把recovery分區設定成了100MiB,原因是要得到B這個參數是1% * P得到的,那麼P一定要大於等於100,而100*128KiB = 12.5MiB,由於我的nand是512MiB,就乾脆把recovery分區設定成100MiB(要考慮到壞塊等問題)
經過上面這些折騰之後,重新燒錄recovery檔案鏡像,系統重啟之後,哈哈,看:
但很快發現問題了,第一次進入recovery狀態是OK的,斷電重啟再次進入時則會出現如下錯誤:
[ 1.754913] UBI: attaching mtd4 to ubi0
[ 1.759155] UBI: physical eraseblock size: 131072 bytes (128 KiB)
[ 1.765625] UBI: logical eraseblock size: 129024 bytes
[ 1.771301] UBI: smallest flash I/O unit: 2048
[ 1.776214] UBI: sub-page size: 512
[ 1.780975] UBI: VID header offset: 512 (aligned 512)
[ 1.787078] UBI: data offset: 2048
[ 1.794128] UBI error: ubi_io_read: error -74 (ECC error) while reading 64 bytes from PEB 2:0, read 64 bytes
[ 1.804473] [<c00a3678>] (unwind_backtrace+0x0/0xec) from [<c02be868>](ubi_io_read+0x1b4/0x248)
[ 1.813659] [<c02be868>] (ubi_io_read+0x1b4/0x248) from [<c02bee1c>](ubi_io_read_ec_hdr+0x6c/0x338)
[ 1.823242] [<c02bee1c>] (ubi_io_read_ec_hdr+0x6c/0x338) from[<c02c24f0>] (ubi_scan+0x1b4/0xb9c)
[ 1.832489] [<c02c24f0>] (ubi_scan+0x1b4/0xb9c) from [<c02b9624>]
從錯誤提示的內容來看是ECC出問題了,但是這裡用的是HWECC,怎麼會報這個錯誤呢?
google一遍,在下面這篇部落格裡找到了問題的原因:
http://blog.csdn.net/lidehua1975/article/details/7768185
按照這裡的方法修改,其中options最先的初始化是在arch/arm/mach-omap2/board-xx.c的
zt6810_flash_init函數中
static void __init zt6810_flash_init(void)
{
……
……
NAND_NO_SUBPAGE_WRITE if (nandcs < GPMC_CS_NUM) {
printk(KERN_INFO "Registering NAND on CS%d\n", nandcs);
board_nand_init(zt6810_nand_partitions,ARRAY_SIZE(zt6810_nand_partitions),nandcs, NAND_BUSWIDTH_16 | NAND_NO_SUBPAGE_WRITE);//modify
by Xandy,NO subpage write
}
}
編譯完核心燒錄,再次進入到recovery模式,出現如下資訊:
[ 7.308471] UBIFS error (pid 1): validate_sb: LEB size mismatch:129024 in superblock,126976 real
[ 7.317840] UBIFS error (pid 1): validate_sb: bad superblock, error 1
[ 7.326354] List of all partitions:
[ 7.330047] 1f00 128 mtdblock0 (driver?)
[ 7.335296] 1f01 1792 mtdblock1 (driver?)
[ 7.340576] 1f02 256 mtdblock2 (driver?)
[ 7.345855] 1f03 5120 mtdblock3 (driver?)
[ 7.351104] 1f04 1024 mtdblock4 (driver?)
[ 7.356384] 1f05 102400 mtdblock5 (driver?)
[ 7.361663] 1f06 413184 mtdblock6 (driver?)
[ 7.366912] b300 3872256 mmcblk0 driver: mmcblk
[ 7.372467] b301 3871232 mmcblk0p1 00000000-0000-0000-0000-000000000000mmcblk0p1
[ 7.381072] No filesystem could mount root, tried: ubifs
哎,重新把製作recovery檔案鏡像的參數改回之前的吧:
mkfs.ubifs -r ${RECOVERY_ROOTFS} -F -o ubifs.img -m 2048 -e126976 -c 788
燒錄,運行,就不會再出現上面這些問題了!
真的是拔山涉水呀!!
目前 recovery系統已經正常載入了,但還有問題,比中提示的cache分區無法掛上去,這個有空再更進修改recovery下分區掛載的問題。