uboot中正常启动模式和recovery启动模式切换的实现

uboot流程分析--修改android启动模式按键 本人用的android平台用的bootloader用的是uboot,貌似大多数手持设备平台都不用这个,因为功能过于强大用不上,反而显得太复杂了。不知道这个平台开发者是怎么想的。既然用了那就来分析一下,顺便修改一下recovery和fastboot的启动按键,以符合我们的硬件要求。 阅读详情
AI摘要

本文详细介绍了嵌入式系统中的Recovery模式及其启动流程。重点讲解了通过U-Boot实现Recovery模式的方法,包括按键检测、环境参数设置等关键步骤。

一个嵌入式系统,一般情况下都是正常启动模式,如果需要系统升级,或系统恢复出厂状态,就会需要用到recovery启动模式,它会从另外备份的kernel和rootfs启动。

在uboot中, check_recovery_mode()这个函数,就是用来实现这个功能的:

这个函数在lib_arm/board.c 的start_armboot (void)中被调用:

void start_armboot (void)
{
        init_fnc_t **init_fnc_ptr;
        char *s;
#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
        unsigned long addr;
#endif
...
#ifdef CONFIG_ANDROID_RECOVERY
        check_recovery_mode();
#endif
...
        }

        /* NOTREACHED - no way out of command loop except booting */
}
只要定义了 CONFIG_ANDROID_RECOVERY, 这个函数就会被调用。

该函数定义如下:

/* export to lib_arm/board.c */
void check_recovery_mode(void)
{
        if (check_key_pressing())
                setup_recovery_env();
#if 0
        else if (check_recovery_cmd_file()) {
                puts("Recovery command file founded!\n");
                setup_recovery_env();
        }
#endif
}
check_key_pressing()就是进入recovery模式的按键检查,若对应的按键被按下,就进入recovery模式,如果没有就正常启动。

#ifdef CONFIG_MXC_KPD

#define PRESSED_HOME    0x01
#define PRESSED_POWER   0x02
#define RECOVERY_KEY_MASK (PRESSED_HOME | PRESSED_POWER)

inline int test_key(int value, struct kpp_key_info *ki)
{
        return (ki->val == value) && (ki->evt == KDepress);
}

int check_key_pressing(void)
{
        struct kpp_key_info *key_info;
        int state = 0, keys, i;

        mxc_kpp_init();

        puts("Detecting HOME+POWER key for recovery ...\n");

        /* Check for home + power */
        keys = mxc_kpp_getc(&key_info);
        if (keys < 2)
                return 0;

        for (i = 0; i < keys; i++) {
                if (test_key(CONFIG_POWER_KEY, &key_info[i]))
                        state |= PRESSED_HOME;
                else if (test_key(CONFIG_HOME_KEY, &key_info[i]))
                        state |= PRESSED_POWER;
        }

        free(key_info);

        if ((state & RECOVERY_KEY_MASK) == RECOVERY_KEY_MASK)
                return 1;

        return 0;
}
#else
/* If not using mxc keypad, currently we will detect power key on board */
#define CPLD_BASE_ADDR 0xF4000000
#define KEY_STATUS 0xA
#define KEY_F1 0x1
#define KEY_F4 0x8

int check_key_pressing(void)
{
        volatile unsigned short tmp = 0;

        tmp = *(volatile unsigned short *)(CPLD_BASE_ADDR + KEY_STATUS);

        if(((tmp & KEY_F1) != 0) && ((tmp & KEY_F4) != 0))
                return 1;

        return 0;
}
#endif
这里用了if -else 完成了两个按键检测功能,第一个是MXC自带的键盘初始化和检测机制,第二个是我自己写的都键盘的内存地址。
setup_recovery_env() 就是设置进入recovery模式需要的enviroment parameters

void setup_recovery_env(void)
{
        char *env, *boot_args, *boot_cmd;
        int bootdev = get_boot_device();
        printf(" bootdev = %d..\n", bootdev);

        boot_cmd = supported_reco_envs[bootdev].cmd;
        boot_args = supported_reco_envs[bootdev].args;

        if (boot_cmd == NULL) {
                printf("Unsupported bootup device for recovery\n");
                return;
        }

        printf("setup env for recovery..\n");

        env = getenv("bootargs_sf");
        /* Set env to recovery mode */
        /* Only set recovery env when these env not exist, give user a
         * chance to change their recovery env */
        if (!env)
                setenv("bootarg_sf", boot_args);

        env = getenv("bootcmd_sf");
        if (!env)
                setenv("bootcmd_sf", boot_cmd);
        setenv("bootcmd", "run bootcmd_sf");
}

