ARM裸板开发过程,程序的链接地址设置为为0x30000000,而前期的启动代码以及相关硬件的初始化代码需要在内部iRAM(steppingstone,起始地址0x0)的4K中运行。链接地址与运行地址(程序启动后PC从0x0位置执行)不一致时,不能出现位置相关代码。文中主要针对 SDRAM 初始化程序地址无关码问题进行了简单的分析。
(本文的由来是我在学习韦东山系列 ARM 裸板开发过程遇到的一个问题所引发的。在虚拟内存(MMU)操作部分,他提到了 SDRAM 初始化过程应该用位置无关的代码实现,方式是直接对SDRAM的寄存器组赋常量值。不过在解释为什么这样实现就是位置无关的过程,并没有解释清楚,带着这样的疑问便有了以下的分析过程。)
 
1、位置相关的初始化过程
下面的初始化过程,由于使用数组存储常量值而产生了位置相关的代码。
               
对于数组常量初始值的声明unsigned long const mem_cfg_val,不论此处是否有const关键字,数组元素均作为常量存储在常量数据区(两者反汇编代码完全一致)。初始化代码的反汇编如下:
               
通过分析这部分代码可知,数组中的常数变量的起始地址存储在地址为0x30000100内存中,即300002d0。该地址处的内容如下图示,可见其与上述C代码的数组常量值保持一致。上面大括号处的代码则完成了将这些常量值从常量数据区copy到栈区的过程。这个过程之所以是位置相关的,关键代码在于 ldr    r3, [pc, #136]    ; 30000100 <first+0x100>
                     

2、位置无关的初始化过程
下面是位置无关的初始化代码。该过程通过直接将初始值写入寄存器的方式,避免了对常量值的单独存储,直接将其融入代码段的二进制指令中。
               
反汇编之后,如下:
                   
通过分析可知,该初始化代码主要通过 r0, r1, r2, r3, ip 等5个寄存器来存放初始值并完成写入SDRAM寄存器组的任务。首个初始值的赋值操作,str r1, [r3],即p[0] = 0x22011110;为了将 0x22011110 存入 r1,共使用了3条汇编指令。由于ARM指令长度4字节的限制,不能直接对 r1 赋值为 0x22011110。其他操作与 r1 的过程类似。
整个初始化的过程并未出现对常量初始值在内存区绝对寻址的过程,故该初始化过程是位置无关的。

ARM裸板开发:04_MMU 链接地址与运行地址不一致时,(SDRAM)初始化程序地址无关码问题的分析的更多相关文章

  1. ARM裸板开发:07_IIC 通过IIC总线接口读写时钟芯片时间参数实现的总结

    问题一:程序直接在iRAM内部可正常执行,而程序搬移(Nand ->SDRAM)之后,就不能正常运行了 #define NAND_SECTOR_SIZE 2048 /* 读函数 */ void ...

  2. 关于在arm裸板编程时使用printf问题的解决方法

    在ARM裸板驱动编程中,是不允许程序直接调用C库程序的.为什么呢?因为此时kernel还没有被加载,所以在封装在kernel层的C库的API是用不了的,那怎么办? 在开发过程中,printf的功能我不 ...

  3. arm裸板驱动总结(makefile+lds链接脚本+裸板调试)

    在裸板2440中,当我们使用nand启动时,2440会自动将前4k字节复制到内部sram中,如下图所示: 然而此时的SDRAM.nandflash的控制时序等都还没初始化,所以我们就只能使用前0~40 ...

  4. 第8课.第一个ARM裸板程序(点亮led)及申引

    1.原理图 2.芯片手册 3.几条汇编代码 1.ldr:读内存 ldr R0, [R1] 假设R1的值是x,读取地址x上的数据(4字节),保存到R0中 ldr R0, =0x12345678 (4字节 ...

  5. 对arm裸板调试的理解

    由于arm芯片一般都包含的由jtag调试这项功能,cpu向外部发出信号时,一般都要同jtag发送出去,它就像一个路口的交警一样,能够控制车辆的运行,当然在arm中指的是cpu发出的数据和地址,我们在调 ...

  6. ARM裸板调试思路总结、笔记

    1. 点灯 2. 串口打印 3. JTAG调试器3.1 命令行调试 3.2 源码级别的调试前提a. 程序必须已经重定位好,位于它的链接地址a.1 如果程序的链接地址是SDRAM, 使用openocd初 ...

  7. 【ios开发之疑难杂症】xcode运行出现SpringBoard 无法启动应用程序(错误:7)

    问题:xcode运行出现SpringBoard 无法启动应用程序(错误:7) 解决方案: 重启模拟器

  8. 【嵌入式开发】 嵌入式开发工具简介 (裸板调试示例 | 交叉工具链 | Makefile | 链接器脚本 | eclipse JLink 调试环境)

    作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42239705  参考博客 : [嵌入式开发]嵌入式 开发环境 (远 ...

  9. 【arm学习】我的第一个裸板程序

    初学ARM感觉写个裸板程序还真的不容易,可能是没有用到ADS,keil之类的开发平台的缘故吧.编译,链接过程在linux平台上完成,这样学起来更有实感,还能顺便熟悉linux环境,以及命令,何乐而不为 ...

随机推荐

  1. CSU 1805 Three Capitals(矩阵树定理+Best定理)

    http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1805 题意: A和B之间有a条边,A和G之间有b条边,B和G之间有c条边.现在从A点出发走遍所 ...

  2. hdu 5671 Matrix 标记。。。有点晕

    Matrix Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem ...

  3. 转载:Nginx负载均衡的5种策略

    nginx可以根据客户端IP进行负载均衡,在upstream里设置ip_hash,就可以针对同一个C类地址段中的客户端选择同一个后端服务器,除非那个后端服务器宕了才会换一个. nginx的upstre ...

  4. Android之动态改变控件大小

    利用getLayoutParams()方法和setLayoutParams()方法.三步曲:1.首先利用getLayoutParams()方法,获取控件的LayoutParams.eg:LayoutP ...

  5. 雷林鹏分享:Ruby 方法

    Ruby 方法 Ruby 方法与其他编程语言中的函数类似.Ruby 方法用于捆绑一个或多个重复的语句到一个单元中. 方法名应以小写字母开头.如果您以大写字母作为方法名的开头,Ruby 可能会把它当作常 ...

  6. [Java学习] Java类的基本运行顺序

    我们以下面的类来说明一个基本的 Java 类的运行顺序: 1. public class Demo{ 2. private String name; 3. private int age; 4. 5. ...

  7. codeforces 497c//Distributing Parts// Codeforces Round #283(Div. 1)

    题意:有n个区间[ai,bi],然后有n个人落在[ci,di],每个人能用ki次.问一种方式站满n个区间. 两种区间都用先x后y的升序排序.对于当前的区间[ai,bi],将ci值小于当前ai的全部放入 ...

  8. hdu5730 分治fft

    题意:\(dp[n]=\sum_{i=1}^ndp[i]*a[n-i]+a[n]\),求dp[n], 题解:分治fft裸题,就是用cdq分治加速fft,因为后面的需要用到前面的dp来算,不可能每次都f ...

  9. hdu-1849-nim模板

    Rabbit and Grass Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  10. Oracle11g温习-第六章:控制文件

    2013年4月27日 星期六 10:33  .控制文件的功能和特点 1) [定义数据库当前物理状态] 2) [维护数据的一致性]  如果控制文件中的检查点与数据文件中的一致,则说明数据一致,可以启动到 ...