曲线救国:一个内核同时启动Linux和安卓系统(仅对技德有效)
2017-07-18 19:04:28
张捷
  • 访问次数: 22
  • 注册日期: 2017-06-27
  • 最后登录: 2017-09-27
  • 当前积分: 182
接上篇http://bbs.emindos.org/forum.php?mod=viewthread&tid=1087

摘要:在统一的内核基础通过chroot在archLinux上启动了技德的remix os,因为EmindOS和openthos的init系统问题现在还没能启动成功。

正文:
曾经尝试在Linux上,把安卓x86的系统解包到一个文件然后通过chroot或者lxc容器来启动,不过都还没搞出来。
后来想了想直接模拟initrd的启动过程来启动试试。基本思路就是解包initrd,修改其init启动文件,chroot initrd /init,利用其挂载system.sfs、data等,再启动安卓x86。道路非常的曲折呀。好在在技德remix os上成功启动了,验证了安卓x86和Linux桌面系统同时运行是完全可行的。不过由于EmindOS、openthos及原生安卓x86的init系统不同,都没有成功。
下面是曲线救国的过程:
1、首先解压initrd.img
  1. mkdir initrd 
  2. cd initrd
  3. zcat ../initrd.img | cpio -id > /dev/null
复制代码
2、修改init文件
      改变原有的挂载system.sfs的模式,system.sfs、ramdisk.img的位置都是已知的,所以没有必要搜索啥了,直接挂就是了。
修改前:
  1. mount -t tmpfs tmpfs /android
  2. cd /android
  3. while :; do
  4.     for device in ${ROOT:-/dev/[hmsv][dmr][0-9a-z]*}; do
  5.         check_root $device && break 2
  6.         mountpoint -q /mnt && umount /mnt
  7.     done
  8.     sleep 1
  9.     echo -n .
  10. done
复制代码
修改后:
  1. zcat ../ramdisk.img | cpio -id > /dev/null
  2. mount -o loop ../system.sfs ../sfs
  3. mount -o loop,rw ../sfs/system.img system
  4. mount --bind ../modules system/lib/modules
  5. cp /init.rc ./
  6. ln -s ../system/lib/firmware  /lib
  7. ln -s ../system/lib/modules  /lib
复制代码
其中initrc是ramdisk.img内的,需要简单修改一下
修改前:
  1. import /init.environ.rc
  2. import /init.usb.rc
  3. import /init.${ro.hardware}.rc
  4. import /init.usb.configfs.rc
  5. import /init.${ro.zygote}.rc
  6. import /init.trace.rc
复制代码
修改后:
  1. import /init.environ.rc
  2. import /init.usb.rc
  3. import /init.remix_x86_64.rc
  4. import /init.usb.configfs.rc
  5. import /init.zygote64_32.rc
  6. import /init.trace.rc
复制代码
ln -s ../system/lib/firmware  /lib和ln -s ../system/lib/modules  /lib 是来向system挂载新内核模块和固件的。

另外init文件的switch_root方式不适应,变更为chroot
修改前:
  1. export ANDROID_ROOT=/system
  2. exec ${SWITCH:-switch_root} /android /init
复制代码
修改后:
  1. export ANDROID_ROOT=/system
  2. chroot /android /init
复制代码
3、引导启动
启动前保证system.sfs、ramdisk.img、编辑过的inir.rc、新内核的modules和firmware在合适的位置。我都放在一个文件夹里了。
建立一个用于启动的文件夹root作为initrd的根目录,然后:
  1. mount -t tmpfs tmpfs root
  2. cp ramdisk.img root
  3. cp system.sfs root
  4. cp -r lib/modules root
  5. cp -r initrd/* root
  6. cp init.rc root
  7. mkdir root/dev
  8. chroot root /init
复制代码
为了方便我都采用复制的方式到root文件里去了,方便挂载。就是速度慢点。反正是验证可行性,也就先这样了。data分区没有挂载,启动以后是内存模式,没法保存数据的。

4、由于安卓的surfaceflinger占用tty7,所以我在archlinux里启动的,用Ubuntu或者emind desktop需要修改gnome和lightdm/gdm到其他tty去。
5、存在的问题:
       a、启动过程曲折,需要简化改进。
       b、仅能在remix os 测试成功。改进安卓x86 或者 Linux  的 init系统才是王道。
       c、archlinux和remix os之间在网络管理上有冲突,造成网络不能访问。不过openthos没有这个问题(chroot archlinux时启动udev测试的结果)
      d、其他问题,比如声卡的冲突,很久以前测试的,现在有些记不得了。
6、期望
     我就是简单的堆砌、测试,对于个中原理一头雾水。还希望有大神指点。听说一铭要搞类似的功能,期待中。
2017.7.17
7、近期进展
        a.启动脚本已经简化,openthos适用
  1. #!/bin/bash
  2. PATH=/sbin:/bin:/system/bin:/system/xbin:$PATH; export PATH
  3. mount -t tmpfs tmpfs android
  4. cd android
  5. zcat ../ramdisk.img | cpio -id > /dev/null
  6. mount -o loop ../system.sfs ../sfs
  7. mount -o loop,rw ../sfs/system.img system
  8. mount --bind ../data data
  9. cp ../init.rc ./
  10. exec chroot ../android /init
复制代码
        b.一铭陈工已经用类似方式复现,效果和稳定性会更好,期待其结果。
         c.用lxc容器启动更加稳定。
         d.目前进行了简单测试,问题还是很多:
                 *      切换后安卓可能键盘丢失,按ctrl再按alt可恢复
                 *      尝试两个系统挂载同一个磁盘,非root用户不能实现
                 *     尝试两个系统同时启动摄像头,摄像头崩溃
                 *     测试分别在Linux和安卓(用VLC)上播放同一视频cpu占用率相当,单核均在40-50%,整体占用率5~6%
                 *     启动百度(酷狗、qq等)音乐后声卡被完全安卓系统占用(个别情况下是好的)
                 *     尝试两个系统同时播放声音,不能实现。
                 *     lxc下运行,如果使用安卓系统执行关机操作,Ubuntu系统根目录会被挂载为只读。(安卓和Ubuntu同一分区测试的结果,不同分区未进行测试)
一铭云社区www.emindos.org,最好玩的Linux和Android开源社区,为广大Linux和Android爱好者提供探索、使用、交流的开源技术平台,更多消息请加入QQ群612724733,下载地址:http://www.emindos.org/emindos.html期待你的参与!