Tiny4412裸机程序之代码重定位初体验

发布者:快乐球球最新更新时间:2022-02-18 来源: eefocus关键字:Tiny4412  裸机程序  代码重定位 手机看文章 扫描二维码
随时随地手机看文章

从前面一节Exynos 4412的启动过程分析 ,我们知道:一上电,exynos4412首先执行固化在IROM中的代码,iROM首先设置程序运行环境 (比如关看门狗、关中断、关MMU 、设置栈 、设置栈 、启动PLL等 ),然后根据OM引脚确定启动设备 (NAND Flash/SD 卡/其他 ),把 BL1从里面读出存入iRAM的0x02021400地址处,最后启动 BL1; BL1从SD卡适当的位置读入14K 字节的数据,存在iRAM地址0x02023400处,所以BL2不能大于(14K – 4) 字节,这里引出了为什么写这一节的原因:如果我们的程序很大,大于14K怎么办????


下面我们先来介绍两个概念:

一是程序当前所处的地址,即程序在运行时,所处的当前地址;二是程序的链接地址,即程序运行时应该位于的运行地址。编译程序时,可以指定程序的链接地址。


什么是重定位

对于Tiny4412而言,前面我们已经说过:启动时BL1只会从sd等启动设备中拷贝14K的代码到IRAM中,那么当我们的程序超过14K怎么办?那就需要我们在前14K的代码中将整个程序完完整整地拷贝到DRAM等其他更大存储空间,然后再跳转到DRAM中继续运行我们的代码,这个拷贝然后跳转的过程就叫重定位。


本章中我们主要学习如何重定位,但是并不会涉如何使用到DRAM,而是简单地将代码从IRAM的0x02023400处拷贝到IRAM的0x0202a000处,然后跳转到0x0202a000处继续运行我们的代码。


一、程序说明

基于上一个实验的代码进行修改,修改了start,S文件以及链接脚本文件:

在start.S文件中增加如下代码:



.text

.globl _start

_start:

 

/* 关闭看门狗 */

ldr r0, =0x10060000

mov r1, #0x0

str r1, [r0]

 

/* 启动Icache */

mrc p15, 0, r0, c1, c0, 0

orr r0, r0, #0x00001000 //打开ICache

//bic r0, r0, #0x00001000 //关闭ICache

mcr p15, 0, r0, c1, c0, 0

 

/* 重定位 - 将代码从0x02023400处拷贝到链接地址0x0202a000处(在链接脚本里指定的),并跳转到这个地址去执行 */

adr r0, _start /* adr指令用于读取_start在当前的运行的物理地址,即0x02023400 */

ldr r1, =_start /* 读取_start的链接地址,即0x0202a000 */

ldr r2, =bss_start /* 读取bss段的起始地址,用于计算需要拷贝的字节多少 */

cmp r0, r1

beq clean_bss /* 如果r0=r1,则跳转到clean_bss,说明此时已经在链接地址处了 */

 

/* 如果r0!=r1,则进行如下的拷贝 */

copy_loop:

ldr r3, [r0], #4 /* 源 */

str r3, [r1], #4 /* 目的 */

cmp r1, r2 /* 判断是否已经拷贝完 */

bne copy_loop /* 如果没有拷贝完就继续拷贝 */

 

/* 清bss段 */

clean_bss:

ldr r0, =bss_start /* r0保存bss段的起始地址 */

ldr r1, =bss_end /* r1保存bss段的起始地址 */

cmp r0, r1

beq run_on_dram /* 如果r0=r1,则跳转到run_on_dram,说明bss段里边没有变量 */

mov r2, #0

clear_loop:

str r2, [r0], #4

cmp r0, r1

bne clear_loop

 

ldr sp, =0x02060000 

 

/* 跳转 */

run_on_dram:

ldr pc, =main /* 执行完这句话之后,PC就指向了main的链接地址 */


这段代码主要实现了代码重定位、清除BSS段、以及跳转到链接地址继续运行,注释说的已经很明白了,有什么的不熟悉的,大家可以留言共同探讨。


