s3c2440裸机-代码重定位(1.重定位的引入,为什么要代码重定位)

发布者:SparklingStar22最新更新时间:2023-08-09 来源: elecfans关键字:s3c2440  裸机  代码重定位 手机看文章 扫描二维码
随时随地手机看文章

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  裸机  代码重定位 引用地址:s3c2440裸机-代码重定位(1.重定位的引入,为什么要代码重定位)

上一篇:s3c2440裸机-代码重定位(2.编程实现代码重定位)
下一篇:s3c2440裸机-内存控制器(五、SDRAM编程实现)

推荐阅读最新更新时间:2024-10-31 12:08

S3C2440汇编点灯
如何点灯 步骤如下 1、看原理图确定控制LED的引脚 2、看主芯片手册确定如何设置/控制引脚 这里JZ2440的芯片,就是S3C2440 3、写程序 主芯片引脚输出高电平或低电平就可以改变LED状态 我们不关心GPIO引脚输出的逻辑电压,只关心高电平或低电平 主芯片输出的两种情况 第一种 此时主芯片 输出3.3V电压,点亮LED 输出0V电压,熄灭LED 第二种 此时主芯片 输出0V电压,点亮LED 输出3.3V电压,熄灭LED 引脚驱动能力不足的情况 有可能有的引脚能够发出的最大电流不能够点亮LED 这时候就需要我们来改进这个电路—— 使用三极管 有可能芯片只能输出1.2V,但足以使得三极
[单片机]
<font color='red'>S3C2440</font>汇编点灯
S3C2440内存初始化
分三部分说明: ①2440地址空间 ②内存与芯片硬件连接 ③存储控制器寄存器 S3C2440地址空间 S3C2440对外提供27根地址线,单靠芯片上的27根引脚,它只能访问128M的外设空间。 为了扩大外设的访问范围,S3c2440芯片又提供了8个片选信号nGCS0~nGCS7,对应Bank0-Bank7。当某个片选信号nGCSx有效时,则可以通过27根地址线去访问对应这个片选的128MB空间。当访问BANKx的地址空间时,nGCSx引脚输出低电平来选中外接设备。由于有8个片选,所以2440芯片能访问的外设空间总为8*128MB=1GB.而1G(0x40000000)以上的空间,则安排给了2440内部的寄存器,访问这些内部的寄存
[单片机]
s3c2440 gcc交叉编译工具链制作
前言: 因为准备学习lwip,之前在stm32上移植跟着教程走得差不多了,但是用的keil。所以想在一个新平台移植一下巩固巩固,正好有2440的板子,也学一下gcc-make这样的开发流程,配套的编译器很老,编译配套的linux2.6.22.6内核还是没问题的,但是当我用裸机模板创建一个包含lwip的代码的工程时,编译就会出现以下错误: collect2: ld terminated with signal 11 , core dumped /home/streleizia/gcc-3.4.5-glibc-2.3.6/bin/../lib/gcc/arm-linux/3.4.5/../../../../arm-linux/bin/
[单片机]
s3c2440硬件篇之六:系统时钟和定时器
S3C2440有三种时钟:FCLK(用于CPU核),HCLK(用于主机模块),PCLK(用于外设).两种PLL(锁相环):MPLL(用于设置FCLK,HCLK,PCLK),UPLL(用于设置USB设备),. S3C2440的CPU核工作电压为1.2V时,主频FCLK可以达到300M,CPU核工作电压为1.3V时,主频FCLK可以达到400M.为了降低电磁干扰,降低板间的布线要求,s3c2410/s3c2440外接的晶振通常很小,一般为12M,那么如何达到主频FCLK的400M的呢?------PLL倍频。 一.设置主频FCLK主要是通过MPLL来软件实现倍频。MPLL主要由3个值MDIV,PDIV,SDIV来决定。而这3个值是
[单片机]
<font color='red'>s3c2440</font>硬件篇之六:系统时钟和定时器
四 ARM9(S3C2440)的ADC和触摸屏控制——理论知识
概述 10 位CMOS ADC(模/数转换器)是一个8 通道模拟输入的再循环类型设备。其转换模拟输入信号为10 位二 进制数字编码,最大转换率为2.5MHz A/D 转换器时钟下的500 KSPS。A/D 转换器支持片上采样-保持功能和掉电 模式的操作。 触摸屏接口可以控制/选择触摸屏X、Y 方向的引脚(XP,XM,YP,YM)的变换。触摸屏接口包括触摸屏引 脚控制逻辑和带中断发生逻辑的ADC 接口逻辑。 触摸屏接口模式 1. 普通转换模式 单转换模式是最合适的通用ADC 转换。此模式可以通过设置ADCCON(ADC 控制寄存器)初始化并且通过读写 ADCDAT0(ADC 数据寄存器0)就能够完成。 2. 分离的X/Y 方向转换模
[单片机]
S3C2440电源管理有关问题及其解决方法
关于2440的电源管理调试出现过的问题以及解决方法: 1、系统睡眠与唤醒,拿到普通的代码,出现的问题经常是进入睡眠后,GPIO唤醒总是导致系统重新启动,其实这是因为没有设置CPU的运行模式,而这运行模式是通过设置GPG13,GPG14,GPG15来进行的。所以就要想唤醒后恢复到睡眠之前的状态,则要在进入睡眠前设置这三个GPIO的模式,可以在arch/arm/plat-s3c24xx/pm.c文件中的s3c2410_pm_enter()中在进入谁面前,也就是执行__raw_writel(0x00, S3C2410_CLKCON)前加入如下三条语句: __raw_writel(__raw_readl(S3C2410_EINTPEND)
[单片机]
S3C2440开发板如何修改LCD参数
1.TQ2440u-boot-1.1.6 本文引用地址:  http://embed.21ic.com/hardware/development/201801/50078.html 修改文件所在的路径是u-boot-1.1.6includeconfigsEmbedSky.h 将#defineLCD_TFTxxx(LCD类型) W353.5寸 TFT4802724.3寸 TFT8004807寸 TFT80060010.4寸 VGA1024768VGA1024*768 2.TQ2440winceEboot和nk 修改文件所在的路径是PLATFORMTQ2440SrcIncs3c2440a_lcd.h 修改#defineLCD_TYP
[嵌入式]
6410 运行裸机程序
关于ok6410的裸机开发资料,大多都是windows下的,使用RVDS编写裸机程序,并编译烧录到开发板上运行,但是我整了很久也没在windows10上将环境装好,又懒得装一个xp的虚拟机,所以就摸索在Linux下进行裸机程序的开发。具体内容分为以下几个部分: 一.前期准备 二.裸机程序的编写(驱动LED) 三.裸机程序编译链接 四.裸机程序的烧录 一.前期准备 1.交叉编译工具链 交叉编译工具链用来编译、链接裸机程序,生成开发板可执行的二进制文件,只需要将ok6410光盘中的交叉编译工具解压到Linux下,并添加环境变量指明路径即可,如下图: 2.tftp服务器 tftp服务器用来将二进制文件传送到开发板上 1.安装xinet
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
  • 学习ARM开发(16)
    ARM有很多东西要学习,那么中断,就肯定是需要学习的东西。自从CPU引入中断以来,才真正地进入多任务系统工作,并且大大提高了工作效率。采 ...
  • 学习ARM开发(17)
    因为嵌入式系统里全部要使用中断的,那么我的S3C44B0怎么样中断流程呢?那我就需要了解整个流程了。要深入了解,最好的方法,就是去写程序 ...
  • 学习ARM开发(18)
    上一次已经了解ARM的中断处理过程,并且可以设置中断函数,那么它这样就可以工作了吗?答案是否定的。因为S3C44B0还有好几个寄存器是控制中 ...
  • 嵌入式系统调试仿真工具
    嵌入式硬件系统设计出来后就要进行调试,不管是硬件调试还是软件调试或者程序固化,都需要用到调试仿真工具。 随着处理器新品种、新 ...
  • 最近困扰在心中的一个小疑问终于解惑了~~
    最近在驱动方面一直在概念上不能很好的理解 有时候结合别人写的一点usb的例子能有点感觉,但是因为arm体系里面没有像单片机那样直接讲解引脚 ...
  • 学习ARM开发(1)
  • 学习ARM开发(2)
  • 学习ARM开发(4)
  • 学习ARM开发(6)
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved