8541E-A90 bootloader部分适配鸿蒙升级逻辑之代码解读

与鸿蒙有缘
发布于 2022-5-5 09:42
浏览
0收藏

一、方案拟定

8541E-A90 bootloader部分适配鸿蒙升级逻辑之代码解读-鸿蒙开发者社区
通过修改uboot的启动参数即挂载的分区节点,确定启动主系统还是recovery系统。从而实现通过同一个uboot、同一个kernel启动两个分区的目的,并通过misc分区保存数据实现分区的自由切换。

二、代码逻辑修改

2.1、涉及的代码文件

device/kaihong/8541e/common/bsp/bootloader/u-boot15/common/loader/recv_mode.c
device/kaihong/8541e/common/bsp/bootloader/u-boot15/common/cmd_cboot.c
device/kaihong/8541e/common/bsp/bootloader/u-boot15/common/loader/sprd_fdt_support.c
device/kaihong/8541e/common/bsp/bootloader/u-boot15/include/boot_mode.h

2.2、代码逻辑实现

2.2.1 misc分区结构体适配

**Tips:**标‘*’部分是改动行,其中注掉的部分是原始的代码,没有注掉的为新增的代码
vi device/kaihong/8541e/common/bsp/bootloader/u-boot15/common/loader/recv_mode.c

 1 #include <common.h>
  2 #include <boot_mode.h>
  3 #include <part_efi.h>
  4 #include "loader_common.h"
  5 #include <sprd_common_rw.h>
  6 

*   7 int is_recovery = 0;     //定义启动recovery分区的flag

  8 extern void reboot_devices(unsigned reboot_mode);
  9 
 10 /* Recovery Message */

