RK3588 recovery模式和misc分区介绍
好的,我理解你的背景,你熟悉 STM32 的双 APP + Bootloader 的升级模式,所以我会把你熟悉的概念作为类比,教科书式、系统地给你讲解你这段话里的知识点,同时强调和 STM32 场景的异同,让你能完全理解。我们逐句拆解。
原文段落
Recovery 模式是在设备上多⼀个Recovery分区,该分区由kernel+resource+ramdisk 组成,主要⽤于升级操 作。
1️⃣ Recovery 分区是什么
概念:
在嵌入式 Linux 或安卓设备中,为了系统升级的安全性,通常会在存储器(eMMC、NAND、SD)上保留一个独立的区域叫 Recovery 分区。它与正常系统分区(System/Rootfs)是隔离的。
组成:
- kernel:Recovery 自己的内核,不依赖主系统内核。
- resource:升级所需的资源文件,例如升级包、校验文件、脚本等。
- ramdisk:临时文件系统,挂载在内存中,提供 Recovery 运行所需的基本环境(命令行工具、脚本、驱动等)。
类比 STM32 双 APP 场景:
- STM32 的 bootloader + 双 APP:bootloader 相当于 Recovery 分区,它独立于 APP,负责安全升级和引导。
- Recovery 分区就是一个独立的“bootloader”环境,但功能更强,能跑 Linux 内核,可以处理大文件系统操作和复杂升级逻辑。
u-boot会根据misc分区(详⻅misc 分区章节)存放的字段来判断将要引导的系统是Normal 系统还是 Recovery 系统。
2️⃣ misc 分区和启动选择
概念:
- misc 分区是一个小分区,用于存储设备状态和启动标志。
- 启动时,u-boot(类似 STM32 的 bootloader)会读 misc 分区的特定字段来决定启动哪个系统。
字段举例:
boot_mode = normal
→ 正常启动系统(System 分区)boot_mode = recovery
→ 启动 Recovery 分区
类比 STM32 双 APP:
- 在 STM32,你可能有一个标志位(flash 某个地址)指示 bootloader 启动 APP1 还是 APP2。
- Linux 设备用 misc 分区做类似事情:标志系统进入升级模式或者正常模式。
关键点:
- 这样设计可以在系统异常、升级失败或断电情况下,保证设备能进入 Recovery,避免设备变砖。
- 对应 STM32,如果 APP1 升级失败,你的 bootloader 可以判断并尝试从 APP2 或保留的安全区域启动。
由于系统的独⽴性,所以Recovery模式能保证升级的完整性,即升级过程被中断,如异 常掉电,升级仍然能继续执⾏。
3️⃣ 升级完整性与独立性
概念:
- 独立性:Recovery 模式独立于正常系统,运行在自己的内核和文件系统环境下,不依赖主系统。
- 完整性保障:升级过程发生中断(掉电、异常重启),Recovery 可以在下次启动时继续升级。
实现方式:
- 升级包写入临时区域(ramdisk 或特殊分区)。
- 写入前进行校验(CRC、签名)。
- 写入主系统分区时,如果掉电,Recovery 可以重新读取升级包继续写。
类比 STM32 双 APP 升级:
-
STM32 bootloader 升级 APP1:
- 如果升级中断,bootloader 下次上电时可以检查 APP1 的完整性(例如 CRC 或标志位)并重新升级。
-
Recovery 的机制更复杂:
- 内核可以管理文件系统(ext4、F2FS 等)
- 可以处理大文件升级
- 可用脚本逻辑处理失败恢复
🔑 总结对比 STM32
概念 | STM32 例子 | Linux Recovery / u-boot |
---|---|---|
独立启动环境 | bootloader | Recovery 分区 kernel+ramdisk |
系统选择标志 | flash 某地址标记 APP1/APP2 | misc 分区 boot_mode 字段 |
升级安全机制 | 升级前 CRC 校验,异常回退 | 升级前校验+脚本控制,可断点续传 |
分区设计 | Bootloader + 双 APP | Recovery + System + misc |
✅ 教科书式理解要点:
- Recovery 分区本质是一个“独立 bootloader”,但功能更强,跑 Linux 内核。
- misc 分区是启动标志存储区,类似 STM32 的 flash 标志位。
- Recovery 的独立性保证了升级的安全性和完整性。
- 设计思想和 STM32 双 APP + bootloader 一致,只是实现复杂度更高,适用于 Linux/安卓环境。
如果你愿意,我可以帮你画一个 STM32 双 APP 与 Linux Recovery 对比示意图,把启动流程、分区和升级逻辑直观地展示出来,让你一眼就理解两者的对应关系。
你希望我画吗?
好,那我帮你画一个 STM32 双 APP 升级 与 Linux Recovery 升级 的启动流程 & 分区结构对比示意图,让你一眼看懂它们的对应关系。
启动流程对比
┌─────────────────────── STM32 双 APP ────────────────────────┐
上电│▼
[ Bootloader ] ← 固定在 Flash 前14KB│ 读取标志位(Flash某地址)│├─ 标志位=APP1 → 跳转到 APP1 区│└─ 标志位=APP2 → 跳转到 APP2 区│└─ APP 运行│└─ 检测到升级 → 下载到备用 APP 区│└─ 升级完成 → 修改标志位 → 重启
┌────────────────────── Linux u-boot + Recovery ───────────────────────┐
上电│▼
[ BootROM ] ← SoC 固化启动代码(不可修改)│▼
[ u-boot (Bootloader) ]│ 读取 misc 分区标志│├─ boot_mode=normal → 启动 active_slot 对应的 Normal 系统│└─ boot_mode=recovery → 启动 Recovery 分区│└─ Recovery 运行(迷你Linux)│└─ 校验/写入备用系统分区│└─ 升级完成 → 修改 misc → 重启
分区结构对比
STM32 双 APP 模式 | Linux Recovery 升级模式 |
---|---|
Bootloader 分区(前14KB) | u-boot 分区 |
APP1 分区(主系统) | Normal 系统分区 A |
APP2 分区(备用系统) | Normal 系统分区 B |
Flash 标志位(单独区域) | misc 分区 |
(无独立升级系统) | Recovery 分区 |
对应关系表
STM32 双 APP 升级 | Linux Recovery 升级 |
---|---|
Bootloader | u-boot |
APP1 / APP2 | System 分区 A / B |
Flash 标志位地址 | misc 分区 |
Bootloader 决定跳转目标 | u-boot 决定启动目标 |
APP 自身升级另一分区 | Recovery 升级另一分区 |
我可以帮你在这张对比图的基础上,再加上 标志位(misc / Flash 地址)变化的完整时序图,这样你可以同时看到启动路径和升级状态切换的动态过程,就像你画 STM32 升级状态机一样清晰。
你要我帮你把这个时序图也加上去吗?这样就能彻底看懂了。
这个“避免变砖”的能力,其实是由 分区独立性 + 启动判断机制 两个点共同体现出来的,你从你熟悉的 STM32 升级思路去看会很清楚。
1. 分区独立性
- Recovery 分区的 kernel + ramdisk 是完全独立的,不依赖正常系统分区(system/rootfs)。
- 正常系统分区哪怕在升级中被破坏(比如写到一半掉电,文件系统损坏),Recovery 分区的内容仍然保持完好。
- 就像 STM32 里,你的 bootloader 存在前 14KB Flash,不会被升级程序覆盖,所以它一直是安全可用的。
2. 启动判断机制(misc 分区)
- u-boot 启动时,优先读取 misc 分区的启动标志,来判断是进入 normal 系统还是 Recovery 系统。
- 如果升级中断,misc 分区里仍然保持着“进入 recovery”这个标志,所以下一次上电会直接进 Recovery,而不会去启动已经损坏的正常系统。
- 对应 STM32,就是你在 bootloader 里检测标志位,如果 APP1 升级失败,就不跳到 APP1,而是进入安全模式或重新升级。
3. 升级可续传(完整性保障)
- 因为 Recovery 有自己的内核和文件系统环境,它可以检测之前的升级是否完整(比如检查临时升级包的 CRC 或签名)。
- 如果发现之前没升级完,就继续写入剩余部分,而不是重新开始。
- 这就保证了即使掉电,也不会变砖——系统至少还能进入 Recovery 再尝试一次。
📌 一句话总结体现点
体现避免变砖的地方就在于: Recovery 分区物理上独立、逻辑上独立,启动时由 misc 分区标志控制流向,即使正常系统被写坏,启动链路仍能切换到 Recovery,保证有一个“永远能跑”的环境继续升级。
如果你愿意,我可以给你画一张 带启动决策流程的分区图,把“哪里体现了避免变砖”用箭头和流程标注出来,这样你一眼就能看出来。
你要我画吗?
对,你的直觉没错——Recovery 确实有点像一个“高级 bootloader”,但是它和 u-boot 还是有明显区别的,尤其是在 运行环境、能力边界、所处位置 这几个方面。
我帮你对比一下,你就能把两者的角色完全分清。
感觉这个recover 也是个bootloader啊, 和uboot 有啥区别????
1. 定位不同
对比项 | u-boot | Recovery |
---|---|---|
位置 | 第一级引导加载器(Bootloader),在存储器前面固定区域(bootloader 分区) | 独立系统分区,存储在 eMMC / NAND 的一个单独分区 |
执行时机 | 上电后第一时间由 ROM Code 调用,负责初始化硬件并加载内核 | u-boot 决定是否进入 Recovery,然后才启动它 |
主要作用 | 初始化 CPU/DDR/外设,加载并启动内核或其他镜像 | 运行一个精简版 Linux(内核 + ramdisk),提供升级、修复等功能 |
是否能直接跑 Linux | ❌(不运行 Linux 内核,只能运行自己的小型命令环境) | ✅(自带 Linux 内核和文件系统环境) |
2. 功能范围不同
u-boot
- 初始化硬件(DDR、串口、存储、网络)。
- 解析分区表,选择启动镜像(kernel / recovery / fastboot)。
- 提供一些简易命令行(读写 flash、传文件、调试)。
- 体积小(几百 KB),不能跑完整文件系统操作。
Recovery
- 已经是一个精简版 Linux 系统(内核 + ramdisk)。
- 有文件系统挂载能力,可以操作 ext4、f2fs、vfat 等分区。
- 可以运行复杂升级逻辑(脚本、UI、USB/OTA 接收数据、解压大文件)。
- 能与用户交互(触摸屏、按键、串口、网络)。
- 体积大(几 MB),启动慢于 u-boot,但功能更全。
3. 运行链路对比
上电启动 → SoC 内部 BootROM → 加载 u-boot →
- 如果是 normal 模式 → u-boot 加载正常系统内核
- 如果是 recovery 模式 → u-boot 加载 recovery 内核 + ramdisk → 进入 recovery 环境
类比 STM32 双 APP:
- BootROM = STM32 的固化启动代码(不可改)
- u-boot = 你写的 Bootloader
- Recovery = 一个独立的 APP,但它不是业务 APP,而是专门负责升级/修复的 APP
4. 为什么看起来像 bootloader
你会觉得 Recovery 像 bootloader,是因为:
- 它也是独立运行环境
- 它也能在主系统坏了时启动
- 它的主要用途也是保证安全启动 & 升级
但本质区别是:
- u-boot 是“启动加载器”(loader):它自己不跑 Linux,只负责把别人拉起来。
- Recovery 是“备用的迷你 Linux 系统”:它由 u-boot 启动,可以独立运行复杂逻辑。
5. 一句话记忆法
u-boot 决定谁能上场,Recovery 是替补队员,Normal 系统是主力队员。
如果主力(Normal 系统)受伤了,替补(Recovery)能立刻上场接手比赛,但裁判(u-boot)必须先安排它上场。
如果你愿意,我可以帮你画一个 启动链路图,把 BootROM → u-boot → Recovery / Normal 系统的关系画成图,让你一眼就明白为什么 Recovery 像 bootloader,但又比 bootloader 高一级。
你要我画吗?
MISC 分区简介
你理解得很对,misc 就是一个单独的 Flash 分区,核心用途就是存放“启动模式”和“当前运行系统”等标志位。
但谁来读写它,要分成 启动前 和 系统运行时 两个阶段来看。
1. 启动前(上电后) → 谁去读 misc
?
读的是 u-boot
-
上电后 SoC 的 BootROM 会先加载 u-boot(bootloader)。
-
u-boot 启动时会读取
misc
分区的特定字段(例如boot_mode
、active_slot
等)。 -
根据字段值,u-boot 决定:
- 启动 Normal 系统(正常内核)
- 启动 Recovery 系统(recovery 分区内核)
- 启动 Fastboot / 升级模式
-
这个逻辑就和你 STM32 bootloader 先检查 flash 某个地址标志位、决定跳转 APP1 还是 APP2 是一个意思。
2. 系统运行时 → 谁去写 misc
?
主要是 运行中的系统(Normal 系统或者 Recovery 系统) 写
-
当你在正常系统里发起升级时:
- APP(或升级服务)会把
boot_mode
改成recovery
- 有时候还会写
slot_b
为 active(双系统/AB 分区机制)
- APP(或升级服务)会把
-
当升级完成(比如 APP2 写成功并校验通过):
- Recovery 会把
boot_mode
改回normal
- 更新
active_slot
为新系统
- Recovery 会把
-
这一步 u-boot 本身不会主动写(它只是读),而是由系统或 recovery 的升级程序去写。
3. 流程举例(类比 STM32 双 APP)
假设是 双系统升级(A/B 分区):
- Normal 系统 运行时,检测到有新固件 → 下载到 B 分区。
- 写
misc.boot_mode = recovery
,misc.active_slot = B
。 - 重启 → u-boot 读到 boot_mode=recovery → 启动 Recovery。
- Recovery 校验 B 分区固件 → 校验成功则写回
boot_mode=normal
并设置 active_slot = B。 - 下次重启 → u-boot 发现 boot_mode=normal → 从 B 分区启动新系统。
4. 对应到你的话
- 升级标志位、当前运行 APP 标志位 → 存在 misc 分区
- 读 → u-boot 在启动早期读
- 写 → 运行的系统(Normal / Recovery)写
- u-boot 本身通常不写,只是根据标志决定启动路径
如果你愿意,我可以帮你画一个 “misc 分区读写时序图”,把 Normal / Recovery / u-boot 在什么时候读、什么时候写标志位用时序关系画出来,你就能一眼看清它的作用链路了。
你要我画吗?这样能把“谁读谁写”彻底搞清楚。
好,那我帮你画一个 misc 分区读写时序图,让你直观看出 Normal 系统、Recovery 系统 和 u-boot 在升级流程中对 misc
分区的读写关系。
misc 分区读写时序(A/B 双系统举例)
┌─────────────────────────────────────────────────────────────┐
│ 正常运行(Normal 系统 A 分区) │
│ │
│ 1. 用户发起升级指令 │
│ 2. 系统下载固件到 B 分区(未运行的分区) │
│ 3. 系统写 misc: │
│ boot_mode = recovery │
│ active_slot = B │
│ 4. 系统重启 │
└─────────────────────────────────────────────────────────────┘│▼
───────────────────────────────────────────────────────────────上电 → BootROM → u-boot 启动阶段
───────────────────────────────────────────────────────────────u-boot:- 读取 misc.boot_mode- 如果是 "recovery" → 加载 recovery 分区 kernel+ramdisk- 如果是 "normal" → 启动 active_slot 对应的系统│▼
───────────────────────────────────────────────────────────────Recovery 系统运行(独立环境)
───────────────────────────────────────────────────────────────Recovery:- 校验 B 分区固件- 写入 B 分区到 active_slot- 校验成功:misc.boot_mode = normalmisc.active_slot = B- 校验失败:misc.boot_mode = normalmisc.active_slot = A (回退)- 重启│▼
───────────────────────────────────────────────────────────────上电 → BootROM → u-boot(再次启动)
───────────────────────────────────────────────────────────────u-boot:- 读取 misc.boot_mode = normal- 读取 misc.active_slot = B- 启动 B 分区(新系统)
核心要点
-
u-boot 只读,不写
- 它根据 misc 的标志来决定启动 normal 还是 recovery。
-
写 misc 的是运行中的系统(Normal 或 Recovery)
- Normal 系统写 “我要升级”
- Recovery 写 “升级完成/回退”
-
Recovery 是升级执行环境
- 它有能力操作分区、解压、校验固件
-
misc 像 STM32 的“跳转标志地址”
- 只是它在 Linux/Android 里是一个单独的分区文件(/dev/block/by-name/misc)
如果你愿意,我还能帮你画一张 STM32 双 APP + Bootloader 和 Linux u-boot + Recovery 的对照图,让你直观看到它们概念上的一一对应。这样你以后看 Android/Linux 升级机制就能秒懂。
你要我画吗?这样会非常直观。
好,那我帮你画一张 STM32 双 APP + Bootloader 和 Linux u-boot + Recovery 的对照图,
把它们的分区结构、启动流程、标志位作用一一对应起来。
对照示意图
┌──────────────────────────────────────────────────────────────────────┐
│ STM32 双 APP 升级结构 │
├───────────────┬─────────────────────────────────────────────────────┤
│ Bootloader │ 固定在 Flash 前 14KB │
│ │ - 上电启动 │
│ │ - 读标志位(Flash 某地址) │
│ │ - 决定跳转 APP1 还是 APP2 │
├───────────────┼─────────────────────────────────────────────────────┤
│ APP1 分区 │ 主运行应用 │
│ │ - 正常工作 │
│ │ - 检测有新固件 → 下载到 APP2 区域 │
│ │ - 写标志位:下次启动从 APP2 启动 │
├───────────────┼─────────────────────────────────────────────────────┤
│ APP2 分区 │ 备用应用 │
│ │ - 升级中写入 │
│ │ - 升级完成后替代 APP1 成为新主系统 │
├───────────────┼─────────────────────────────────────────────────────┤
│ 标志位区域 │ Flash 某个地址(例如 0x08003C00) │
│ │ - 当前运行 APP 标志 │
│ │ - 升级状态标志 │
└───────────────┴─────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────────────┐
│ Linux u-boot + Recovery 升级结构 │
├───────────────┬─────────────────────────────────────────────────────┤
│ BootROM │ SoC 固化在芯片内的启动代码 │
│ │ - 上电运行 │
│ │ - 加载 u-boot 到内存 │
├───────────────┼─────────────────────────────────────────────────────┤
│ u-boot │ 存在于 bootloader 分区 │
│ │ - 读 misc 分区标志 │
│ │ - 决定启动 normal 系统还是 recovery 系统 │
├───────────────┼─────────────────────────────────────────────────────┤
│ normal 系统 │ 主运行系统(内核 + rootfs) │
│ │ - 正常工作 │
│ │ - 检测有新固件 → 下载到备用系统分区(B) │
│ │ - 写 misc:boot_mode=recovery,active_slot=B │
├───────────────┼─────────────────────────────────────────────────────┤
│ recovery 分区 │ 独立 Linux(内核 + ramdisk) │
│ │ - 启动后负责执行升级 │
│ │ - 校验固件 → 成功则修改 misc 为 normal 并切换 slot │
├───────────────┼─────────────────────────────────────────────────────┤
│ misc 分区 │ 存放启动模式和当前活动系统标志 │
│ │ - boot_mode: normal / recovery │
│ │ - active_slot: A / B │
└───────────────┴─────────────────────────────────────────────────────┘
关键对应关系表
STM32 双 APP 升级 | Linux u-boot + Recovery 升级 |
---|---|
Bootloader (前 14KB) | u-boot 分区 |
APP1 / APP2 | normal 系统分区 A / B |
Flash 标志位地址 | misc 分区 |
Bootloader 读标志位跳转 | u-boot 读 misc 选择启动系统 |
Bootloader 也能升级 | Recovery 专职升级 |
APP 负责写标志位 | normal / recovery 系统写 misc |
一眼结论
- u-boot ≈ STM32 Bootloader(决定跳哪去)
- Recovery ≈ 一个专用的升级 APP(独立系统环境)
- misc 分区 ≈ STM32 的标志位存储地址
- A/B 分区机制 ≈ STM32 双 APP 升级思路
我可以在这个图的基础上,再帮你画一个 Linux 升级中 misc 分区标志变化流程图,让你看到每次写标志、读标志是在哪个阶段发生的,这样启动和升级逻辑就彻底搞透。
你要我画这个流程图吗?这样就能把“谁读谁写”一眼看清。
个人总结理解:
- recovery :就是个专用来升级的app(进入这个就可以升级其他app ),单独放在falsh一个分区的,跟uboot ,kernel,rootfs 是独立的 ,负责升级启动不同的app
- misc:就是个单独的flash分区,存储app升级标志位,以及当前运行的app标志位,升级app2成功了 就把app2标志位置位,然后uboot启动时候 读取判断misc分区标志位运行哪个app? 以及recover 或者其他升级完了 再改写misc分区的升级标志位