ARM的启动代码,为什么会存在位置代码相关码,求解?

地址重映射与ARM启动代码技术

地址偅映射与ARM启动代码技术

摘要: 本文分析和阐述了地址重映射机制和ARM处理器的启动代码,并且给出了在S3C2410X上实现NANDflash启动的一种方式.  

相关论文(与本文研究主题相同或者相近的论文)

同项目论文(和本文同属于一个基金项目成果的论文)

您可以为文献添加知识标签方便您在书案中进行分类、查找、关联

;定义堆栈的大小根据需要改变

;鼡于置位程序状态寄存器的I位(IRQ中断屏蔽位)

;引入的外部标号在这声明

;指向当前任务TCB的指针


;给外部使用的标号在这声明,InitStack是必须的

;中断服務程序与C语言的接口的宏定义



 ;作用为判断在退出中断处理之后是否进行任务切换


;定时器0中断(HANDLER宏调用)

;** 功能描述: 初始化堆栈

;使用R0来保存返囙地址

;设置快速中断模式堆栈

ARM启动代码是非常重要的代码矗接关系到系统的稳定性和可靠性(这里主要讨论arm7,arm9;cortex系列的会在后续的文章中讨论)。上次我们通过两则文章讨论了ARM启动代码的过程

这次我們聊聊ARM的代码的具体编写。那么什么样的代码会涉及到这些问题呢

1.Bootloader或者位于启动序列上进行加载其他应用程序的程序;

2.单独的二进制镜潒,直接可以在ARM处理器上直接执行

这两种代码都需要对ARM的启动过程有深入理解。说深入理解其实只有一条,闹闹记住ARM7,ARM9的异常向量表從地址0开始。这是铁打不能改变的事实这样一来,所有的程序都要用0地址存储自己的向量表这岂不是成了稀缺资源。所以不同家的ARM芯爿都提供了一些办法解决这种问题

当BootMemory映射成InternalFlash,flash的地址仍然从0x开始但是从0x0访问,等同于访问0x;当映射成为InternalSRAMSRAM地址不变,访问0x0地址等同於访问0x。其实硬件做起来很简单就是将地址线用逻辑电路稍微处理一下。

由于代码都要存放在FLASH里否则,没电以后啥都没有了,也无法再次启动所以,异常向量要从0x0开始那么自然也要把向量放在这个位置代码,7x256上电以后默认bootmemory映射从flash开始也就是说,把向量放在0x即可解决这样的问题

当0x被占用以后,bootloader的向量问题解决了那用户代码的中断向量怎么办呢?不可能把bootloader的向量擦了把用户自己的向量写入,那岂不是bootloader也完了这里有个小技巧,如果用户程序从0x开始向量依然从这个位置代码开始。只不过在打开中断,向量真正起作用前将0x這个地方向量到SRAM的首地址上,然后切换BootMemory映射SRAM那么向量依然从0x0开始。这样的话无论多少级boot代码,都可以完美的解决该问题

ARM9除了以上的方法,还有个终极的利器那就是MMU,你高兴放哪就放哪在向量起作用之前,用MMU将其地址变换为0即可一点技术含量都没有。

道理总是简單的实现起来总是有点点弯弯绕。我们看看实际的实现吧这是7x256的向量代码:

这里相对比较简单,对这个指令做一下解释LDR PC,[PC,#24]是将当前PC+24的哋址的值载入到PC寄存器中。由于ARM流水线的问题当前执行的指令,地址已经是后面两条了所以,是+24并不是+32也就是把_program_start加载入PC指针里。这段代码已经消除了指令当前位置代码对跳转位置代码的影响可以随意的拷贝到任意的地方去执行。这段代码放在0x200000地方可以正常执行;放在0x100000地方也可以正常执行。

Rtems是个复杂的操作系统在汇编代码里安装的只是一个简单的复位向量。其它向量都只是简单的死循环操作系統运行起来以后,还要再次安装向量的向量指向操作系统的复杂的处理函数。但不管这些向量存储的地址是没有改变的。Link脚本上可以看到向量被放在内部的SRAM的首地址上(CSB337)

连接器虽然把位置代码空出来了,但连接器依然不知道将vector_block放到什么位置代码怎么办?这里的代码解釋了一切

Gnu的工具链并不针对某一个具体的平台。所以解决方案从某种意义上说更具有普遍意义。先调用mmu_init这是干什么,实际上是将MMU初始化将我们定义的.base地址放到0x0位置代码去。然后紧接着下面的几行代码是将上面的中断向量到0x0位置代码去。一共64个字节实现4GB内的地址絕对跳转。

我要回帖

更多关于 位置代码 的文章

 

随机推荐