JZ2440关于代码重定位

关于裸机程序重定位的问题,我对基于jz2440的开发板上的重定位程序进行了分析,总结以下学习过程

在开始之前,先简单说一下2440开发板的两种启动过程

     1、nand flash启动,将编译好的程序烧入开发板的nand flash进行启动,这时CPU内部会自动

         将nand flash内部的代码前4k拷贝到CPU片内SRAM上执行,所以此时CPU执行的0地址为

        片内SRAM上的地址。

     2、nor flash启动,将程序烧录进norflash进行启动的话,CPU执行代码的0地址为nor flash内的地址

        也就是说,CPU从nor flash中取指,执行。

那么为什么需要程序的重定位呢?

如果从nor flash中启动的话,nor flash不能像内存那样进行简单的写操作,那么程序中的一些变量就行出错, 如果是nand flash中启动的话,因为nand flash中前4K的代码会被拷贝到片内的SRAM中去,那么当程序大于4K的话也会 执行出错,所以会有代码重定位的需求。

关于链接脚本的语法和作用在此不做解析,但要知道一点,生成的bin文件的格式是和链接脚本有关的,

比如链接脚本对应

SECTIONS

{
  .= 0x30000000;
 .= ALIGN(4);
.text      :
  {
*(.text)
 }
   .= ALIGN(4);
.rodata : { *(.rodata) 
  .= ALIGN(4);
.data : { *(.data) }
  .= ALIGN(4);
  __bss_start = .;
.bss : { *(.bss) *(.COMMON) }
_end = .;
}

根据链接脚本生成的bin文件的格式如下
在这里插入图片描述
此时该程序如果从nor flash中启动执行的话,它在nor flash中的位置如下
在这里插入图片描述
它被烧录进nor flash的0地址,CPU从0地址处开始取指,执行,当执行到我们的重定位代码处开始进行代码的重定位

  /* 重定位text,  rodata, data段整个程序 */
mov r1, #0
ldr r2, =_start         /* 第1条指令运行时的地址 */
ldr r3, =__bss_start    /* bss段的起始地址 */
cpy:
ldr r4, [r1]
str r4, [r2]
add r1, r1, #4
add r2, r2, #4
cmp r2, r3
ble cpy

上面的0就是nor flash中的加载地址,_start是程序的运行地址(0x300000000),从这里进行拷贝,将程序拷贝到SDRAM中运行地址处,结果如下
在这里插入图片描述
跳转到SDRAM中执行程序,如果执行程序从nand flash中启动的话,如果程序小于4K,此时的重定位程序直接从SRAM中拷贝到SDRAM中去,拷贝程序和nor flash的程序没有差别,如果程序大于4k的话就必须从nand flash中进行拷贝,此时就需要专门的nand flash操作程序去拷贝,关于nand flash的程序在另一篇文章中介绍,这里也只是总结一下我对整个重定位的理解,也在初级学习阶段,如果有不对的地方请指正,谢谢。

发布了33 篇原创文章 · 获赞 2 · 访问量 1038

猜你喜欢

转载自blog.csdn.net/weixin_41791581/article/details/99682221
今日推荐