链接脚本reload.lds修改为如下:


SECTIONS {

. = 0x0202A000;

.text : { 

*(.text) 

}

.rodata ALIGN(4) : {

*(.rodata*)

}

.data ALIGN(4) : { 

*(.data*) 

}

bss_start = . ;

.bss ALIGN(4) : { 

*(.bss) *(COMMON) 

}

bss_end = . ;

}


主要增加了bss段的起始bss_start及结束bss_end 的定义,这两个标号在start.S中被用到。


二、编译、烧写、运行

1.编译

通过FTP或者其他工具将文件上传到服务器上去,输入make命令进行编译将得到reload.bin文件。

2.烧写

将SD卡插入电脑,并让VmWare里的Ubuntu识别出来,然后执行如下命令:


sudo ./sd_fusing.sh /dev/sdb ../8_reload/reload.bin


将SD卡插入Tiny4412开发板,上电,你会看到和上一节的运行效果一样(因为我们没有修改LED的显示效果,只是修改了程序的运行地址,这个对外是看不出区别的)。


三、反汇编文件分析

将反汇编文件reload.dis,从服务器上下载下来,我们进行简单分析一下:

155713_4AHc_2888084.png

从上图可以看出,程序的链接地址确实是我们在连接脚本里指定的0x0202a000

160248_xR3t_2888084.png

我们再来看看跳转的那条指令;


