Firefly开源社区

标题: ubuntu&android双系统制作过程 [打印本页]

作者: orbbec-wmy    时间: 2017-2-22 11:42
标题: ubuntu&android双系统制作过程
ubuntu&android双系统制作过程


同样站在巨人的肩膀上总结制作过程,参(nian)考(tie)这个版主点击跳转



硬件:rk3288cpu maligpu
软件:ubuntu16.04 & android4.4

双系统原理简单介绍:

android系统分区详解:
分区大小(字节)分区名称
4Muboot
4Mmisc
16Mresource
16Mkernel
32Mboot
32Mrecovery
52Mbackup
128Mcache
4Mkpanic
768Msystem
4Mmetadata
1Guserdata
64Mradical_update
总容量-2152Muser


首先了解下android在进入急救模式时,或者说恢复出厂设置的时候都会去加载recovery分区里的内容,原本recovery分区就放着一个急救内核用来升级、恢复所用。目前双系统的原理的要点就是把启动ubuntu的内核放到recovery分区,这样只要androidjinru急救模式,就相当于切换到recovery分区执行ubuntu的kernel,最终成功引导ubuntu 根文件系统。
而正常情况下,开机是不会跑到recovery分区的,一般是uboot阶段会去加载misc分区,读取当中的字段,然后判断是否要加载recovery分区,misc.Img字段如下:
用 hexdump 命令可以方便地查看 misc.img 的内容:
复制代码

可见,前 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 分区,因此,问题等价于如何进入安卓的急救模式。以下有几种方式:


2~4 项都是通过写 misc 分区,达到切换到 recovery,这里也即是 Linux 的目的。我这边制作过程中才用点选恢复出厂设置的方法进入ubuntu系统。

2.如何从 Linux 切换回 Android

很简单,写个脚本将 misc 分区清空,然后重启即可:
复制代码

制作过程:
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 启动,检测到此文件存在,便判断这是第一次启动,需要做以下安卓系统的初始化动作:

实现细节在在 /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,直接拷到对应目录下,给其读写权限即可。





作者: jpchen    时间: 2019-6-13 19:04
好贴
作者: x-forever    时间: 2019-6-14 14:26
厉害了,相当不错,谢谢!
作者: 余正清    时间: 2024-4-10 20:55
牛逼




欢迎光临 Firefly开源社区 (https://dev.t-firefly.com/) Powered by Discuz! X3.1