移植OpenHarmony轻量系统【4】启动文件与链接 原创 精华

连志安
发布于 2022-2-9 17:58
浏览
3收藏

摘要:本文简单介绍OpenHarmony轻量系统移植,启动文件和链接
适合群体:想自己动手移植OpenHarmony轻量系统的朋友

上一节我们已经实现了大部分代码,现在我们需要实现启动文件和最终链接成可烧录到开发板的文件。

4.1 ARM芯片移植轻量系统基础知识

在做芯片移植工作之前,我们需要掌握一点点基础知识。

(1)适配LiteOS-M轻量系统

GD32F303系列器件是基于Arm® Cortex®-M4处理器的32位通用微控制器。所以我们使用的是内核是LiteOS-M,对应的是OpenHarmony轻量系统。
事实上,OpenHarmony已经做好了Cortex®-M4 核相关的通用移植工作,具体代码可以查看文件夹:“kernel\liteos_m\kernel\arch\arm”
可以看到目前已经支持了cortex-m4核。所以内核移植工作基本不需要,减少了我们很多工作量,但是我们仍然需要移植GD32F303芯片相关的。
移植OpenHarmony轻量系统【4】启动文件与链接-鸿蒙开发者社区

(2)哈佛架构

GD32F303采用的是哈佛架构,哈佛架构的特点是代码指令和数据分开存储。对于GD32F303而言,代码是存放在片内flash上,地址是0x8000000。
数据(也就是代码中用到的各种变量、内存等)是存放在芯片内部内存RAM上,地址是0x20000000,总共64K,即0x10000。
移植OpenHarmony轻量系统【4】启动文件与链接-鸿蒙开发者社区

(3)编译结果分析

对于GD32F303而言,编译出来的固件一般是bin格式、或者hex格式。通常编译最后的结果会产生4种不同的内容,有时我们也称为4段:
1)code:即程序代码部分,该内容由所有程序指令组成,也是代码运行的主体,通常是要烧录到GD32F303片内flash上。
2)RO-data:只读数据段,例如我们在程序中所定义的全局常量数据和字符串都位于此处。由于这些数据都是只读,不会改变的,那这些只读的全局就没必要放到内存种,可以直接放到flash中,可以节省内存。
3)RW-data:已初始化的读写数据,程序中定义并且初始化的全局变量和静态变量位于此处。由于内存刚上电后,内存上的数据是未知,所以我们需要事先把这些全局变量、静态变量的初始值先存放到flash中,然后上电后,由CPU将flash中的初始值赋予到内存中的变量中。
4)ZI-data:未初始化的全局变量或者初始化为0的全局变量,这些变量默认都是0,我们只需要CPU上电后,将这些内存都清零即可。

由上我们可以的出来2个结论:
1)我们编译出来的固件要烧录到GD32F303的片内flash,需要由3段数据:code、RO-data、RW-data
移植OpenHarmony轻量系统【4】启动文件与链接-鸿蒙开发者社区
2)芯片上电后,GD32F303需要将RW-data的内容复制到内存对应位置,从而保证初始化的全局变量和静态变量的值正确;还要对内存中的ZI-data段进行清零操作,最后才能执行main函数。

(4)程序如何启动

对于ARM Cortex-M系列的芯片而言,当芯片上电后,ARM核会将地址为0x8000000的数据映射到0地址,然后从0地址开始读取程序指令。
而0x8000000地址是芯片内部flash的起始地址。也就是编译生成的固件最终要烧录到的地址。所以我们的固件前面的代码非常重要,它是我们芯片启动后执行的第一条指令。

(5)中断向量表

对于ARM Cortex-M系列的芯片而言,0x8000000地址第一个字节是栈指针,由于栈是从高往下增长的,所以该栈指向芯片最大内存处即可。
接下来从0x8000000的第2个字节开始是中断向量表,存放着所有中断处理函数指针。前面16个是内核中断,其中第一个中断指针存放的是Reset_Handler复位中断处理函数。芯片一上电、或者复位,都会先从该中断函数开始运行,所以这个函数是我们最重要的,我们需要在该函数中完成RW-data、ZI-data数据的操作,同时初始化好芯片时钟、最后进入main函数。
移植OpenHarmony轻量系统【4】启动文件与链接-鸿蒙开发者社区

4.2 启动文件

这里我将启动文件放到这个路径下:
device\board\lianzhian\gd32f303_lianzhian\sdk\startup_gd32f30x.s
这样的话方便不同的开发板可以自己定义自己的启动文件。
启动文件startup_gd32f30x.s 。最重要的是将RW-data的内容复制到内存对应位置,从而保证初始化的全局变量和静态变量的值正确;还要对内存中的ZI-data段进行清零操作,最后才能执行main函数。
代码都是汇编,参考自st和gd相关启动文件,重要代码如下:
移植OpenHarmony轻量系统【4】启动文件与链接-鸿蒙开发者社区

4.3 链接脚本

这里我将链接脚本放到这个路径下:
device\board\lianzhian\gd32f303_lianzhian\gd32f30x_hrst.ld
用于指定code、RO-data、RW-data、ZI-data如何分布。
首先指定内存地址为0x20000000,大小为64K、
片上flash地址为:0x8000000,大小为512K
这里跟芯片相关,需要正确修改,否则可能起不来。
移植OpenHarmony轻量系统【4】启动文件与链接-鸿蒙开发者社区

同时链接脚本也指定了固件的生成规则:
移植OpenHarmony轻量系统【4】启动文件与链接-鸿蒙开发者社区
这里只截取了部分,可以看到生成的固件最开始存放的isr_vector,这个是中断向量表,在启动文件中定义:
移植OpenHarmony轻量系统【4】启动文件与链接-鸿蒙开发者社区
接下来就是text,也就是代码段
还有rodata,只读数据段。
后面还有其它定义,我们下一篇再细节。
至此我们的启动文件、链接脚本中比较关键的部分已经说明完。

4.4 链接参数

我们还需要修改device/board/lianzhian/gd32f303_lianzhian/liteos_m/config.gni文件,指定链接参数:
移植OpenHarmony轻量系统【4】启动文件与链接-鸿蒙开发者社区
在 board_ld_flags 中增加:
“-T${ohos_root_path}device/board/lianzhian/gd32f303_lianzhian/gd32f30x_hrst.ld”

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
5
收藏 3
回复
举报
1条回复
按时间正序
/
按时间倒序
红叶亦知秋
红叶亦知秋

被连老师爆发式的更新惊到了,感谢老师的分享。

回复
2022-2-10 10:10:07
回复
    相关推荐