这里用到一个全局变量, 用来保存recovery模式启动时的evn参数:

struct reco_envs supported_reco_envs[BOOT_DEV_NUM] = {
        {
         .cmd = NULL,
         .args = NULL,
         },
        {
         .cmd = NULL,
         .args = NULL,
         },
        {
         .cmd = NULL,
         .args = NULL,
         },
        {
         .cmd = NULL,
         .args = NULL,
         },
        {
         .cmd = NULL,
         .args = NULL,
         },
        {
         .cmd = CONFIG_RECOVERY_BOOTCMD_SPI_NOR,
         .args = CONFIG_RECOVERY_BOOTARGS_SPI_NOR,
         },
        {
         .cmd = NULL,
         .args = NULL,
         },
        {
         .cmd = NULL,
         .args = NULL,
         },
        {
         .cmd = NULL,
         .args = NULL,
         },
};

/*
 * Recovery Configs
 */
#define CONFIG_ANDROID_RECOVERY
#define CONFIG_RECOVERY_BOOTARGS_SPI_NOR \
        "setenv bootargs_sf setenv bootargs console=ttymxc0,115200 ip=dhcp root=/dev/mtdblock3 rootwait rw"
#define CONFIG_RECOVERY_BOOTCMD_SPI_NOR \
        "setenv bootcmd_sf run bootargs_sf;sf probe 1;sf read ${loadaddr} 80000 300000;bootm ${loadaddr}"


env参数设置如下:

正常启动,从MMC启动

setenv bootcmd_mmc run bootargs_base bootargs_mmc\;mmc dev 0\;ext2load mmc 0:1 ${loadaddr} /boot/uImage\;bootm ${loadaddr}
setenv bootcmd run bootcmd_mmc
recovery模式启动,从spi-flash中启动

setenv bootargs_sf setenv bootargs console=ttymxc0,115200 ip=dhcp root=/dev/mtdblock3 rootwait rw
setenv bootcmd_sf run bootargs_sf\;sf probe 1\;sf read ${loadaddr} 80000 300000\;bootm ${loadaddr}
setenv bootcmd run bootcmd_sf


开发板救砖指南:当eMMC无法启动时如何用TF卡重烧Uboot 本文详细介绍了开发板eMMC无法启动时的救砖方法,重点讲解如何通过TF卡重烧Uboot并恢复完整系统。内容涵盖故障诊断、TF卡启动制作、分区重建、镜像烧写等关键步骤,适用于iTOP-4412、RK3568等常见开发板,帮助开发者快速解决启动故障问题。 阅读详情

相关推荐

RK3576 Android SD启动与eMMC启动对比:2种模式切换与3个关键差异点

本文深入解析RK3576平台Android系统的SD启动与eMMC启动模式,详细对比2种启动方式的技术差异与性能表现,并提供实战切换指南。从物理特性、启动流程到开发调试,全面剖析SD卡与eMMC在嵌入式系统中的关键区别,帮助开发者根据项目需求选择最优启动方案。

weixin_30394669的博客 413

记录自己学习android系统启动以及 recovery过程(1)----------uboot

记录自己学习android系统启动以及 recovery过程(1)----------uboot 欢迎指出其中错误。 启动uboot bootm文件作为uboot->kernel的最后一个步骤,负责引导内核,并配置需要传递进内核的相关参数 在uboot启动后,会检查是否需要recovery,一般通过两个途径, 1.挂载boot device,并查看/cache/recovery文件,2.

aibing7的专栏 4525

OpenHarmony 5.1.0 RK3568 开发板烧录:Loader与Maskrom模式切换的3种场景与操作

本文深入解析OpenHarmony 5.1.0在RK3568开发板上的烧录过程,重点介绍Loader与Maskrom模式的差异及三种典型场景下的操作指南。涵盖新板首次烧录、固件损坏恢复和升级失败重试等实用技巧,帮助开发者高效完成系统烧录与恢复工作。

dielucuan8830的博客 391

