实现Linux/Android双系统启动和重启切换的一个思路
来源:互联网 发布:性价比帽子品牌知乎 编辑:程序博客网 时间:2024/05/14 07:30
双系统启动的方式不止一种。
一、对于双系统的启动镜像来说:
1、Linux系统和Android系统的uboot、kernel镜像相同而文件系统(rootfs)不同;
2、Linux系统和Android系统的uboot镜像相同而kernel镜像和文件系统(roofts)不同。
这两种情况都可以实现对双系统的启动和切换。
二、双系统启动和相互切换的实质是设置标志位,在启动时读取标志位信息从而启动相应的系统!下面是两种实现方式。
1、启动(重启)时,单独分出一个分区存储标志位(保证两个系统都能对这一块分区操作);
在应用程序中向分区写入标志位,然后重启在uboot阶段自动scan读取这个分区中的标志位(对应启动相应的系统)。
2、在文件系统分区写入一个.txt文件(文件存储标志位);
在uboot中scan读取该.txt文件的中的内容(标志位),然后决定启动相应的系统。
三、本次主要讨论Linux系统和Android共uboot的情况,实现方式为单独分出一个分区存储标志位。已实现。
1、要实现双系统的启动和相互切换,需要对uboot启动过程、bootargs引导参数有相应的了解。
2、首先,将uboot,Android系统的kernel和file system,Linux系统的kernel和file system烧写到emmc中,如下图所示。
注意:烧写的物理位置应与下面讲到的bootargs引导参数相对应,否则系统启动会失败!!!
图中为主要烧写部分,其他的烧写按照自己思路稍微调整。
设置flags分区,存储我们的启动标志位。
3、对uboot的修改:
(1)将bootargs引导参数写入uboot中,并且制作command命令,至于怎样将制作的command命令放在".u_boot_cmd"段: ,用下面例子讲解。
例子:
a)在common文件夹下创建cmd_sunplus.c;
b)在cmd_sunplus.c中添加“sunplus_linuxemmcboot 和sunplus_androidemmcboot”命令的响应函数的实现。具体的实现代码如下:
//====================================================================
int do_sunplus_linuxemmcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int ret = 0;
/*①
设置bootargs引导参数
//这里BOOT_TYPE_LINUX_EMMC为 "console=ttyAMA0,115200 root=/dev/mmcblk0p8 rootfstype=ext4 rootwait blkdevparts=mmcblk0:1M(boot),1M(bootargs),4M(baseparam),4M(pqparam),4M(logo),3058M(unused),8M(kernel),96M(rootfs),1M(flags),-(others) coherent_pool=1M"
*/
setenv("bootargs", BOOT_TYPE_ANDROID_EMMC );
/*②
从emmc中读取kernel到内存中:起始地址为0x600000(内核文件存储的实际物理地址),长度为0x4000,读到起始地址为0x1000000的内存中
*/
ret = run_command("mmc read 0 0x1000000 0x600000 0x4000" , 0);
if(ret == -1) {
printf("read kernel failed.\n");
sp_failed();
}
/* ③
启动Linux的kernel
*/
printf(GREEN"Boot to linux.\n"NONE);
run_command("bootm 0x1000000" , 0);
printf("bootm linux sys failed.\n");
return ret;
}
U_BOOT_CMD(
sunplus_linuxemmcboot, 1, 0, do_sunplus_linuxemmcboot,
"[sunplus app func]:boot up linux from emmc",
"\n"
);
int do_sunplus_androidemmcboot (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
int ret = 0;
/*①
设置bootargs引导参数
//这里BOOT_TYPE_ANDROID_EMMC为 "console=ttyAMA0,115200 blkdevparts=mmcblk0:1M(fastboot),1M(bootargs),10M(recovery),2M(deviceinfo),8M(baseparam),8M(pqparam),20M(logo),20M(logobak),40M(fastplay),40M(fastplaybak),40M(kernel),20M(misc),8M(userapi),8M(hibdrv),8M(qbflag),300M(qbdata),800M(system),1024M(userdata),500M(cache),50M(private),50M(sdcard),218M(unused),1M(flags),-(others) coherent_pool=1M"
*/
setenv("bootargs", BOOT_TYPE_ANDROID_EMMC );
/*②
从emmc中读取kernel到内存中:起始地址为0x4B000(内核文件存储的实际物理地址) ,长度为0x5000,读到起始地址为0x1FFBFC0的内存中
*/
ret = run_command("mmc read 0 0x1FFBFC0 0x4B000 0x5000" , 0);
if(ret == -1) {
printf("read kernel failed.\n");
sp_failed();
}
/* ③
启动Android的kernel
*/
printf(GREEN"Boot to android.\n"NONE);
run_command("bootm 0x1FFBFC0" , 0);
printf("bootm android sys failed.\n");
return ret;
}
U_BOOT_CMD(
sunplus_androidemmcboot, 1, 0, do_sunplus_androidemmcboot,
"[sunplus app func]:boot up android from emmc",
"\n"
);
//====================================================================
c)将common/cmd_sunplus.c编译进u-boot.bin,在common/Makefile中加入如下代码:
COBJS-$(CONFIG_BOOT_SUNPLUS) += cmd_sunplus.o
d)在include/configs/hi3798mx.h(代码相应位置)加入如代码:
#define CONFIG_BOOT_SUNPLUS
e)重新编译下载U-Boot就可以使用sunplus_linuxemmcboot 和sunplus_androidemmcboot 命令了
(2)在boot源码的Main.c中,找到main_loop()函数。
要实现双系统启动,需要在boot启动阶段扫描咱们定义的标志位,然后启动相应的系统。下图是main_loop()函数的扫描标志位操作,在如图所示位置加入扫描标志位分区,既能率先扫描分区,又能达到控制Ctrl+C到boot命令下
4、编译boot,烧写完成之后启动系统。
启动完成后,在Linux系统下,flags(标志位分区)是/dev/mmcblock0p9第九分区,在/dev/mmcblock0p9设备文件中写入“android”,重启即可切换到Android系统。同理,在Android系统下,flags(标志位分区)在/dev/block/mmcblock0p23第23分区,在/dev/block/mmcblock0p23设备文件中写入“linuxaa”,即可切换到Linux系统。
两个系统虽然是不同的设备文件名,但都是操作的同一块物理地址(起始地址为0x63400)。
这样就完成了双系统的启动。
本文只是一种思路,有更好的请广大码友指教!
1 0
- 实现Linux/Android双系统启动和重启切换的一个思路
- Linux 和 Windows 双系统启动顺序切换
- 实现Linux和QNX双系统启动
- Qt 切换皮肤的一个实现思路
- 电脑双系统启动顺序的切换方法
- android 2种切换语言方式:应用内切换和随系统而切换 代码实现重启应用
- linux和xp双系统的启动顺序问题
- Linux和Win7双系统无法启动的完美解决方案
- windows 和 linux双系统改变 grub 的启动顺序
- windows 和 linux双系统改变 grub 的启动顺序
- XP和Linux双系统启动菜单的修复
- XP和Linux双系统如何修改默认启动的系统
- Linux下memcache的安装和启动、停止、重启
- 【Linux】 网络服务的启动、关闭和重启
- Vista和Ubuntu Linux双系统启动问题
- Linux和windows双系统启动终极解决方法
- linux和windows双系统启动顺序
- linux和windows双系统,更改启动项
- Java中23种设计模式详解,留着备忘
- LeetCode笔记:357. Count Numbers with Unique Digits
- 2016大总结17展望
- config服务之间数据有差异
- C/C++ OpenCV之Scharr边缘检测
- 实现Linux/Android双系统启动和重启切换的一个思路
- 《2016年度中国智库大数据报告》发布 哪些智库进入TOP20榜单
- [iOS]部分页面变换主题,navigation bar,tabBar颜色修改,状态栏
- 仿OneThinkPHP代码实现数据库备份还原失败总结
- 修改xcode快捷键
- PL/SQL DEVELOPER 使用的一些技巧
- PTA1007 Maximum Subsequence Sum
- Struts2的拦截器笔记--excludeMethods
- mysql判断是否为闰年