问题现象,华硕tinkerboard 2s启动失败,出错日志如下:
[ 1.620614] Run /init as init process
[ 1.627199] init: init first stage started!
[ 1.627699] init: [libfs_mgr]ReadFstabFromDt(): failed to read fstab from dt
[ 1.628020] init: [libfs_mgr]fstab path by boot mode:/fstab.rk30board
[ 1.628849] init: Using Android DT directory /proc/device-tree/firmware/android/
[ 1.794027] init: bool android::init::FirstStageMount::InitRequiredDevices(): partition(s) not found in /sys, waiting for their uevent(s): metadata
[ 11.795669] init: Wait for partitions returned after 10001ms
[ 11.795720] init: bool android::init::FirstStageMount::InitRequiredDevices(): partition(s) not found after polling timeout: metadata
[ 11.795877] init: Failed to mount required partitions early ...
[ 11.811644] init: #00 pc 00000000000e9ea0 /init
[ 11.811694] init: #01 pc 000000000006c7ac /init
[ 11.811724] init: #02 pc 000000000006ed84 /init
[ 11.811752] init: #03 pc 00000000000a4268 /init
[ 11.811780] init: #04 pc 0000000000064294 /init
[ 11.811807] init: #05 pc 0000000000147244 /init
[ 11.811832] init: Reboot ending, jumping to kernel
[ 11.872744] reboot: Restarting system with command 'bootloader'
分析问题:
从日志看metadata分区挂载不上,理论上android启动不是必须挂载metadata分区,我调整了gpt分区,确实把metadata分区删除了,于是我将该分区增加上去,依然报错。android启动会读取/proc/device-tree/firmware/android/ 获取要挂载的分区信息,该信息是从dtb中生成的,我查看dts,并没有相关信息。我增加了metadata分区,但没有上报uvent事件,于是,我在内核添加打印,查看是否内核都解析到分区信息:
diff --git a/block/partition-generic.c b/block/partition-generic.c
index 98d60a59b843..fa5debe8233e 100644
--- a/block/partition-generic.c
+++ b/block/partition-generic.c
@@ -322,6 +322,8 @@ struct hd_struct *add_partition(struct gendisk *disk, int partno,
const char *dname;
int err;
+ printk("zeng start:%llx,len:%llx,name:%s/n",(u64)start, (u64)len, info->volname);
+
err = disk_expand_part_tbl(disk, partno);
if (err)
return ERR_PTR(err);
发现并没有确实没有解析到metadata分区,于是再查看gpt信息,发现metadata分区起始地址0x007B0000,写错0x0077B0000,emmc并没有这么大,导致没有生成metadata分区。修改后,系统正常启动:
[ 1.616551] Run /init as init process
[ 1.623069] init: init first stage started!
[ 1.623593] init: [libfs_mgr]ReadFstabFromDt(): failed to read fstab from dt
[ 1.623905] init: [libfs_mgr]fstab path by boot mode:/fstab.rk30board
[ 1.624690] init: Using Android DT directory /proc/device-tree/firmware/android/
[ 1.667915] init: [libfs_mgr]Created logical partition system on device /dev/block/dm-0
[ 1.668798] init: [libfs_mgr]Created logical partition vendor on device /dev/block/dm-1
[ 1.669744] init: [libfs_mgr]Created logical partition product on device /dev/block/dm-2
[ 1.670573] init: [libfs_mgr]Created logical partition odm on device /dev/block/dm-3
从打印信息看,tinkerboard 开发板,并不是从/proc/device-tree/ 获取分区信息的,而是从文件/fstab.rk30board获取,该文件是存在ramdisk的。文件内容如下:
system /system ext4 ro,barrier=1 wait,logical,first_stage_mount
vendor /vendor ext4 ro,barrier=1 wait,logical,first_stage_mount
odm /odm ext4 ro,barrier=1 wait,logical,first_stage_mount
product /product ext4 ro,barrier=1 wait,logical,first_stage_mount
/dev/block/by-name/metadata /metadata ext4 nodev,noatime,nosuid,discard,sync wait,formattable,first_stage_mount
/dev/block/by-name/misc /misc emmc defaults defaults
/dev/block/by-name/cache /cache ext4 noatime,nodiratime,nosuid,nodev,noauto_da_alloc,discard wait,check
/dev/block/by-name/userdata /data ext4 discard,noatime,nosuid,nodev,noauto_da_alloc,data=ordered,user_xattr,barrier=1 latemount,wait,formattable,check,fileencryption=software,quota,reservedsize=128M,checkpoint=block
/dev/block/zram0 none wap defaults zramsize=50%
/devices/platform/*usb* auto vfat defaults voldmanaged=usb:auto
/devices/platform/fe320000.dwmmc/mmc_host* auto auto defaults voldmanaged=sdcard1:auto,encryptable=userdata
可知metadata分区是被要求在第一阶段需要被挂载上。