首页 > 技术知识 > 正文

1. 前言

由于场景需求,需要切换不同的rootfs进行挂载; 如下记录了调试过程

2. chroot 切换原理

Linux 3.4版本内核支持chroot系统调用,chroot可以改变进程froot directory 到新的文件系统挂载路径,current->fs->root = { new path,包含root vfsmount和root dentry}。 busybox工具包支持chroot shell命令:

chroot [OPTION] NEWROOT [COMMAND [ARG]…] chroot OPTION NEWROOT: 切换到新的root目录,在新的root目录下执行命令 3.adb shell rootfs切换 (1)获取rootfs2烧录文件

lichee编译linux方案,拷贝lichee/out/sun8iw7p1/linux/common/rootfs.ext4,将拷贝后的rootfs.ext4重命名为rootfs2.ext4{注:lichee/out/sun8iw7p1/linux/common/buildroot/target目录下放着rootfs.ext4原文件和目录}。 lichee编译android方案,将rootfs2.ext4文件拷贝到lichee/out/sun8iw7p1/android/common/目录下。

(2) 添加rootfs2分区

修改lichee/tools目录下pack文件和方案对应的sys_partition.fex文件,添加rootfs2分区。

diff –git a/pack/chips/sun8iw7p1/configs/dolphin-p2/sys_partition.fex b/pack/chips/sun8iw7p1/configs/- -dolphin-p2/sys_partition.fex index e3453e5..2890a09 100755 — a/pack/chips/sun8iw7p1/configs/dolphin-p2/sys_partition.fex +++ b/pack/chips/sun8iw7p1/configs/dolphin-p2/sys_partition.fex @@ -89,6 +89,14 @@ size = 16384 keydata = 1 user_type = 0x8000 +;——————————> mmcblk0p10/nandg +[partition] + name = rootfs2 + size = 286720 + downloadfile = “rootfs2.fex” + keydata = 1 + user_type = 0x8000 + ;——————————> mmcblk0p11/nandh [partition] name = Reserve0 diff –git a/pack/pack b/pack/pack index 4a2afde..a199b5a 100755 — a/pack/pack +++ b/pack/pack @@ -599,6 +599,7 @@ function do_pack_android() ln -s ${ANDROID_IMAGE_OUT}/boot.img boot.fex ln -s ${ANDROID_IMAGE_OUT}/system.img system.fex ln -s ${ANDROID_IMAGE_OUT}/recovery.img recovery.fex + ln -s ${LICHEE_OUT}/rootfs2.ext4 rootfs2.fex
<
(3) 手动挂载rootfs2分区

调试主板烧录android方案固件,系统启动初始化后,查看block块与分区的映射关系,检查rootfs分区块设备是否已经创建,如下蓝色标示所示。

# ls -l /dev/block/by-name lrwxrwxrwx root root 1970-01-01 08:00 Reserve0 -> /dev/block/nandi lrwxrwxrwx root root 1970-01-01 08:00 Reserve1 -> /dev/block/nandk lrwxrwxrwx root root 1970-01-01 08:00 Reserve2 -> /dev/block/nandl lrwxrwxrwx root root 1970-01-01 08:00 UDISK -> /dev/block/nandn lrwxrwxrwx root root 1970-01-01 08:00 boot -> /dev/block/nandc lrwxrwxrwx root root 1970-01-01 08:00 bootloader -> /dev/block/nanda lrwxrwxrwx root root 1970-01-01 08:00 cache -> /dev/block/nandm lrwxrwxrwx root root 1970-01-01 08:00 env -> /dev/block/nandb lrwxrwxrwx root root 1970-01-01 08:00 klog -> /dev/block/nandj lrwxrwxrwx root root 1970-01-01 08:00 misc -> /dev/block/nande lrwxrwxrwx root root 1970-01-01 08:00 private -> /dev/block/nandg lrwxrwxrwx root root 1970-01-01 08:00 recovery -> /dev/block/nandf lrwxrwxrwx root root 1970-01-01 08:00 rootfs2 -> /dev/block/nandh lrwxrwxrwx root root 1970-01-01 08:00 system -> /dev/block/nandd

rootfs2 分区对应block设备创建成功后,通过adb工具执行以下命令进行手动挂载rootfs2分区: adb shell e2fsck -y /dev/block/nandh

adb 控制台打印如下: e2fsck 1.41.14 (22-Dec-2010) /dev/block/nandh: clean, 996/7168 files, 24876/28672 blocks

mkdir /mnt/tmps mount -o rw,noatime,nosuid,nodev,nomblk_io_submit,barrier=1,noauto_da_alloc -t ext4 /dev/block/nandh /mnt/tmps

