历史上的今天
返回首页

历史上的今天

今天是:2025年04月19日(星期六)

2020年04月19日 | 嵌入式Linux学习笔记之——代码重定位002_链接脚本的引入

2020-04-19 来源:eefocus

① NOR启动:

② nand 启动:

上次讲到的g_char不能按照程序正确输出的原因是nor启动的时候g_char在nor flash中,其不可写的特性决定了输出结果。


现在能否修改Makefile让nor启动时讲代码拷贝到SDRAM中,这样就可以实现全局变量的可读可写了。

现在想在nor flash启动的时候将其中的代码段拷贝至SDRAM中0地址起始的空间,将全局变量g_char拷贝至0x30000000起始的空间。

编译之后发现.bin文件变成了800M,805306369-->0x30000001,符合程序中的g_char所占1字节的设置。


但是nor flash一共才2M,不可实现。


解决方法有两种:


第1种: 只是重定位了全局变量


① 在,bin文件中让g_char和代码段靠在一起


② 烧写至nor flash中


③ 运行时让前面的代码段将g_char复制到SDRAM起始的0x30000000地址空间中,即重定位。


第2种:重定位了整个代码+全局变量


让代码段和g_char之间没有那么大的空洞。

我们怎么将位于0x30000000的数据data段跟位于0地址的代码段拼在一起呢?


因为这些复杂的操作通过简单的参数设置已经无法实现,因此需要引入链接脚本来完成相应的操作。


链接脚本:

通过链接脚本的方式实现:

SECTIONS {

.test 0 : { *(.test) }

.rodata : { *(.rodata) }

.data 0x30000000 :  AT(0X800) { *(.data) }

.bss : { *(.bss) *(.COMMON)}

}


编译

烧写至开发板的nor flash之后发现输出是乱码,烧写至nand flash之后依然是乱码。


在链接脚本中,我们将data段定位到了0x800(2048)的位置上,但是在main函数中访问g_char时的地址是0x30000000。

下面查看main函数的反汇编码:

从反汇编码可以看出,寄存器r3确实在0x30000000地址中得到了其中的值,但是我们在程序中并没有将g_char的值放到0x3000000的地址空间去,因此缺少了重定位的一个步骤。

修改代码:现在需要将g_char的值从0x800的地方复制到0x30000000的地址空间去。


在start.S文件中加入重定位的代码即可:


/* 重定位data段 */

mov r1, #0x800

mov r0, [r1]

mov r1, #0x30000000

str r0, [r1]

之后编译代码下载至开发板,发现还是乱码。。。“RP值低预警”。。。


查找问题后发现,原因竟然是。。。在start.S中没有初始化SDRAM!!

之后再次编译代码下载至开发板(注意设置开发板启动模式为nor启动):

成功!!


接下来的问题是,刚刚的重定位代码并不通用。在重定位的时候我们是在知道原地址和重定位地址的情况下从0x800仅仅复制了一个字节到0x30000000地址中去的,如果我们要复制多个字节又该怎么做呢?


首先修改链接脚本:


SECTIONS {

.text 0 : { *(.text) }

.rodata : { *(.rodata) }

.data 0x30000000 : AT(0X800) 

data_load_addr = LOADADDR(.data);

data_start = . ;

*(.data) 

data_end = . ;

}

.bss : { *(.bss) *(.COMMON)}

}

注意:链接脚本中的“.”代表当前地址,这里的当前地址指的是前面各种段地址的顺延。

然后修改start.S文件:


/* 重定位data段 */

ldr r1, =data_load_addr  /* data段在bin文件中的地址,加载地址 */、

ldr r2, =data_start     /* data段的重定位(从nor或者nand flash中定位至SDRAM中)开始地址,运行时的地址 */

ldr r3, =data_end       /* data段重定位的结束地址 */


/* 接下来将r1所指地址中的值拷贝至r2所指的地址空间 */

cpy:

ldrb r4, [r1]   //从r1地址处拷贝一个字节到r4

strb r4, [r2]

add r1, r1, #1

add r2, r2, #1

cmp r2, r3

bne cpy

在main函数中加入一个全局变量:


char g_char = 'A';

char g_char3 = 'a';


const char g_char2 = 'B';

int g_A = 0;

int g_B;


int main(void)

