韦东山视频观后感
来源:互联网 发布:windows命令行常用命令 编辑:程序博客网 时间:2024/04/29 03:15
一:
DDR=Double Data Rate双倍速率同步动态随机存储器。严格的说DDR应该叫DDR SDRAM,人们习惯称为DDR,
现在我们来分析一下DDR的初始化
一个程序分为:代码段、数据段、BSS段
代码段:指令之类的东西
数据段:有初始值并且初始值不为0的全局变量或者静态变量
BSS段:初始值为0或者无初始值的全局变量和静态变量例如:
volatile int i = 0;
volatile int j = 0x12345678;
volatile int k = 0;
volatile int g;
/* gpm0,1,2,3设为输出引脚 */
*gpmcon = 0x1111;
i、k、g存在于BSS段里面
j存在于数据段里面
而对于*gpmcon = 0x1111;来说合适这存在于代码段中
先对程序的烧写了解一下:
1、 我们的程序一开始是烧写在nand flash上的
2、 当我们设置为nand启动后,6410片内有8K的内存,CPU会通过内部硬件将nand flash 前8K的内容复制到RAM(起始地址为00000000)中去执行。
现在有一个问题就是我们写的程序超过了8K怎么办呢?
如果我们的程序超过了8K的话,那我们就需要用到DDR了,然后把整个程序拷贝到DDR中去,那么我们把程序拷贝到DDR的哪个地方呢,我的DDR有256M的空间,这时候就需要用到链接地址了,也就是会把程序复制到链接地址去。
举个链接脚本的例子吧。
SECTIONS //表示段
{
. = 0x5000; /**. 表示当前地址,给它赋地址为0x5000也就是整个程序的链接地址**/
.text: { /** .text 段名自己可以任意修改 ********/
start.o /** start.o表示整个start.o文件(包括代码、数据、BSS段)**/
*(.text) /** 存放其他所有文件的代码段 **/
}
.data: { /** 数据段**/
*(.data) /** 其他所有文件的数据段**/
}
bss_start =.; /*定义变量,并且给变量bss_start赋值为当前地址(当前地址就是顺序排放下来的地址) */
.bss: {
*(.bss) /** 其他所有文件的Bss段**/
}
bss_end = .; /** 定义变量,并且给变量bss_end赋值为当前地址,同样当前地址就是顺序排放下来的地址最后一个bss之后的地址6 **/
}
注释已经非常详细
重定位:关于重定位的理解,我们刚才已经说了
当我们设置的链接地址不在0x0000000的时候(比方说0x50000000)就需要进行重定位,即:在硬件把原来的程序复制到内部8K的RAM中之后,因为链接地址不在0x00,所以重定位功能就会将程序复制到起始地址为0x50000000的位置去
显然在重定位完成之前,肯定也要运行一段代码,那么为什么这段代码能够运行呢,这就涉及到另外一个概念----位置无关码,因为使用位置无关码(所谓的位置无关码就是任意连接位置都能够运行的)写的
位置无关码的使用:
1、 跳转的时候使用相对指令b、bl
2、 不访问全局变量、静态变量
总结一下:
1、 程序运行的时候应该位于它的链接地址;假设它的链接地址为0x50000000
2、 硬件决定了程序一开始从0开始运行,所以需要用到重定位(前面一小段代码把程序复制到链接地址)
3、 前面一小段代码为何能运行,因为用的是位置无关码(b、bl指令)
最后来分析一下整个程序的启动过程:
1. 假设我们把生成的axf映像文件烧写到nand flash中去,设置的链接地址为0x00000100
2. 一上电片内硬件自动把8K拷贝到OK6410片内内存中
3. 然后从地址零处开始运行
4. 接着重定位将程序转移到链接地址处
5. 最后使用位置相关码BL跳转到连接处执行就OK了.
二:http://blog.csdn.net/ustc_dylan/article/details/6965330
位置无关代码(PIC)的思考
应用程序必须经过编译、汇编和链接后才变成可执行文件,在链接时,要对所有目标文件进行重定位(relocation),建立符号引用规则,同时为变量、函数等分配运行地址。当程序执行时,系统必须把代码加载到链接时所指定的地址空间,以保证程序在执行过程中对变量、函数等符号的正确引用,使程序正常运行。在具有操作系统的系统中,重定位过程由操作系统自动完成。 在设计Bootloader程序时,必须在裸机环境中进行,这时Bootloader映像文件的运行地址必须由程序员设定。通常情况下,将Bootloader程序下载到ROM的0x0地址进行启动,而在大多数应用系统中,为了快速启动,首先将Bootloader程序拷贝到SDRAM中再运行。一般情况下,这两者的地址并不相同。
首先来看下面的链接脚本文件:
- ENTRY(_start)
- ;指定输出可执行文件的起始代码段为_start.
- SECTIONS
- {
- .= BOOTADDR ; bootloader的开始地址/
- .= ALIGN(4); 代码以4字节对齐
- .text :;指定代码段
- {
- cpu/arch/start.o (.text) ; bootloader中的text段
- *(.text) ;其它text段
- }
- .= ALIGN(4)
- .rodata :{*(.rodata)};指定只读数据段
- .= ALIGN(4);
- .data :{*(.data)};指定读/写数据段
- .= ALIGN(4);
- __bss_start =.; 把__bss_start赋值为当前位置,即bss段的开始位置
- .bss :{*(.bss)}; 指定bss段
- _end =.; 把_end赋值为当前位置,即bss段的结束位置
- }
需要指出的是,链接脚本中所描述的输出段地址为虚拟地址VMA(VirtualMemoryAddress)。这里的“虚拟地址”仅指映像文件执行时,各输出段所重定位到相应的存储地址空间,与映像文件烧写到的实际的地址无关(即映像的加载地址)。因此,上面的链接脚本实际上指定了Bootloader映像在执行时,将被重定位到BOOTADDR开始的存储地址空间,以保证在相关位置对符号进行正确引用,使程序正常运行。
假设这里指定BOOTADDR= 0x0。以ARM为例,ARM处理器复位后总是从0x0地址取第1条指令,因此只需把BOOTADDR设置为0,再把编译后生成的可执行二进制文件下载到ROM的0x0地址开始的存储空间,程序便可正常引导;但是,一旦在链接时指定映像文件从0x0地址开始,那么Bootloader就只能在0x0地址开始的ROM空间内运行,而无法拷贝到SDRAM空间运行实现快速引导。当然,搬运代码最后的跳转语句可以写成绝对地址,如jmp 0x10000,这样可以正确的跳到RAM中的0x10000地址处,但当执行继续执行碰到其他符号地址计算,或全局数据访问的时候,由于此时不是位置无关代码,此时地址的计算需要查询map表,但是map表中的地址仍然在ROM空间中,所以还会跳回ROM空间,另外,还会有其他问题,如动态内存申请等。
有了位置无关代码,只需修改链接脚本文件的BOOTADDR=0x10000即可,即将整个镜像文件都映射到RAM空间,但是bootloader最开始的搬运代码必须是位置无关的代码,这样虽然搬运代码被映射到RAM地址空间,但它在0x0开始的ROM中也能正确执行,搬运代码最后的跳转语句就可以跳转到某个标号了,因为此时标号的地址已经被映射到了ram空间,之后的代码执行将没有任何问题。
当然,可以将搬运代码和搬运完成跳转到的代码分段映射,即搬运代码映射到ROM地址空间,其他代码映射到RAM空间。但是这样会存在一个问题:生成的bin文件变得非常大。生成的bin文件将会按照映射到地址空间来生成,如果ROM空间与RAM空间地址不连续,假设ROM地址空间为0x0 ~ 0x1000 , RAM地址空间为0x10000~0x20000,那么, 0x1000~0x10000之间的地址空间都被填充为0,除非在生成bin文件时重新进行拼装。
如何编写位置无关代码呢?
引用同一位置无关段或相对位置固定的另一位置无关段中的符号时,必须是基于PC的符号引用,即使用相对于当前PC的偏移量来实现跳转或进行常量访问。
1.位置无关的程序跳转。使用相对跳转指令实现程序跳转。指令中所跳转的目标地址用基于当前PC的偏移量来表示,与链接时分配给地址标号的绝对地址值无关,因而代码可以在任何位置进行跳转,实现位置无关性。
2.位置无关的常量访问。在应用程序中,经常要读写相关寄存器以完成必要的硬件初始化。为增强程序的可读性,利用EQU伪指令对一些常量进行赋值,但在访问过程中,必须实现位置无关性。
3. 使用绝对地址进行跳转,一般是在不同的位置无关代码段之间跳转。
最后,总结一下位置无关代码段的优点:
1.简化设计,方便实现系统的快速引导。位置无关代码可以避免在引导时进行地址映射,并方便地跳转到RAM中实现快速引导
2.实现复位处理智能化。位置无关的代码可以被加载到任意地址空间运行
3.便于调试。Bootloader的调试通常也是一个繁琐的过程,使用位置无关代码,则可以将映像文件加载到RAM中进行调试,这既能真实地反映程序从ROM中 进行系统引导的情况,又可以避免频繁烧写程序存储器
- 韦东山视频观后感
- 韦东山视频 笔记
- 韦东山视频
- 驱动浅析(观看韦东山视频)
- 韦东山视频实验之触摸屏
- 韦东山视频实验之Nand驱动
- 韦东山视频实验之Nor驱动
- 韦东山视频实验之虚拟网卡
- 学习韦东山老师视频心得
- 韦东山视频第1期 学习计划
- 韦东山第二期视频之心得体会
- 韦东山视频第二期之心得体会
- 学习韦东山视频心得(一)
- 学习韦东山视频心得(二)
- 学习韦东山视频心得(三)
- 韦东山视频心得体会之矢量字体
- 内核启动流程分析(基于韦东山视频修改)
- 内核启动流程分析(基于韦东山视频修改)
- 视频 log
- The method setCharacterEncoding(String) is undefined for the type HttpServletResponse
- 纯C语言INI文件解析
- javascript内部原理篇[进入上下文之前javascript所做的工作]
- The End!2013年中国互联网行业巨头的喜与忧
- 韦东山视频观后感
- 并发协程goroutine
- setWindowFlags(Qt::FramelessWindowHint);使得窗体透明的问题解决
- android 遮罩层效果
- 在Linux系统环境下修改MySQL的root密码
- Android布局类型资源(一)---color、string、dimen
- Github for Windows使用介绍
- thinkphp命名规则
- 一种基于java语言的模板引擎velocity的使用