最近,我有努力学习《深入浅出嵌入式底层软件开发》。我自我觉得这本书很好。如果你有一块Mini2440的开发板,那就再好不过了。

学了点东西,写点总结。以下是我在做 Page130,2.6.8内存驱动实验总结。

我按照书上的指示,完成了代码的编写。对项目作如下配置:

上述的配置中 -ro-base 0x30000000 告诉Linker,本程序将被加载到 0x30000000 上运行。

实验程序的功能是,程序最初是在0x00000000 地址上开始运行。它初始化SDRAM后,将自己复制到0x30000000地址上,然后跳到SDRAM中运行。

第一个问题:我在用AXD进行调试时,总是发现程序运行到 copyallloop 中死掉。

copyallIMPORT  |Image$$RO$$Base|    IMPORT  |Image$$RW$$Limit|    ldr r0, = |Image$$RO$$Base|   ldr r1, = |Image$$RW$$Limit|   ldr r2, = 0x00000000   copyallloopteq r0, r1   beq quitcopy   ldr r3 , [r2], #4   str r3 , [r0], #4        b copyallloop
quitcopymov pc, lr

copyall函数的功能是将 0x00000000 地址上的所有程序代到复制到SDRAM的 0x30000000 地址上去。可是总是在copyallloop 循环中死掉。

结果查看寄存器才知道,知道程序开始并没有被加载到0x00000000的地址上,而是被加载到SDRAM中。如下是程序开始运行时,各寄存器的值:


    由此可以得知,PC的初始值为0x3000005C,而不是PC = 0x00000000。说明调试时程序被加载到SDRAM中运行。

这么一来,那么将0x00000000地址区间的数据考到0x30000000地址上来,而程序自身就运行在0x30000000地址上。这样一来,复制的数据将程序自己给覆盖了。难怪要死在那里。

在进入copyallloop之前,反汇编如下:

当r0 = 0x3000000D0时:

此时,0x300000D0之前的指令已被更改。所以,死在这里了。

第二个问题:为什么xmain()函数被放在0x0000地址上,而不是start呢?

令我奇怪的是,程序开始执行时,PC并不等于0x00000000,而是另一个值。如下所示:

可见,图中所示A处,PC并不等于0x0000,而是0x005C。不对呀!ARM核启动不是多0x0000开始的吗?怎么成了0x005C呢?再看D处,start启动程序被放到了0x005C的位置。而放在 0x0000 地址上的指令则是xmain函数入口,见C处。

当我退出调试模式,直接复位运行。我发现,程序只在反复运行 xmain() 函数。而没有执行start处初始化相关的指令。可见ARM复位后,还是从0x0000地址上开始执行的。

那么,为什么编译器要把 xmain 放在0x0000地址上,而不是 start 呢?我详细地对比了书上的配置界面的各项设置。发现在 Equivalent Command Line 栏中,我少写了 "-first init.o" 这句话的意思就是说,把init.o目标文件的代码放在首位。正确的命令串为:

-info totals -ro-base 0x30000000 -first init.o

修改配置后,重新编译。在AXD中查看其反汇编代码,如下:

这样以来,start就被放到了前面了。

第三个问题:如何完成实验?

现在,我把 RO Base设置成了0x30000000 ,只要一进入调试模式,AXD就自动将我的代码加载到了 SDRAM 的 0x30000000 地址上了。

按照书中的要求,代码应该被烧录到 0x00000000 地址上(Nor Flash)中才对。而且工程编译后又没有bin或hex文件,也没法直接用H-Flasher烧。

(1)我该怎么让代码在调试时烧到 0x00000000 上,而不是 0x30000000上。
    (2)如何让工程在编译时生成烧录文件。

关于生成bin文件方法:

1. DebugRel Settings->Linker->ARM fromELF->Output format指定Plain binary->Output file name 路径

2. DebugRel Settings->Target->Post-Linker中选择ARM fromELF

3. 重新Make,就会生成bin文件。