adb 控制台打印如下: root@dolphin-fvd-p1:/ # mount …. … /dev/block/nandh /mnt/tmps ext4 rw,nosuid,nodev,noatime,nomblk_io_submit,noauto_da_alloc,data=ordered 0 0 … …. # ls -l /mnt/tmps -rwxr-xr-x root root 2809 2016-07-28 15:21 autorun.sh drwxr-xr-x root root 2012-09-26 15:20 bin drwxr-xr-x root root 2012-07-02 16:21 dev drwxr-xr-x root root 2016-07-28 15:21 dragonboard drwxr-xr-x root root 2014-03-15 20:26 etc drwxr-xr-x root root 2012-07-02 16:21 home lrwxrwxrwx root root 2012-07-02 16:21 init -> bin/busybox drwxr-xr-x root root 2016-07-28 15:21 lib lrwxrwxrwx root root 2012-07-02 16:21 linuxrc -> bin/busybox drwxr-xr-x root root 2012-07-02 16:21 mnt drwxr-xr-x root root 2012-07-02 16:21 opt drwxr-xr-x root root 2012-07-02 16:21 proc drwxr-xr-x root root 2012-07-02 16:21 root drwxr-xr-x root root 2012-07-02 16:21 sbin drwxr-xr-x root root 2012-07-02 16:21 sys drwxr-xr-x root root 2012-07-02 16:21 tmp drwxr-xr-x root root 2012-07-02 16:21 usr drwxr-xr-x root root 2012-07-02 16:21 var
<
(4) adb shell手动切换 / 目录

chmod 777 /mnt/tmps/bin busybox-smp chroot /mnt/tmps /bin/busybox mount -t proc newproc /proc busybox-smp chroot /mnt/tmps /bin/busybox cat /proc/self/mountinfo

将当前adb shell 进程rootfs / 目录切换到/mnt/tmps挂载路径,挂载proc文件系统到新的 / 目录下,并重命名newproc,最后通过cat /proc/self/mountstats 命令打印出adb shell空间mountinfo 信息,查看rootfs是否切换成功。 命令执行后,从adb控制台打印可以看到adb shell进程空间的 / 目录已经切换到/dev/block/nandh块设备对应的挂载分区,且newproc挂载在当前进程空间的 /proc 路径。 adb 控制台打印如下: 292 1 93:56 / / rw,nosuid,nodev,noatime shared:19 – ext4 /dev/block/nandh – -rw,nomblk_io_submit,noauto_da_alloc,errors=remount-ro,data=ordered 512 292 0:3 / /proc rw,relatime shared:20 – proc newproc rw

为了进一步证明adb shell rootfs已经切换成功,此时通过console shell执行命令: cat /proc/self/mountstats 命令执行后,从console 控制台打印可以看到,/dev/block/nandh块设备已经成功挂载在系统/mnt/tmps 目录下,而newproc挂载到了/mnt/tmps/proc目录下,说明adb shell rootfs切换成功。

console 控制台打印如下: …. ….. …. 292 1 93:56 / /mnt/tmps rw,nosuid,nodev,noatime shared:19 – ext4 /dev/block/nandh- -rw,nomblk_io_submit,noauto_da_alloc,errors=remount-ro,data=ordered 512 292 0:3 / /mnt/tmps/proc rw,relatime shared:20 – proc newproc rw …. ….. …. 4. android init rootfs切换

参照实验操作细节,准备以下实验条件和步骤: (1) 添加rootfs2分区 (2) 修改android init代码,添加切换rootfs代码

— a/init/boostup.c +++ b/init/boostup.c @@ -726,6 +726,13 @@ static int aw_media_karaok_boost_cpus(int pid, int index) active = 0; } + B_LOG(“\n\n ++++++++++++ boost pid %d changeroot\n”,getpid()); + if (execl(“/system/bin/busybox-smp”, “/system/bin/busybox-smp”, “chroot”, + “/mnt/tmps”, “/bin/busybox”, “init”, NULL)) { + ERROR(“pid%d start exec failed %s \n”, getpid(), strerror(errno)); + }

(3) 编译、烧录android固件和启动android系统 (4)手动挂载rootfs2分区, 修改rootfs2分区/bin目录和/sbin目录下的文件可执行权限 (5) 发送init rootfs切换命令 setprop media.boost.pref modem1:2

发送完命令后,android init进程首先通过chroot命令将进程的rootfs切换到/mnt/tmps分区,然后通过exec命令加载/mnt/tmps/bin/busybo ELF可执行文件,最后执行busybox init。 注意:此处的init rootfs切换只是初步试验,由于busybox init过程会涉及解析initab,挂载分区等操作,所以android init 直接切换到linux小系统的busybox init不会执行完整过程。

接下来需要验证android init进程切换rootfs后,进程状态会发生哪些变化.

a. 系统Init进程名发生变化 通过adb shell ps-p命查看系统init进程名称已经变更成/bin/busybox,如下:

Android Rootfs切换调试记录

b. 系统console控制台发生变化 通过串口console 控制台可以看到linux小系统登录的shell界面, Android Rootfs切换调试记录1

c. 系统init进程信息变化 通过adb shell cd /proc/1 命令切换到系统init进程在/proc debug目录,查看切换后的init进程状态变化,如下,系统init进程cwd对应到/mnt/tmps目录,运行的ELF文件对应到exec /mnt/tmps/bin/busybox可执行文件,root目录指向root -> /mnt/tmps 目录。 Android Rootfs切换调试记录2

adb shell debuggerd命令查看系统init进程backtrace Android Rootfs切换调试记录3

adb shell 命令查看系统init进程mountinfo信息,/目录切换到/dev/block/nandh块设备区 Android Rootfs切换调试记录4

猜你喜欢