Android Rootfs切换调试记录

free-jdx 2021-03-26 16:03:04 4479
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,如下:

b. 系统console控制台发生变化
通过串口console 控制台可以看到linux小系统登录的shell界面,

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 目录。

adb shell debuggerd命令查看系统init进程backtrace

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

声明:本文内容由易百纳平台入驻作者撰写,文章观点仅代表作者本人,不代表易百纳立场。如有内容侵权或者其他问题,请联系本站进行删除。
free-jdx
红包 93 7 评论 打赏
评论
0个
内容存在敏感词
手气红包
    易百纳技术社区暂无数据
相关专栏
置顶时间设置
结束时间
删除原因
  • 广告/SPAM
  • 恶意灌水
  • 违规内容
  • 文不对题
  • 重复发帖
打赏作者
易百纳技术社区
free-jdx
您的支持将鼓励我继续创作!
打赏金额:
¥1易百纳技术社区
¥5易百纳技术社区
¥10易百纳技术社区
¥50易百纳技术社区
¥100易百纳技术社区
支付方式:
微信支付
支付宝支付
易百纳技术社区微信支付
易百纳技术社区
打赏成功!

感谢您的打赏,如若您也想被打赏,可前往 发表专栏 哦~

举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

审核成功

发布时间设置
发布时间:
是否关联周任务-专栏模块

审核失败

失败原因
备注
拼手气红包 红包规则
祝福语
恭喜发财,大吉大利!
红包金额
红包最小金额不能低于5元
红包数量
红包数量范围10~50个
余额支付
当前余额:
可前往问答、专栏板块获取收益 去获取
取 消 确 定

小包子的红包

恭喜发财,大吉大利

已领取20/40,共1.6元 红包规则

    易百纳技术社区