1.重定位的引入(为什么要代码重定位)

我们知道s3c2440的cpu从0地址开始取指令执行,当从nor启动时,0地址对应nor,nor可以像内存一样读,但不能像内存一样写。我们能够从nor上取指令执行。

例子1:当nand启动的时候,我们nand中的前4K指令会变自动加载到sram中去,这时的0地址对应sram。

那么我们的程序如果大于4K,要从nand启动,sram只拷贝了nand中的前4K代码,那么如何解决这个问题呢?

那么就需要重定位代码到sdram中去,sdram的容量较大,又可以直接被cpu访问。

例子2:我们知道,程序含有:

代码段(.text)
数据段(.data):存放初始值不为0的全局变量/静态变量
rodata段(.rodata):const修饰的全局变量或静态变量
bss段(.bss):存放初始值为0或者未初始化的全局变量/静态变量
commen段(.commen):注释

假设有如下代码编译成一个bin文件。

#include "s3c2440_soc.h"
#include "uart.h"
#include "init.h" int g_Char = 'A'; //.data
int g_CharB = 'B'; //.data
int g_CharC = 'C'; //.data
int g_CharD = 'D'; //.data const int g_roval = 'C'; //.rodata
int g_A = 0; //bss
int g_B; //bss int main(void)
{
uart0_init();
while (1)
{
putchar(g_Char);
g_Char++; /* nor启动时, 此代码无效,由于nor启动,nor上不可写 */
delay(1000000);
}
return 0;
}

我们把它分别烧录到nand和nor看看有什么不一样?

1.烧录到nor: 我们发现程序一直输出‘AAAAAAA’。

2.烧录到nand: 我们发现程序无任何输出。

我们发现nor启动时, 对g_Char++无效,nand启动程序无任何输出,为什么呢?

我们对程序反汇编看看:

我们发现程序的.text段是从0地址开始的,那么cpu从0地址取指令进行译码、执行。

当从nor启动时,0地址对应nor;当从nand启动时,0地址对应sram,所以无论从nand还是从nor启动cpu都能取指令执行。

但是,我们在来看下.data段,发现.data段的起始地址是0x8474(即g_Char变量的地址为0x8474)。

那么:

1)当把程序烧录进nor, .data段在nor上的某一段区域,由于nor能像内存一样读,

但不能像内存一样直接写,所以对 'g_Char'修改无效。

2)当把程序烧录进nand, .data段在nand的某一区域,nand启动时硬件会自动把nand上的前4K数据copy到SRAM,然后cpu从sram取指令执行。但是.data段的起始地址0x8474>0x1000,超过了4K,cpu没法把.data段也copy到SRAM,所以当访问'g_Char'时,发生了异常(abt数据访问终止,这个异常后面我会在“异常与中断”里面专门讲解)。

那我们再仔细看看反汇编,发现.rodata段和.text段是连续的,但是.rodata段和.data段中间有一段"空洞"。用图形表示更形象,bin文件的内容分布如下所示:

那么我们怎么去掉空洞,让.data段了紧接着.rodata段呢?

用链接脚本(这个下节会讲),但现在直接在编译的时候用 "-Tdata 0x800",这样指定.data段基地址为0x800,这样nand启动时.data就能自动copy到SRAM了。再看下反汇编的.data段:

这时我们烧录程序到nand,从nand启动,发现能输出‘ABCDEFG’...

有人说为什么不吧.data段指向到sdram呢,这样不就能对对全局变量写了?

我做了这个尝试,编译时用"-Tdata 0x30000000", 发现编译出来的bin文件有800多M,为什么有这么大呢?由于我们指定.data段存放在0x30000000(sdram的基地址),这时bin文件的内部结构如下所示:

这个时候根本无法烧录。

通过上面2个例子,现在总结下为什么要代码重定位:

1.nand启动,前4K代码被自动copy到sram,当程序大于4K的时候需要重定位代码到sdram。

2.nor启动, 全局变量在nor上,不能像内存一样直接写该全局变量,那么也需要重定位到sdram。