202a060: e59ff010 ldr pc, [pc, #16] ; 202a078

将当前PC的值加上24后的地址的内容赋给PC,即:


0x202a060 + 8 +16 = 0x0202a078

将0x0202a078这个地址的值赋给PC


160549_gx0J_2888084.png

0x0202a0b0这个地址正是main函数的入口地址。


我在自己的开发板上面试验成功。有兴趣的小伙伴可以自行试验。

关键字:Tiny4412  裸机程序  代码重定位 引用地址:Tiny4412裸机程序之代码重定位初体验

上一篇:Exynos4412 文件系统制作(三)—— 文件系统移植
下一篇:TINY4412 裸机程序之点灯

推荐阅读最新更新时间:2024-11-17 06:07

分享tiny4412,emmc烧录u-boot, 支持fastboot模式烧写emmc
前言: 按照光盘介绍编译烧写U-boot也无法启动板子,只有superboot使用后才可以启动板子。到此大家估计很多和我想的一样,如何使用开源的u-boot来启动开发板。 言归正传,我们的目的是要用u-boot来运行tiny4412. 正文: 首 先要注意的是,原版的内核配置把CONFIG_ARM_TRUSTZONE给打开了,这个与superboot.bin是配套使用的,但是u-boot经 研究发现暂不支持TZ模式,所以内核配置要把这个选项去掉。不然按照教程会出现死机。论坛也有很多网友发现了此现象,不再赘述。(后面有时间本人会研究下 trustzone机制) 把TZ选项去掉后,通过SD卡烧录u-boot可以把板子带起来,这个不是
[单片机]
S3C2440—10.代码定位
本文主要介绍ARM裸机代码重定位的相关知识,以及重定位的实现过程。 下面将由ARM裸机(S3C2440)的启动方式开始分析,引入段的概念,随后介绍链接脚本的使用以及代码重定位的操作,首先会使用汇编语言验证代码重定位的可行性,最后将使用C语言实现代码重定位。 一.启动方式 S3C2440的启动方式有俩种: NOR FLASH启动 NAND FLASH启动 说起ARM裸机的启动方式,就是将程序的bin文件烧写在ARM的存储空间中,ARM从这些地址中读取指令到CPU中执行,需要数据的时候去数据的存储地址取数据。说白了启动方式的不同就是bin文件烧写地址的不同,可以烧在NOR FLASH中,也可以烧在NAND FLASH中,俩种F
[单片机]
S3C2440—10.<font color='red'>代码</font><font color='red'>重</font><font color='red'>定位</font>
二、mini2440裸机程序之按键检测实验
开发板:mini2440, NandFlash:K9F2G08U0B 256M大小,CPU:S3C2440A 。 开发环境:MDK4.11 仿真器:Jlink v8 这是我用csdn发表的第一个文章,之前使用过arm-linux-gcc裸机开发mini2440,但是很多函数什么的不能直接调用(我的技术问题),准备重新整理一下ARM裸机,整理好之后准备下一阶段学习。关于软件MDK4.11和它的注册机,我传不上去,说是由于文件太大,又想要的直接留言邮箱要就行了。 下面开始我们的第一个LED灯的点亮程序吧! 1、新建一个项目工程 双击MDK图标 进入开发环境,如下图, 单击Project/New uVision Pro
[单片机]
二、mini2440<font color='red'>裸机</font><font color='red'>程序</font>之按键检测实验

推荐帖子

为什么还在使用继电器驱动汽车电机?
随着汽车电气系统中更小更智能的集成电路(IC)的出现,是时候开始正视房间里的大象了:为什么我们仍然使用继电器控制汽车天窗、窗玻璃升降装置、电动锁、后行李箱盖提升装置、记忆座椅、压缩机以及车上的各种泵?虽然,继电器价格亲民且易于设计,但是由于它们的使用寿命有限且体积较大,因此它们的功能对于现代电机应用来说稍显笨重。对于一个安静、小型而安全的解决方案而言,固态IC是汽车电机控制应用的最佳选择。解决方案尺寸让我们比较两种解决方案,如图1所示的是具有相同的电压和电
Jacktang 模拟与混合信号
硬件工程师炼成之路笔记
硬件工程师炼成之路笔记硬件工程师炼成之路笔记非常好的资料,很有借鉴价值,下载保存了,谢谢分享。 站在肩上可以看得更远一点、、、多谢版主大大分享这么好的资料,祝楼主大大,心想事成!感谢楼主提供的电子资料,对我这个刚入门的初学者很需要,感谢分享
btty038 RF/无线
C/C++的64位整数[原]by 赤兔
在做ACM题时,经常都会遇到一些比较大的整数。而常用的内置整数类型常常显得太小了:其中long和int范围是,数据类型声明用上面两种均可输入输出用%I64d==================以下可无视=========================以下是对这种混乱情况的解释,如无兴趣可以跳过首先要说的是,和Java等语言不同,C/C++本身并没有规定各数据类型的位数,只是限定了一个大小关系,也就是规定从所占的bit数来说,short=int=long=
Hellovictoria DSP 与 ARM 处理器
5G印刷电路板铜箔表面粗糙度
使用激光显微镜测量超出Rz(最大高度)的粗糙度分析5G印刷电路板上铜箔的表面粗糙度移动电话的快速普及推动了移动通信系统的创新,该系统大约每十年就会进行一次重大的技术革新。这一演变始于20世纪80年代第一个使用模拟移动电话的移动通信系统(1G)。第二代(2G)为手机带来了电子邮件和互联网,而第三代(3G)则提供了高速、大容量的通信。第四代(4G)带来了更高的速度和更大的容量,使手机成为观看视频和玩游戏的平台。2020年,我们进入了第五代,即5G。5G技术实现超高速度和超大容
btty038 PCB设计
一个完整的项目范例,供大家参考
本帖最后由paulhyde于2014-9-1509:45编辑一个完整的项目范例,供大家参考一个完整的项目范例,供大家参考本帖最后由paulhyde于2014-9-1509:45编辑来看看。。。。。。。。本帖最后由paulhyde于2014-9-1509:45编辑。。。。。。。。。。。。。。。。。。。。本帖最后由paulhyde于2014-9-1509:45编辑看一下??????????????????????
xfh168168 电子竞赛
多片DSP的JTAG连接
如题,如何进行两片DSP的JTAG的串行连接问题,连接后他们的仿真是怎么区分对哪个DSP进行的,片子是TMS320VC5502和TMS320C6713多片DSP的JTAG连接文档说的很清楚,不过你没有必要这么做,还是单独仿真比较可靠。要不,一个cpu坏,另一个也不能仿真有道理谢谢了
wxiaojin DSP 与 ARM 处理器
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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