如何将uboot里面的参数传给recovery或kernel

最近我们在做一个LCM两屏或三屏兼容的问题,所以首先要在uboot里面读出各屏的id,然后再将读得到的id传给recovery和kernel,实现机器的正常显示. 一.首先实现uboot读lcm的id.           1.bootable/bootloader/lk/target/msm7627a_sku3_Q6_D/rules.mk是uboot里面宏开关,打开所显示的屏宏 DEF

Android驱动人生 1万+

RK3568 Maskrom模式全解析:三种进入方式与救砖实战

在嵌入式系统开发中,芯片启动流程是理解底层恢复机制的基础。RK3568作为通用型SoC,其上电后首先执行固化在内部ROM中的BootROM代码,用于初始化硬件并检测外部启动介质。当BootROM无法加载可用Loader或检测到强制信号时,芯片会进入Maskrom模式——这是芯片最底层、几乎不可被破坏的恢复状态。该模式在设备树配置错误、Uboot损坏、系统变砖等场景下极具价值,能够擦除Flash、烧写全部分区,是嵌入式工程师手中的“安全网”。基于这一原理,实际开发中常通过开发板按键、短接焊盘或复位组合等方式触

weixin_34342207的博客 477

OpenHarmony调试三板斧:串口日志、设备树选型与系统工具链实战

在嵌入式系统开发中,日志分析与硬件配置是定位问题的基石。串口日志作为系统启动阶段最可靠的信息源,能够完整呈现从Bootloader到内核初始化的全链路状态;设备树(DeviceTree)则扮演着硬件资源描述与匹配的关键角色,直接影响驱动加载与外设工作。掌握日志分级过滤、设备树节点修改与验证,以及hilog、hdc等系统调试工具链,是提升开发效率的核心能力。本文以RK3568开发板为例,结合x86环境补充,系统梳理了从硬件上电到应用层调试的完整方法,帮助开发者快速定位启动失败、驱动异常、系统卡死等高频问题。

weixin_34090562的博客 431

Android上层进入recovery流程

recovery介绍 recovery是android的一种特殊模式,我称之为还原升级模式。这里从recovery的功能说起: 1.擦除用户数据 设置菜单中的恢复到出厂模式,即擦除用户数据 2.系统升级 设置菜单中的系统升级功能;OTA INSTALL,即使用update.zip包升级 recovery的详细功能在源码 bootable/recovery/recovery.c

Hansomewang的博客 3570

RK3588 USB OTG烧录全解析:从Maskrom到Loader的底层原理与实战

在嵌入式系统开发中,固件烧录是连接硬件与软件的桥梁,无论是开发板调试还是量产交付,掌握底层启动流程对工程师至关重要。以Rockchip RK3588平台为例,其USB OTG烧录机制依托芯片内部固化的BootROM,在系统损坏时可通过Maskrom模式恢复设备。从BootROM初始化到Loader引导,再到U-Boot与内核启动,每个阶段都决定了烧录的成败。理解状态机原理,熟练使用RKDevTool、upgrade_tool等工具,能有效解决设备识别失败、烧录中断、分区表错误等常见问题。本文从基础概念出发,

weixin_33966095的博客 294

【原创】从零开始——Android 4.0 实现recovery模式,出厂设置功能

在移植recovery之前,我们需要知道为什么需要移植recovery? 1、需要实现恢复出厂设置功能 2、需要实现recovery升级功能(主要是方便用户自己定制ROM) 在移植这个recovery的时候遇到了N多的问题,没人指导,没有可供参考的书籍,只有度娘和谷歌陪伴。下面将会提到一些典型会遇到的问题。 如何进入recovery? 1、开机的时候按下组合按键 2、在

brantyou的专栏 6471

RK3288项目(一)--系统ota升级

本章来介绍下RK3288项目中的OTA升级,从uboot选择启动到磁盘读写 都会涉及

文艺小少年的博客 906

12-RK平台U-Boot启动流程

先看概述,把这一章要回答的问题摆出来,带着问题听。RK 特有的 BootROM -> MiniLoader -> SPL -> U-Boot -> Kernel。这是因为 RK 平台使用闭源的 DDR 初始化固件,需要通过 MiniLoader 来加载和运行。为什么多一层?这是 RK 平台的特殊性决定的。RK 平台使用闭源的 DDR 初始化固件,这段代码 Rockchip 不开源,只能以二进制形式提供,它需要一个载体来加载和运行,这个载体就是 MiniLoader。