ARM9学习笔记之——SDRAM实验相关推荐

  1. STM32学习笔记:按键实验

    STM32学习笔记:按键实验 一.所使用的函数 1.时钟使能函数 RCC_APB2PeriphClockCmd(uint32_t RCC_APB2Periph, FunctionalState New ...

  2. ARM9学习笔记之——MMU

    我记得有一次我去应聘ARM-Linux软件工程师.结果被问到ARM中的虚拟内存是怎么管理的.由于我只对X86平台下的MMU了解,所以我被问倒了.原来我所学的只是皮毛.还有很多东西值得我去深入.要做AR ...

  3. 唤醒手腕Python全栈工程师学习笔记(微机实验篇)

    01.树莓派安装操作系统 官网下载网址:https://www.raspberrypi.org/downloads/ 官网为不同的电脑操作系统提供了烧录软件,大家可以根据不同的操作系统下载对应软件.而 ...

  4. ZYNQ学习笔记——高速ADDA实验

    文章目录 高速AD/DA实验 AD/DA原理 分类 高速AD/DA简介 硬件设计 程序设计 顶层模块(hs_ad_da) AD 数据接收模块 DA数据发送模块 遇到的问题 高速AD/DA实验 AD/D ...

  5. MIT 6.828 学习笔记4 Lab2实验报告

    Lab2实验报告 Execrise 1 static void *boot_alloc(uint32_t n) {static char *nextfree;char *result;if (!nex ...

  6. ANSYS学习笔记——汽车绕流实验

    2D平面汽车模型绕流实验 ICEM建模和画非结构网格 #打开ICEM,File->change working directory setting->C盘,确定(软件第一次使用时需要进行这 ...

  7. 电路基础学习笔记6:实验验证戴维南定理

    一.实验目的 1.验证戴维南定理的正确性,加深对该定理的理解. 2.掌握测量有源二端网络等效参数的一般方法. 二.原理说明 任何一个线性有源网络,如果仅研究其中一条支路的电压和电流,则可将电路的其余部 ...

  8. Linux驱动学习笔记 -- 驱动总线实验

    驱动总线 在Linux系统中,除了硬件总线,还有一种软件虚拟出来的总线 – 驱动总线bus 这种驱动总线的作用:软件与硬件代码分离,提高程序的复用性 驱动总线分三个部分: 三者都是在/include/ ...

  9. PHP实训笔记,【学习笔记19】实验吧 让我进去

    知识点 MD5拓展攻击 解题思路 打开网站后看到,什么都没有,尝试抓包分析 360截图17860604827894.PNG Burp 抓包发现,Cookie有东西.先是把source=0改成sourc ...

  10. 正点原子stm32F407学习笔记3——蜂鸣器实验

    一.硬件设计 蜂鸣器为有源蜂鸣器,当 PF.8 输出高电平的时候,蜂鸣器将发声,当 PF.8 输出低电平的时候,蜂鸣器停止发声,硬件原理图如下 二.软件设计 1.新建beep.c文件 打开keil软件 ...

最新文章

  1. linux中的fg命令
  2. python二十:内置函数
  3. 【MASHIII调制器】MASHIII调制器的Simulink建模与仿真
  4. 【机器学习基础】前置知识(四):一文掌握Pandas用法
  5. [剑指offer]面试题13:在O(1)时间删除链表结点
  6. node 获取mysql数据类型,node连接mysql获取数据
  7. EPTP 和 EPT 分页结构条目的格式
  8. BSGS-BabyStepGiantStep算法+拓展
  9. 不是我吹!超级全面的权限系统设计方案面世了
  10. 360深度实践:Flink 与 Storm 协议级对比
  11. Json转换为Model,Struct,Class对象 Swift
  12. 来自IT公司速查手册的各大IT公司薪资和待遇内幕
  13. 梳理需求-需求调研报告
  14. 全面了解三极管——三极管基本参数2
  15. 实证研究使用正交化和自助法寻找显因
  16. 关于博客的书写——读刘末鹏博客学习方法篇有感
  17. 最好的网络拓扑制作软件
  18. securecrt能输入命令吗?
  19. 大数据时代,我们必守的三条底线,大数据杀熟,不可忍
  20. Greenplum集群Master与Standby相互切换

热门文章

  1. 二维码QR码的“疯狂”广告
  2. Linux 内核--任务0的运行(切换到用户模式)move_to_user_mode
  3. 复杂对象ibatis插入,属性为list,怎么一次性插入
  4. 2019牛客多校第三场F Planting Trees(单调队列)题解
  5. centos7 修改语言为中文
  6. 使用openssl实现ECDSA签名以及验证功能(附完整测试源码)
  7. 纯CSS实现二级下拉导航菜单
  8. [hiho 10]由前序中序遍历求后序遍历
  9. WCF REST(9篇)
  10. 降低站长成本 推荐8个免费或低廉小型建站工具