ubuntu&android双系统制作过程_misc.img_感悟人生-123的博客-程序员秘密

技术标签: firefly学习  

ubuntu&android双系统制作过程

转载 作者 :orbbec-wmy 链接方式: link
同样站在巨人的肩膀上总结制作过程,参(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源码不做任何修改。在打包时注意就可以。

打包过程:

简单暴力的方法:把官方的双系统固件下载下来然后出了一些打包脚本和可执行文件,其他全部换成自己东西。
下面是我截取出来的可用文件下载地址:
[link]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,直接拷到对应目录下,给其读写权限即可。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_43835681/article/details/102676837

智能推荐

network.service - LSB: Bring up/down networking Loaded: loaded (/etc/rc.d/init.d/network; bad; v_瓦哥架构实战的博客-程序员秘密

 linux/centos7 关闭NetworkManager服务 network configure error systemctl disable NetworkManagerhttp://blog.51cto.com/doiido/1553441 http://blog.51cto.com/addam/1839518 https://www.jian...

七年级计算机教案部编,闽教版七年级上信息技术教案新部编本(59页)-原创力文档..._逆狗的博客-程序员秘密

育人犹如春风化雨,授业不惜蜡炬成灰育人犹如春风化雨,授业不惜蜡炬成灰教师学科教案[20-20学年度第—学期]任教学科:任教年级:任教老师:xx市实验学校r \??- 二〕r——2013-2014 学年上学期信息技术教案课题:活动一:话说信息技术应用教学目标:通过感受和描述身边的信息,感知信息,了解信息的概念及其特征。2 . 了解信息技术及其发展过程。感受信息技术带来的生活方式、学习方式的变化。能正...

文本摘要:传统方法整理+论文阅读笔记(CopyNet,Pointer-Generator-Network,NeuSum)_whxf_的博客-程序员秘密

文本摘要:传统方法整理+论文阅读笔记(CopyNet,Pointer-Generator-Network,NeuSum)文章目录文本摘要:传统方法整理+论文阅读笔记(CopyNet,Pointer-Generator-Network,NeuSum)摘要文本摘要方法简述CopyNet模型综述拷贝模式和生成模式}Decoder状态更新矩阵M多重处理实验Pointer-Generator-Networ...

Android之PowerManager电源管理_chenzujie的博客-程序员秘密

翻译来源PowerManager这个类让你拥有控制设备状态的权利。使用这个api类会很明显地影响设备电量的使用时长。除非你确实需要PowerManager.WakeLock否则不要轻易使用它们,并尽量使用低等级功能,并确保在你不使用它们的时候立即释放PowerManager.WakeLock。你可以通过使用Context.getSystemService来获取这个类的实例。

matlab xdata ydata,关于命令:x = lsqcurvefit ('fun', x0, xdata, ydata,..._君信陌的博客-程序员秘密

Iwenttohavemyglasses______.A.fitB.fittedC.fitonD.fittedonEFITA.0B.2C.3D.4WhatlessonhasReeboklearnedfromNike'sdistributionproblems?A.AcompanyshouldnotsWhatlessonhasReeboklearnedfromNike'sdistributionpr...

数量经济学推荐的Julia教程_weixin_30482383的博客-程序员秘密

http://quant-econ.net/jl/learning_julia.htmlJulia最为号称和c媲美的运行速度,想python一下简单的语法,虽然发展还不完善,但任然值得去关注。Julia运行学习和python很像,现在安装好了之后就有了一个repl,设置好环境变量后就可以在任何地方调用它了编写Julia脚本也很简单,sublime安装它的语法高亮和补全扩展就可以了运...

随便推点

机器学习经典算法总结(5)——强化学习_强化学习 贪心策略__Yucen的博客-程序员秘密

一.强化学习的概念1. 基础介绍强化学习模型根据输入学习一系列动作(action),而不同的动作会逐渐累计起来,在某些时候就会得到一些奖赏(reward)。执行某个动作并不能立即获得这个最终奖赏,只能得到一个当前反馈。机器要做的是通过在环境中不断尝试而学得一个策略(policy)。举一个相关实例:通常强化学习在游戏领域应用较多,输入就是当前的状态(如前后左右哪里有敌人,自身的技能CD值,红蓝条等等...

单接口测试(场景测试)_单接口测试有意义吗_qq_37920268的博客-程序员秘密

json格式测试:通常我们的接口一般设计的都是传递json串,那么就需要去测试如果传递非json的情况,这时候程序会不会正确的处理,返回相应的 error code默认值测试:很多情况一些非必填的参数会有默认值,比如说一个查询的接口,参数count为返回查询的结果数量,默认为10,那么就应该有一条case来测试,当然前置条件是数据库里面必须要存在这样的数据超过10条...

Oracle sql语句执行顺序_orcal plsql 执行先后_Simon188的博客-程序员秘密

转自:http://wang286480403.iteye.com/blog/1899915sql语法的分析是从右到左 一、sql语句的执行步骤:1)语法分析,分析语句的语法是否符合规范,衡量语句中各表达式的意义。2)语义分析,检查语句中涉及的所有数据库对象是否存在,且用户有相应的权限。3)视图转换,将涉及视图的查询语句转换为相应的对基表

C#调用codesoft实现批量打印_ChampaignWolf的博客-程序员秘密

 private void button4_Click(object sender, EventArgs e)        {            //即然能找到这来的基本上应该是对Codesoft有所了解了,所以基础的codesoft软件怎么用就不再讲,软件本身很简单,看看就会了,附件中有lab可以自己看一下            //1、在工程中添加Lppx2.tlb引用(这个Lppx2....

最长相同子串问题(一)_最长字串 串一分为二,两部分的和相同_Vitalia的博客-程序员秘密

输入两个长度不超过15的字符串,输出这两个字符串的最长相同子串,若有多个,则输出在第一个字符串中位置相对靠前的子串。测试样例:aaababccdeabcdabcdefbcdefabcdabcdefghatbcdtdefgabcdefghbcdeaaaaaaaaaaaaaaaaaaab#include #include using

压力测试介绍_系统 压力测试_张某人想退休的博客-程序员秘密

1.性能测试、压力测试、负载测试的区别性能测试负载测试、容量测试、压力测试(强度测试)都属于性能测试,性能测试是指在给定条件基准的前提下能达到的运行程度,测试软件在系统中的运行性能,度量系统与预定义目标的差距。负载测试(关注用户数量how much和性能指标)负载测试是模拟在超负荷环境中运行,通过不断加载(如逐渐增加模拟用户的数量)或其它加载方式来观察不同负载下系统的响应时间和数据吞吐量、系统占用的资源(如CPU、内存)等,以检验系统的行为和特性,以发现系统可能存在的性能瓶颈、内存泄漏、..

推荐文章

热门文章

相关标签