*  11 // struct recovery_message {    
*  12 //  char command[32];
*  13 //  char status[32];
*  14 //  char recovery[1024];
*  15 // };
*  16 struct recovery_message {
*  17     char command[20];
*  18     char update[100];
*  19 };
* 

 20 int get_recovery_message(struct recovery_message *out)
 21 {
 ......
79 int get_mode_from_file(void)
 80 {
 81     debugf("!!!!!!!!!! %s:%d entry\n", __FUNCTION__, __LINE__);
 82     struct recovery_message msg;
 83     char partition_name[32];
 84     unsigned valid_command = 0;
 85 
 86     /*get recovery message */
 87     if (get_recovery_message(&msg)) {
 89         return CMD_UNKNOW_REBOOT_MODE;
 90     }
 91     if (msg.command[0] != 0 && msg.command[0] != 255) {
 92         debugf("Recovery command: %.*s\n", sizeof(msg.command), msg.command);
 93     }
 94     /*Ensure termination */
 95     msg.command[sizeof(msg.command) - 1] = '\0';

*  96     //if (!strcmp("boot-recovery", msg.command)) {
*  97     if (!strcmp("boot_updater", msg.command)) {  //和鸿蒙的填充内容保持一致
*  98         is_recovery = 1;   //flag赋值1

 99         debugf("%s:Message in misc indicate the RECOVERY MODE is_recovery = %d\n", __FUNCTION__, is_recovery);
100         return CMD_RECOVERY_MODE;
101     } else if (!strcmp("update-radio", msg.command)) {

* 102         // strcpy(msg.status, "OKAY");
* 103        // strcpy(msg.command, "boot-recovery");
* 104         strcpy(msg.command, "boot_updater");

105         /*send recovery message */
106         set_recovery_message(&msg);
107         reboot_devices(0);
108         return CMD_UNKNOW_REBOOT_MODE;
109     } else {
110         return 0;
111     }
112 }
113 /* set recovery message to boot fastbootd */
114 int set_recovery_run_fastbootd(void)
115 {
116     struct recovery_message msg = {0};
117 
118     strcpy(msg.command, "boot-fastboot");
* 119     strcpy(msg.update, "recovery\n");
* 120     strcpy(msg.update, "--fastboot\n");
121 
122     set_recovery_message(&msg);
123     return 0;
124 }
125 
126 /* clear recovery message for boot fastbootd */
127 int clear_recovery_not_run_fastbootd(void)
128 {
129     struct recovery_message msg = {0};
130 
* 131     strcpy(msg.command, "boot_updater");
* 132     strcpy(msg.update, "recovery\n");
133 
134     set_recovery_message(&msg);
135     return 0 ;

vi device/kaihong/8541e/common/bsp/bootloader/u-boot15/include/boot_mode.h

......
 97     do{\
 98             array[index]  = fun;\
 99         }while(0)
100 
* 101 extern int is_recovery;  //把flag在头文件里声明,方便其他文件访问
102 int get_mode_from_file(void);
103 int set_recovery_run_fastbootd(void);
104 int clear_recovery_not_run_fastbootd(
......

2.2.1 修改启动方式

vi device/kaihong/8541e/common/bsp/bootloader/u-boot15/common/cmd_cboot.c

151 /*1 get mode from file, just for recovery mode now*/
152 boot_mode_enum_type get_mode_from_file_extend(void)
153 {
154     debugf("!!!!!!!!!!!!!!!!!! %s:%d entry\n", __FUNCTION__, __LINE__);
155     switch (get_mode_from_file()) {
156         case CMD_RECOVERY_MODE:
157             debugf("cboot:get mode from file:recovery, is_recovery = %d\n", is_recovery);

* 158             // return CMD_RECOVERY_MODE;
* 159             return CMD_NORMAL_MODE;    //均按照主分区的方式启动

160         default:
161             debugf("!!!!!!!!!!!!!!!!!! %s:%d CMD_UNDEFINED_MODE", __FUNCTION__, __LINE__);
162             return CMD_UNDEFINED_MODE;
163     }
164     debugf("!!!!!!!!!!!!!!!!!! %s:%d CMD_UNDEFINED_MODE", __FUNCTION__, __LINE__);
165     return CMD_UNDEFINED_MODE;
166 }

2.2.2 适配分区的挂载节点

vi device/kaihong/8541e/common/bsp/bootloader/u-boot15/common/loader/sprd_fdt_support.c

1651 int fdt_fixup_system_mount_part_num(void *fdt)
1652 {
1653     int ret = 0;
1654 
1655 #ifndef CONFIG_NAND_BOOT
1656     if (gd->boot_device == BOOT_DEVICE_EMMC) {
1657         unsigned int num;
1658         int nodeoffset;
1659         const char *path;
1660         char buf[128];
1661         int str_len;
1662 
1663         char *path_copy, *s, *v, *v_copy, *k;
1664        //get_img_partition_id("system", &num);
* 1664         if(is_recovery) {      //挂载主分区还是recovery分区,为填充启动参数做准备
* 1665             get_img_partition_id("recovery", &num);
* 1666         } else {
* 1667             get_img_partition_id("system", &num);
* 1668         }

1669         memset(buf, 0, sizeof(buf));
1670 
1671         /* Find the "chosen" node */
1672         nodeoffset = fdt_path_offset(fdt, "/chosen");
1673         /* If there is no "chosen" node in the blob, leave */
1674         if (nodeoffset < 0) {
1675             errorf("fdt_chosen_bootargs_replace: cann't find chosen");
1676             return -1;
1677         }

三、切换分区的命令

**1、**在主分区命令行执行 reboot updater可以切换到recovery分区
**2、**在recovery分区执行 updater_reboot 可以切换到主分区,但是由于recovery分区的串口无法输入,目前无法执行该命令。
以上两种方式均是通过修改misc分区来实现分区切换,现提供hi3516dv300的misc分区的数据结构如下:
8541E-A90 bootloader部分适配鸿蒙升级逻辑之代码解读-鸿蒙开发者社区

2
收藏
回复
举报
回复
    相关推荐