瑞芯微Cortex-A7系列芯片u-boot补丁,引导鸿蒙内核liteos.bin 精华
鸿蒙系统已开源不久,网上关于鸿蒙移植到第三方芯片的相关资料较少,把自己移植的步骤陆续分享给大家 。
手上的几个Rockchip系列芯片做了移植,在rv1126,rk3126c,rk3288几颗芯片跑了liteos的最小系统。
这篇文章先教大家如何修改uboot引导鸿蒙内核liteos.bin
1.烧写工具修改与配置。
瑞芯微原厂提供的烧写工具可对Android固件和Linux固件的烧写。修改工具添加liteos和rootfs两个分区。用来烧写鸿蒙的liteos.bin内核,rootfs.img。
右键点击瑞芯微烧写工具,选择导入配置选择我已经修改好的cfg文件。
工具显示的几个分区loader,uboot,liteos,rootfs会根据parameter分区所指定的parameter.txt文件更新实际的分区地址。
接下来配置下希望固件烧写在设备上存储的对应位置和分区大小。
我们打开看下rk3288原厂的Android配置文件parameter.txt
FIRMWARE_VER: 8.1
MACHINE_MODEL:rk3288
MACHINE_ID:007
MANUFACTURER:RK3288
MAGIC: 0x5041524B
ATAG: 0x00200800
MACHINE: 3288
CHECK_MASK: 0x80
PWR_HLD: 0,0,A,0,1
TYPE: GPT
CMDLINE: mtdparts=rk29xxnand:0x00002000@0x00004000(uboot),0x00002000@0x00006000(trust),0x00002000@0x00008000(misc),0x00010000@0x0000a000(liteos),0x00020000@0x0001a000(recovery),0x00010000@0x0002a000(backup),0x00020000@0x0003a000(oem),0x00010000@0x0005a000(rootfs),-@0x0015a000(userdata:grow)
uuid:rootfs=614e0000-0000-4b53-8000-1d28000054a9
指出的标红部分是我做的修改。
0x00010000@0x0000a000(liteos)
@符号左边10000指分区的大小(以块为单位512),a000指分区其实位置,(liteos)指分区名称。
在这里分区大小和分区起始地址保持默认的,将分区名字从原来的kernel改成了liteos.
0x00010000@0x0005a000(rootfs)
这边也将原来的分区名称system改成了rootfs,并把原来的分区大小改成了10000.
分区的大小可自己随便修改。分区大小以块为单位,每块大小是512。可对分区大小进行换算,计算出实际可存储空间,把10000十六进制转换成10进制
0x00010000 转十进制65536 ,乘上块大小512 再转换成M位单位,实际存储空间是32M
(65536 * 512)/1024/1024 = 32M
上面配置文件可知liteos和rootfs分区各分配了32M用来存放固件,大家可根据需求修改.重新配置删除不需要的分区
2.修改u-boot 引导liteos.bin。
liteos.bin可通过go命令+litesos.bin文件在内存中对应的内存地址进行启动。
如:go x01000000
前面烧写的固件被存放到0x0000a000(liteos)分区大小为0x00010000
我们需要将liteos和rootfs这两个个分区的数据读到物理内存。
对u-boot进行修改,添加两个u-boot环境变量,用于指定分区存放的物理内存位置
diff --git a/include/configs/rk3288_common.h b/include/configs/rk3288_common.h
index 35aff11851..b5436a2c76 100644
--- a/include/configs/rk3288_common.h
+++ b/include/configs/rk3288_common.h
"pxefile_addr_r=0x00100000\0" \
"fdt_addr_r=0x08300000\0" \
"kernel_addr_r=0x02008000\0" \
+ "liteos=x01000000\0" \
+ "rootfs=0x40000000\0" \
"ramdisk_addr_r=0x0a200000\0"
#include <config_distro_bootcmd.h>
把 liteos和rootfs分别放到物理内存x01000000和0x40000000。
打开cmd/bootrkp.c文件修改拷贝分区,并执行go命令
U_BOOT_CMD(
bootrkp, 1, 1, do_boot_rockchip,
"Boot Linux Image from rockchip image type",
"kernel.img: zImage/Image\n"
"boot.img: ramdisk\n"
"resource.img: dtb, u-boot logo, kernel logo"
);
找到uoboot启动命令bootrkp对应方的法
static int do_boot_rockchip(cmd_tbl_t *cmdtp, int flag,
int argc, char *const argv[])
{
char *part_name = "rootfs";
struct blk_desc *dev_desc;
disk_partition_t part;
int ret;
dev_desc = rockchip_get_bootdev();
if (!dev_desc) {
printf("dev_desc is NULL!\n");
return CMD_RET_FAILURE;
}
ret = part_get_info_by_name(dev_desc, part_name, &part);
if (ret < 0) {
printf("Could not find %s part\n", part.name);
return CMD_RET_FAILURE;
}
return boot_rockchip_image(dev_desc, &part) ? CMD_RET_FAILURE : 0;
}
static int boot_rockchip_image(struct blk_desc *dev_desc,
disk_partition_t *boot_part)
{
disk_partition_t kernel_part;
ulong ramdisk_addr_r;
ulong kernel_addr_r;
int ramdisk_size;
int kernel_size;
int ret;
printf("\n## Booting Rockchip Format Image\n");
ramdisk_addr_r = env_get_ulong("rootfs", 16, 0);//获取存放rootfs的实际内存地址
kernel_addr_r = env_get_ulong("liteos", 16, 0);//获取存放liteos的实际内存地址
ret = part_get_info_by_name(dev_desc, "liteos", &kernel_part);//获取liteos分区
if (ret < 0) {
printf("Could not find kernel partition, ret=%d\n", ret);
return -EINVAL;
}
kernel_size = read_rockchip_image(dev_desc, &kernel_part,
(void *)kernel_addr_r);//将liteos分区读到物理内存
if (kernel_size < 0) {
printf("Failed to read kernel image, ret=%d\n", ret);
return -EINVAL;
}
printf("%s_size:0x%x\n",kernel_part.name,kernel_size);
ramdisk_size = read_rockchip_image(dev_desc, boot_part,
(void *)ramdisk_addr_r);//将rootfs分区数据读到物理内存
if (ramdisk_size < 0)
ramdisk_size = 0;
printf("%s_size:0x%x\n",boot_part->name,ramdisk_size);
printf("%s @ 0x%08lx (0x%08x)\n", kernel_part.name,kernel_addr_r, kernel_size);
printf("%s @ 0x%08lx (0x%08x)\n", boot_part->name,ramdisk_addr_r, ramdisk_size);
char fit_addr[12];
char localcmd[100] = {0};
snprintf(fit_addr, sizeof(fit_addr), "0x%lx", (ulong)kernel_addr_r);
sprintf(localcmd,"md.b 0x%08lx 10;md.b 0x%08lx 10; go 0x%08lx",kernel_addr_r,ramdisk_addr_r,kernel_addr_r);//用md.b命令用来打印打印指定内存起始的10个单位的数据,方便确认数据。
printf("exec:%s\n",localcmd);
run_command_list(localcmd, strlen(localcmd), 0);//执行命令
return 0;
}
修改include/configs/rockchip-common.h文件,将bootrkp命令放到前面执行,删除用不上的Android启动命令。
diff --git a/include/configs/rockchip-common.h b/include/configs/rockchip-common.h
index 4103342d42..1a15df7e14 100644
--- a/include/configs/rockchip-common.h
+++ b/include/configs/rockchip-common.h
@@ -144,7 +144,6 @@
"boot_android ${devtype} ${devnum};"
#else
#define RKIMG_BOOTCOMMAND \
- "boot_android ${devtype} ${devnum};" \
"bootrkp;" \
"run distro_bootcmd;"
#endif
接着重新编译u-boot
u-boot$ ./make.sh rk3288
烧写固件启动:
致此,我们的u-boot代码已修改完成,u-boot支持启动烧写到存储设备上的liteos.bin了。
u-boot代码和烧写工具可在 github获取:
https://github.com/rockchip-linux/u-boot.git
https://github.com/rockchip-linux/tools/tree/master/windows/RKDevTool/RKDevTool_Release
完整的u-boot补丁可在附件下载
好东西啊。。。。。。。。。。。
膜拜大佬,求教一下rv1108可以移植liteOS_a版本的鸿蒙吗
rv1108可以移植, 对着芯片手册修改mmu内存映射,uart串口启动,具体移植方法参考韦东山的视频课程