s3c2440裸机-代码重定位(1.重定位的引入,为什么要代码重定位)的更多相关文章

  1. linux上使用J-Link调试S3C2440裸机代码

    linux上使用J-Link调试S3C2440裸机代码 工具: segger的jlink仿真器 segger的jlink for linux 交叉编译工具链里面的arm-xx-linux-xx-gdb ...

  2. Windows下对文件夹下所有图片批量重命名(附C++,python,matlab代码)

    https://blog.csdn.net/u011574296/article/details/72956446: Windows下对文件夹下所有图片批量重命名(附C++,python,matlab ...

  3. 【转载】s3c2440裸机开发调试环境(MDK4.6,Jlink v8,mini2440)

    用于arm裸机程序开发的IDE基本有 以下3个:MDK,IAR,还有ADS.具体它们的具体情况在这里我就不多说了,百度一下就明白了.由于之前开发c51,stm32时候都使用了MDK开发环境,而且MDK ...

  4. s3c2440裸机-时钟编程(二、配置时钟寄存器)

    s3c2440裸机编程-时钟编程(二.配置时钟寄存器) 1.2440时钟时序 下图是2440时钟配置时序: 1.上电后,nRESET复位信号拉低,此时cpu还无法取指令工作. 2.nRESET复位信号 ...

  5. 好代码是管出来的——浅谈.Net Core的代码管理方法与落地(更新中...)

    软件开发的目的是在规定成本和时间前提下,开发出具有适用性.有效性.可修改性.可靠性.可理解性.可维护性.可重用性.可移植性.可追踪性.可互操作性和满足用户需求的软件产品. 而对于整个开发过程来说,开发 ...

  6. PC逆向之代码还原技术,第四讲汇编中减法的代码还原

    目录 PC逆向之代码还原技术,第四讲汇编中减法的代码还原 一丶汇编简介 二丶高级代码对应汇编观看. 1.代码还原解析: 三丶根据高级代码IDA反汇编的完整代码 四丶知识总结 PC逆向之代码还原技术,第 ...

  7. idea没有代码自动提示功能和包自动引入不了问题

    idea没有代码自动提示功能和包自动引入不了问题 原因:节电模式 File -> Power Save Mode (被勾选了) 处理方法: File -> Power Save Mode ...

  8. php实现把数组排成最小的数(核心是排序)(看别人的代码其实也没那么难)(把php代码也看一下)(implode("",$numbers);)(usort)

    php实现把数组排成最小的数(核心是排序)(看别人的代码其实也没那么难)(把php代码也看一下)(implode("",$numbers);)(usort) 一.总结 核心是排序 ...

  9. 判断语句(if...else)if...else语句是在指定的条件成立时执行代码,在条件不成立时执行else后的代码

    判断语句(if...else) if...else语句是在指定的条件成立时执行代码,在条件不成立时执行else后的代码. 语法: if(条件) { 条件成立时执行的代码 } else { 条件不成立时 ...

  10. Typora代码块配色和标题自带序号的实现代码

    Typora代码块配色和标题自带序号的实现代码 先打开主题文件夹 文件>偏好设置>外观>打开主题文件夹 然后编辑base.user.css(如果没有就新建一个)文件 /*标题自动添加 ...

随机推荐

  1. CoderForces-Round60D(1117) Magic Gems

    D. Magic Gems time limit per test 3 seconds memory limit per test 256 megabytes input standard input ...

  2. CodeForces845G-Shortest PathProblem?

    You are given an undirected graph with weighted edges. The length of some path between two vertices ...

  3. 初次在Vue项目使用TypeScript,需要做什么

    前言 总所周知,Vue新版本3.0 使用 TypeScript 开发,让本来就很火的 TypeScript 受到更多人的关注.虽然 TypeScript 在近几年才火,但其实它诞生于2012年10月, ...

  4. CyAPI环境搭建

    http://jingyan.baidu.com/article/e6c8503c0690cee54f1a1893.html

  5. Python3 网络编程和并发编程总结

    目录 网络编程 开发架构 OSI七层模型 socket subprocess 粘包问题 socketserver TCP UDP 并发编程 多道技术 并发和并行 进程 僵尸进程和孤儿进程 守护进程 互 ...

  6. Jenkins编译过程中出现ERROR_ Failed to parse POMs错误

    一.在使用jenkins编写过程中突然出现以下问题 Parsing POMs Established TCP socket on 59407 [java] $ java -cp /var/lib/je ...

  7. java虚拟机栈 相关操作

    针对JVM虚拟栈 和栈帧的操作 虚拟机栈: 栈元素是栈帧.方法调用,栈帧入栈,反之出栈. 栈帧:一个方法的运行空间. 1.局部变量表:方法定义的局部变量.方法的参数存在该表. 实例方法中有个隐含参数“ ...

  8. php5.4.16执行shell脚本

    因为要用到Python脚本,所以打算直接在PHP中直接调用系统命令system(). 要注意两点: 一.PHP5.3以上不存在安全模式,即要直接执行脚本不需要作任何其他配置. 二.system函数格式 ...

  9. 2016/11/10 kettle概述

    ETL(Extract-Transform-Load,即抽取,转换,加载),数据仓库技术,是用来处理将数据从来源(以前做的项目)经过抽取,转换,加载到达目的端(正在做的项目)的过程.也就是新的项目需要 ...

  10. go 1.13编译遇到xxx/go.mod malformed record data 问题

    背景: 公司在做自己的发布平台,需要自动化编译go 工程,大部分开发使用的都是go 1.12 版本 由于go mod的机制,有很多包需要代理才能进行下载,而自动化编译频繁的进行代理切换就很麻烦. 所以 ...