内核笔记 1148

android学习第八讲:Android的一个启动过程的分析

从这章开始,我们来分析Android的一个启动过程的分析 我们首先来看一下Android的整个系统的启动分析, 首先我们得先给我们的设备通电(Powon),上完电CPU内部会有一个bootloader,这个是在生产的时候就已经烧录好了,它会根据我们的硬件GPIO的一些设置来判断我们的系统是在U盘,SD卡,或者是在内置Flash中启动,然后去引导我们的uboot,我们的uboot

寒冰 812

boot_recovery解包打包超级工具兼容海思内核rec.zip

win下工具:免费交流群:566781254。工具可解压普通安卓boot,rec。兼容海思盒子uboot格式rec解压打包(非高安),比如hi3798芯片系列的盒子,拖入一键解压,一键打包,包含keys生成工具和视频教程。玩海思盒子改私签必备工具。

基于RK3568打包TPL,SPL,UBoot镜像并运行:实战角度

结合正点原子RK3568开发板理解TPL,SPL,UBoot启动运行流程

weixin_43390831的博客 312

Uboot命令和内核启动参数的设置方法

Uboot命令和内核启动参数的设置方法 Uboot命令和内核启动参数的设置方法

手把手教你用DCA1000EVM解析IWR6843毫米波雷达数据(附MATLAB代码)

本文提供了一份详尽的实战指南,手把手教你使用DCA1000EVM采集并解析TI毫米波雷达IWR6843的原始数据。内容涵盖硬件连接配置、mmWave Studio参数设置、LVDS数据流结构解析,并附有核心MATLAB代码,详细演示了从原始二进制文件到距离-速度谱的信号处理全链路,帮助开发者快速掌握数据解析与处理的关键步骤。

terraform7cloud的博客 227

魔百盒CM201-2免拆机串口救砖:Hi3798MV300 BootROM Recovery实战

BootROM是SoC芯片上电后最先执行的固化引导程序,属于硬件级启动保障机制,不依赖外部存储与文件系统,仅需供电、时钟和基础总线通畅即可运行。其核心价值在于提供底层恢复入口,支撑UART Download Mode等调试/刷机能力,广泛应用于海思Hi3798MV300等国产TV SoC的故障修复场景。在eMMC或NAND存储损坏、U-Boot损毁、系统卡LOGO等典型启动失败情况下,通过强制触发BootROM Recovery模式,配合定制全量固件镜像与HiTool工具,可绕过损坏引导层实现裸设备级重写。

weixin_34279246的博客 242

MMSegmentation 安装教程,避免mmcv不合适版本,及相关问题解决

都行,不做要求。

qq_43683133的博客 1220

android4.4 恢复出厂设置,Android4.4.2恢复出厂设置(四)

u-Boot启动部分U-Boot启动到Linux的流程图如下所示:U-Boot启动Linux流程board_init_rU-Boot首先从u-bootarch/arm/lib/crt0.S调用u-boot/arch/arm/lib/board.c中的board_init_r开始启动,函数board_init_r的实现如下所示:void board_init_r(gd_t *id, ulong de...

weixin_34552166的博客 645

QGC二次开发实战指南(一):从零构建自定义地面站界面

本文详细介绍了QGC二次开发实战指南,从零开始构建自定义地面站界面。通过QT和QML技术结合MAVLINK协议,开发者可以打造适合特定业务场景的无人机监控系统,提升操作效率与用户体验。文章包含环境搭建、界面设计、数据绑定等完整开发流程,是QGC二次开发的实用教程。

weixin_28693683的博客 496

UNITE真菌数据库使用避坑指南:从下载到注释的完整流程

本文提供了UNITE真菌数据库从下载到注释的完整实战指南。针对真菌ITS序列分析,重点解析了数据库版本选择、格式转换的常见陷阱,并详细介绍了如何训练优化的sklearn分类器以提升物种注释的精度和可靠性,帮助用户构建高效稳定的本地工作流。

weixin_29240343的博客 200
上一篇: tftp server config on Ubuntu
下一篇: spi-norflash s25fl128s driver
lamdoc
博客等级 码龄18年 155粉丝 655原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值