|
ubuntu&android双系统制作过程
发表于 2017-2-22 10:35:15
浏览:7003
|
回复:0
打印
只看该作者
[复制链接]
楼主
ubuntu&android双系统制作过程
同样站在巨人的肩膀上总结制作过程,参(nian)考(tie)这个版主:点击跳转
硬件:rk3288cpu maligpu
软件:ubuntu16.04 & android4.4
双系统原理简单介绍:
android系统分区详解:
分区大小(字节) | 分区名称 | 4M | uboot | 4M | misc | 16M | resource | 16M | kernel | 32M | boot | 32M | recovery | 52M | backup | 128M | cache | 4M | kpanic | 768M | system | 4M | metadata | 1G | userdata | 64M | radical_update | 总容量-2152M | user |
首先了解下android在进入急救模式时,或者说恢复出厂设置的时候都会去加载recovery分区里的内容,原本recovery分区就放着一个急救内核用来升级、恢复所用。目前双系统的原理的要点就是把启动ubuntu的内核放到recovery分区,这样只要androidjinru急救模式,就相当于切换到recovery分区执行ubuntu的kernel,最终成功引导ubuntu 根文件系统。
而正常情况下,开机是不会跑到recovery分区的,一般是uboot阶段会去加载misc分区,读取当中的字段,然后判断是否要加载recovery分区,misc.Img字段如下:
用 hexdump 命令可以方便地查看 misc.img 的内容:
- $ hexdump -C rkst/Image/misc.img
- 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
- *
- 00004000 62 6f 6f 74 2d 72 65 63 6f 76 65 72 79 00 00 00 |boot-recovery...|
- 00004010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
- *
- 00004040 72 65 63 6f 76 65 72 79 0a 2d 2d 77 69 70 65 5f |recovery.--wipe_|
- 00004050 61 6c 6c 00 00 00 00 00 00 00 00 00 00 00 00 00 |all.............|
- 00004060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
- *
- 0000c000
复制代码
可见,前 16K (0x4000) 字节都是 0,然后是一个 "boot-recovery" 命令,后面又跟着 "recovery", "--wipe_all" 这些动作和参数。
启动加载器(bootloader, 这里是 u-boot),会读出这个分区的内容,如果是 "boot-recovery",则加载 recovery 分区,则进入了ubuntu系统;如果不是的话,直接加载kernel分区,进入了android系统。
所以要实现双系统的切换,只要实现向misc分区里面读写标志即可,即有下面的两种方法:
android->ubuntu : 向misc分区写入 boot-recovery的标志
ubuntu->android : 清空misc分区的内容
具体实现方案:
1.如何从android进入 Linux
接下来的事情是解决如何进入 Linux, 因为我们将 Linux 放在 recovery 分区,因此,问题等价于如何进入安卓的急救模式。以下有几种方式:
- 拔掉 USB 线,按住开发板的 recovery 键开机(无论是初次上电、重启或按 reset 键开机都可以)。这是临时性的切换,下次开机不按,还是会进入 Linux 。
- 在安卓系统的设置里选择恢复出厂设置。实际上,恢复出厂设备这个功能已被阉割了,重启后会进入 Linux。
- Firefly-RK3288 在安卓系统的关机菜单(点底部工具栏的关机按钮进入)增加了一项切换系统的选择,非常人性化。当然,它是检测到 linuxroot 分区才会出现,也就是说单系统是不会出现的。
- 将 SDK 里的 rkst/Image/misc.img 刷进到 misc 分区。
2~4 项都是通过写 misc 分区,达到切换到 recovery,这里也即是 Linux 的目的。我这边制作过程中才用点选恢复出厂设置的方法进入ubuntu系统。
2.如何从 Linux 切换回 Android
很简单,写个脚本将 misc 分区清空,然后重启即可:
- sudo dd if=/dev/zero of=/dev/block/mtd/by-name/misc bs=16k count=3
- sudo reboot
复制代码
制作过程:
ubuntu根文件系统制作:
首先得有一个得以正常使用的ubuntu固件,之前的文档有讲述如何制作ubuntu 根文件系统。也就是现在你先运行一个单ubuntu系统的固件,在此基础上修改。在~目录下创建 b2android.sh
在里面添加以下内容:
sudo dd if=/dev/zero of=/dev/block/mtd/by-name/misc bs=16k count=3
echo ; sleep 1
sudo sync
echo; sleep 1
sudo reboot
加上执行权限chmod +x b2android.sh
我们在 Linux 的根文件系统里增加了一个标志文件 /firstboot 。当 Linux 启动,检测到此文件存在,便判断这是第一次启动,需要做以下安卓系统的初始化动作:
- 使用 resize2fs 扩展根文件系统,修正文件系统的容量信息
- 格式化 userdata 分区
- 格式化 cache 分区
- 格式化 metadata 分区
- 格式化 user 分区
- 删除标志文件 /firstboot
- 重启回安卓系统
实现细节在在 /etc/rc.local,具体开机会执行的脚本first-boot-recovery.sh中修改成下面这样:
#!/bin/bash
clean_first_boot () {
rm -f /firstboot 2>/dev/null
sync
}
android_recovery () {
echo "=======Formatting userdata(/data)..."
mkfs.ext4 /dev/block/mtd/by-name/userdata
echo "=======Formatting metadata(/metadata)..."
mkfs.ext4 /dev/block/mtd/by-name/metadata
echo "=======Formatting cache(/cache)..."
mkfs.ext4 /dev/block/mtd/by-name/cache
if [ "$1" == "all" ]; then
echo "=======Formatting user(/sdcard)..."
for ((i=1;i<5;i++)); do
if mkfs.vfat /dev/block/mtd/by-name/user; then
break
fi
if grep -q "$(readlink -f /dev/block/mtd/by-name/user)" /proc/mounts; then
umount /dev/block/mtd/by-name/user
fi
sleep 1
echo "=======Retry: %i..."
done
fi
clean_first_boot
# reboot to android
dd if=/dev/zero of=/dev/block/mtd/by-name/misc bs=16k count=3
sync
reboot
}
if [ -e /firstboot ]; then
echo "======Expanding the rootfs..."
resize2fs /dev/block/mtd/by-name/linuxroot
if [ -e /dev/block/mtd/by-name/system ]; then
android_recovery all
else
rm -f /usr/local/bin/b2android* \
/usr/share/applications/b2android.desktop \
/home/firefly/Desktop/b2android.desktop
fi
clean_first_boot
elif grep firefly-recovery /dev/block/mtd/by-name/misc >/dev/null 2>&1; then
android_recovery
fi
具体开机脚本参考:点击跳转
ok之后打包ubuntu固件,方法可参考:点击跳转
其实ubuntu只要做两件事,第一次刷完机启动时做了原本android该做的格式化工作;还有就是添加一个切换到android的脚本。
android源码不做任何修改。在打包时注意就可以。
打包过程:
简单暴力的方法:把官方的双系统固件下载下来然后出了一些打包脚本和可执行文件,其他全部换成自己东西。
下面是我截取出来的可用文件下载地址:
http://pan.baidu.com/s/1gf0wScb
然后可以把自己的misc.img boot.img system.img kernel.img resource.img linux-rootfs.img linux-boot.img 放进这个文件夹,然后点击mkupdate.bat 就能生成固件了。另外根据需求可自行修改parameter的分区大小,我这边将linuxroot修改为4g大的空间。
注意点:
1.ubuntu和android的kernel是否一定要求同一份源码编译?
经试验,可以不同源码编译而成,当这边只有一个resource分区而且只能是android用的,所以要想用两个不同的kernel,linux-boot.img的打包方式就要将ubuntu所需的resource,img也打包进去:
mkbootimg --kernel zImage --ramdisk initrd.img --second resource.img -o linux-boot.img
这样可以使得ubuntu kernel和android kernel分离开来,互不影响。
2.有时从android切到ubuntu后,执行reboot后又回到android系统
这种情况有可能就是misc分区又被清空了,导致uboot阶段没有加载recovery分区,解决方法是ubuntu开机脚本中加入
sudo dd if=/usr/local/bin/misc.img of=/dev/block/mtd/by-name/misc bs=16k count=3
其中misc.img就是android编译出来的misc.img,直接拷到对应目录下,给其读写权限即可。
|
|