SylixOS启动脚本分析

      本周学习了一些ARM指令、伪指令、链接脚本命令等,并对整个编译过程、elf文件有了更加深入的理解。ARM指令在ARM架构参考手册里面有了详细的介绍,这里不再列出,以下是一些GCC链接脚本命令的分析。
      以SylixOS启动脚本为例,分析一下链接脚本相关命令。SylixOS链接文件包括config.h、config.lds、SylixOSBSP.ld,它们位于BSP板级支持包根目录内。

      config.h文件定义了RAM、ROM的基址和大小,定义了TXET、DATA、DMA、APP段的大小,config.h文件定义如下:
/****************************************************************
ROM RAM 相关配置
****************************************************************/
#define BSP_CFG_ROM_BASE (0x00000000)
#define BSP_CFG_ROM_SIZE (4 * 1024 * 1024)
#define BSP_CFG_RAM_BASE (0x30000000)
#define BSP_CFG_RAM_SIZE (64 * 1024 * 1024)
#define BSP_CFG_TEXT_SIZE (6 * 1024 * 1024)
#define BSP_CFG_DATA_SIZE (18 * 1024 * 1024)
#define BSP_CFG_DMA_SIZE (6 * 1024 * 1024)
#define BSP_CFG_APP_SIZE (34 * 1024 * 1024)
#define BSP_CFG_BOOT_STACK_SIZE (128 * 1024)

       config.lds文件定义如下:
MEMORY
{
TEXT (rx) : ORIGIN = (0x30000000), LENGTH =(6 * 1024 * 1024)
DATA (rw) : ORIGIN = (0x30000000) + ((6 *1024 * 1024)), LENGTH = (18 * 1024 * 1024)
}
BOOT_STACK_SIZE = (128 * 1024);

       MEMORY命令用来描述目标内存块的位置和大小,config.lds文件定义了两个内存块区域,TEXT(可读可执行)和DATA(可读可写),ORIGIN表示内存区域的起始地址,LENGTH表示内存长度。
       SylixOSBSP.ld文件定义如下:
INCLUDE "config.lds"
OUTPUT_FORMAT(elf32-littlearm) /* 二进制文件格式 */
OUTPUT_ARCH(ARM) /* ARM架构 */
/*
* SECTIONS命令告诉编译器如何将输入段映射到输出段,以及输出段在内存中的位置
*/
SECTIONS
{
/***************************************************************************
代码段 LMA == VMA== ORIGIN(TEXT)
ORIGIN(TEXT)表示TEXT内存块区域的起始地址
.text段是可执行代码段
***************************************************************************/
.text : {
*(.vector)
*(.text)
*(.text.*) /* cpp namespace function */
*(.romrun) /* ROM 中必须的函数 */
*(.rodata) /* read-only data (constants) */
*(.rodata*)
*(.glue_7)
*(.glue_7t)
} >TEXT /* >TEXT表示该段属于TEXT内存块 */
/***************************************************************************
GOT
***************************************************************************/
.got : {
*(.got.plt)
*(.got)
} >TEXT
/***************************************************************************
.ARM.exidxis sorted, so has to go in its own output section.
***************************************************************************/
.ARM.exidx: {
. =ALIGN(4);
PROVIDE(__exidx_start = .);
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
. =ALIGN(4);
PROVIDE(__exidx_end = .);
} >TEXT
/***************************************************************************
.data 段数据初始化内容放在这里
PROVIDE用来定义一个符号(如果程序中定义则忽略该定义,使用程序中定义的)
它的语法是 PROVIDE(symbol= expression)
***************************************************************************/
. =ALIGN(4);
PROVIDE(_etext = .);
/***************************************************************************
数据段
.data 段运行地址 VMA 为 ORIGIN(DATA), 装载地址 LMA 为 _etext,
连接器会将 .data 的初始化数据放在 _etext 的地方, 然后启动程序必须将 _etext 的内容搬运到
VMAORIGIN(DATA) 中. 大小等于 SIZEOF(.data)
下面的定义说明.data段的运行地址是DATA内存块的首地址,装载地址为_etext(AT命令指定)
从.data段开始,程序的装载地址和运行地址均不相同,个人理解
***************************************************************************/
.dataORIGIN(DATA) : AT (_etext) {
. =ALIGN(4);
PROVIDE (_data = .);
*(.data)
. =ALIGN(4);
PROVIDE (_edata = .);
} >DATA
/***************************************************************************
清零段
NOLOAD 表示不装载, 启动程序只需要借助 __bss_start 和 __bss_end 两个符号指定的起始地址和结束地址
将 .bss 区域清零即可. (注意 *.noinit 可以不进行清零)
***************************************************************************/
.bss(NOLOAD) : {
. =ALIGN(4);
*(.noinit)
. =ALIGN(4);
PROVIDE (__bss_start = .);
*(.bss)
. =ALIGN(4);
*(COMMON)
. =ALIGN(4);
PROVIDE (__bss_end = .);
} >DATA
/***************************************************************************
栈段
SylixOS 启动时使用,异常入口也使用
***************************************************************************/
.stack (NOLOAD) : {
. =ALIGN(8);
PROVIDE (__stack_start = .);
. +=BOOT_STACK_SIZE;
. =ALIGN(8);
PROVIDE (__stack_end = .);
} >DATA
/***************************************************************************
内核堆段
***************************************************************************/
.heap(NOLOAD) : {
. =ALIGN(8);
PROVIDE (__heap_start = .);
__heap_end = ORIGIN(DATA) + LENGTH(DATA) - 128;
PROVIDE (__heap_end = .);
} >DATA
}
      由于.data段的装载地址与运行地址不相同,那么在C代码运行之前,需要汇编去实现将.data段的数据从装载地址拷贝到运行地址处,然后程序才可以正常运行。初始化代码在startup.S中实现。
      至于.bss段、.stack段、.heap段,里面的值并不重要,不需要装载进BIN文件,只需记录它们的起始地址和结束地址,再进行相应操作即可。
--------------------- 
作者:jiangheng12138 
来源:CSDN 
原文:https://blog.csdn.net/automan12138/article/details/77478315 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值