{

uart0_init();


while(1)

{

putchar(g_char);   

g_char++;      /* nor启动时,此代码无效 */

putchar(g_char3);   

g_char3++;      /* nor启动时,此代码无效 */

delay(100000);

}


编译烧写:

成功。

推荐阅读

史海拾趣

赛微(Cellwise)公司的发展小趣事

在技术创新和产品研发的过程中,赛微高度重视知识产权的保护和管理。公司积极申请各类专利和软件著作权,加强知识产权保护力度。截至目前,赛微已经拥有国际/国内软件著作权98项,国际/国内专利166项,正在申请的国际/国内专利64项。这些知识产权的积累不仅提升了公司的核心竞争力,也为公司的长期发展奠定了坚实基础。

超音(CY)公司的发展小趣事

超音(CY)公司成立于XXXX年,初期专注于音频设备的研发和生产。创始人XXX先生凭借对音乐的热爱和对技术的追求,决定进入电子行业,并确定了音频设备作为公司的主要发展方向。在初创阶段,超音面临了诸多挑战,包括资金短缺、技术瓶颈和市场竞争等。然而,通过不懈的努力和创新,超音逐渐在音频设备领域崭露头角。

诚芯微(CXW)公司的发展小趣事

在2017年,诚芯微被认定为国家高新技术企业,这是对公司技术实力和创新能力的高度肯定。获得这一荣誉后,诚芯微进一步加大了研发投入,加强了与高校和科研机构的合作,推动了公司技术的持续创新。同时,公司还扩大了产能,优化了供应链管理,提升了市场竞争力。

AF International公司的发展小趣事

在电子行业发展日新月异的背景下,AF International始终坚持技术创新,不断推出新产品、新技术。公司投入大量资金用于研发,引进先进的生产设备和测试仪器,确保产品质量的稳定提升。此外,AF International还积极与高校、科研机构合作,共同开展技术研发项目,推动电子行业的创新发展。正是这些技术创新成果,使得AF International在行业中始终保持领先地位。

辰颐电子公司的发展小趣事

在辰颐电子公司的发展历程中,品质和创新一直是其核心竞争力。公司始终坚持对产品品质的严格把控,从原材料采购到生产流程,再到售后服务,都力求做到精益求精。同时,公司还注重技术创新和研发投入,不断推出具有竞争力的新产品,满足市场不断变化的需求。这种品质与创新的双轮驱动模式,使辰颐电子在激烈的市场竞争中脱颖而出。

Eurohm Resistors公司的发展小趣事

随着市场的不断扩张和竞争的加剧,Eurohm Resistors始终坚持品质至上的原则。公司建立了严格的质量控制体系,从原材料采购到生产流程,再到成品检验,每一个环节都严格把关。这种对品质的坚守不仅赢得了客户的信任,也为公司赢得了良好的口碑。

问答坊 | AI 解惑

PCB行业中关于RoHS指令有害物质的检测方法

要求2006年7月1日开始,电子电气设备中禁止使用铅、汞、六价铬、镉和多溴联苯(PBB)、多溴二苯醚(PBDE);其中镉限量指标 100PPm(0.01%),另五种限量l000ppm(0.1%)。企业出口欧盟的产品都需符合以上的限量要求,并且要展示相应的证明文件, ...…

查看全部问答>

监控系统中的各种干扰解决大全

1. 木纹状的干扰   这种干扰的出现,轻微时不会淹没正常图像,而严重时图像就无法观看了(甚至破坏同步)。这种故障现象产生的原因较多也较复杂。大致有如下几种原因:  (1)视频传输线的质量不好,特别是屏蔽性能差(屏蔽网不是质量很好的铜 ...…

查看全部问答>

浅说三极管的开关应用

本帖最后由 paulhyde 于 2014-9-15 03:44 编辑 三极管,电子元件,在我们平时所看到的电路板中有很多,三极管工作起来呢就像个水龙头,一个进水的的地方(NPN的集电极,PNP的射电极),一个出水的地方(NPN的射电极),还有就是龙头的把手了(基极 ...…

查看全部问答>

关于过程性连续赋值语句

各位大侠,我想问下,过程性连续赋值语句的最大特点是什么啊?   我还想问下,过程性连续赋值语句对于reg变量是不是不支持啊? 我最近用quartusII仿真程序,在全编译的时候出现procedural continuous assignment to register is not su ...…

查看全部问答>

evc 下如何建立ATL/WTL 的工程?

我下载了WTL80,发现该目录下有个文件夹“AppWizCE”,要怎样才能使EVC下能够通过AppWizard来创建ATL/WTL个工程呢? 如果不能通过AppWizard来创建,evc下如何建立ATL/WTL的exe工程?…

查看全部问答>

Wince程序在设备上运行报异常!!!

我将bin目录下的exe文件和sdf数据库文件复制到wince设备上,运行exe文件就报异常。 异常信息: Error SmartDevice.exe MissingMethodException File or assembly name \'System.Data.SqlServerCe, Version=3.5.1.0, Culture=neutral, PublicKe ...…

查看全部问答>

欢迎申请版主

欢迎申请www.devdiv.net版主…

查看全部问答>

大家使用IAR编译STM32系列工程都使用优化功能吗?

最近发现一个问题,使用IAR的编译优化的时候,对采样数据有很大的影响。现在做的这个项目使用STM32101 64K的片子,程序到47K了,但还没有做完,于是想试下IAR4.41的优化功能,选择High(Maximun Optimization),编译出来有31K多,心 ...…

查看全部问答>

=== 请问,CCS的help和tutorial里面好多乱码,怎么解决? ===

我用的是CCS2.2,C6000的tutorial里面, dsp/bios那部分里面好多乱码,尤其是涉及到文件路径的地方 是不是我的系统少装了什么? 谢谢…

查看全部问答>

keil 编译问题

今天在编译的时候右击led.h(我用的是KEIL 4),试图打开这个文件,总是说:source browser led.h  is undefined。打开其他头文件也是如此,我检查了一遍,KEIL的设置并没有改,头文件路径都已添加。重新建立一个工程也是打不 ...…

查看全部问答>