引言:目的是为了弥补嵌入式设备启动过程中可能遇到的单一启动备份方案的不足之处的问题,传统的单一启动备份方案在遇到启动过程中的问题时,可能会导致系统无法正常启动,例如:系统更新失败、Loader 或 U-Boot 的软件代码出现错误或异常、Loader 或 U-Boot 部分被损坏或破坏等等情况;因此,这项功能的目的是在系统启动过程中,通过同时使用两个备份的 Loader 和 U-Boot,以提供更高的容错性和可靠性。当一个备份出现问题时,系统可以无缝地切换到另一个备份,确保系统能够顺利启动,并尽可能减少对系统正常运行的影响。
功能方案设计拆分为两部分,loader以及uboot修改,对于备份分区的新增还需考虑到dtsi的更迭,需要掌握嵌入式系统启动流程、loader、uboot使用(模式,命令)、固件更新操作流程、内存映射、设备树、设备和存储管理、DEBUG调试能力。
我们设计流程前提是已知如下启动流程。
系统启动
│
├─> Loader 阶段
│ │
│ ├─> 加载 FDT
│ │ ├─> 校验和验证 ──> 成功 ──> 继续
│ │ └─> 失败 ──> 尝试从备份加载
│ │
│ ├─> 加载 ATF
│ │ ├─> 校验和验证 ──> 成功 ──> 继续
│ │ └─> 失败 ──> 尝试从备份加载
│ │
│ └─> 加载 U-Boot
│ ├─> 校验和验证 ──> 成功 ──> U-Boot启动
│ └─> 失败 ──> 尝试从备份加载
│
└─> U-Boot 阶段
│
├─> 加载 Kernel
│ ├─> 校验和验证 ──> 成功 ──> 继续
│ └─> 失败 ──> 尝试从备份加载
│
└─> 加载 RootFS
├─> 校验和验证 ──> 成功 ──> 启动 Kernel
└─> 失败 ──> 尝试从备份加载
一、新增备份分区
在nand位置的dtsi新增分区,以及分区的dtsi,如下所示,其中注意update也需要一同更新。
partition_ubootbk { label = "ubootbk"; reg = <0x0 0x800000 0x0 0x1C0000>; };
partition_kernelbk { label = "kernelbk"; reg = <0x0 0x9C0000 0x0 0x0500000>; };
id6 { partition_name = "kernel"; source_file = "Image.bin"; };
id7 { partition_name = "ubootbk"; source_file = "u-boot.bin"; };
二、loader/uboot修改
只需要在想要err处或者checksum处进行切换即可,大致流程可以参考通过dtsi设备进行别名映射切换的方式,以及cmd命令,还有bootargs的状态去调试,即可成功切换。