好文档就是一把金锄头!
欢迎来到金锄头文库![会员中心]
电子文档交易市场
安卓APP | ios版本
电子文档交易市场
安卓APP | ios版本

连接脚本相关.docx

4页
  • 卖家[上传人]:桔****
  • 文档编号:555331518
  • 上传时间:2023-06-12
  • 文档格式:DOCX
  • 文档大小:15.66KB
  • / 4 举报 版权申诉 马上下载
  • 文本预览
  • 下载提示
  • 常见问题
    • 连接脚本相关知识一个程序本质上都是由bss段、data段、text段三个组成的这样的概念,不知道最初来源于哪里的规定, 但在当前的计算机程序设计中是很重要的一个基本概念而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式 系统运行时的内存大小分配,存储单元占用空间大小的问题BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域BSS是英文 Block Started by Symbol的简称BSS段属于静态内存分配用于存放没有被初始化的或者初始化为0的全局变 量和静态变量数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域数据段属 于静态内存分配用于存放已经初始化过的(且初始化值不为0)的全局变量和静态变量代码段:代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域这部分区域 的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序 在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等堆(heap):堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。

      当进程调 用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时, 被释放的内存从堆中被剔除(堆被缩减)栈(stack):栈又称堆栈,是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}中定义的变量(但 不包括static声明的变量,static意味着在数据段中存放变量)除此以外,在函数被调用时,其参数也会被压入 发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中由于栈的先进先出特点,所以栈 特别方便用来保存/恢复调用现场从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区 SECTIONS 〃该链接脚本,就是用来对bss段、data段、text段进行有效的排版的!!{.=0x00000000;.text : {*(.text)} 〃冒号:两边一定要有空格!!!!!!!.=0x32000000;.data : {*(.data)}__bss_start =.;.bss : { *(.bss) }_end =.;}注意:1.若为nor flash启动,为什么.=0x32000000不能够改成.=0x1000呢?那是因为nor flash的只读不写的特 性决定了的,当程序再次初始化bss中的全局变量的时候,是不可能完成的!!!!!2. 一般bss段是紧跟在data段后面的! ! ! !问:怎么理解一个连接地址?答:以一个没有被初始化的变量i为例子(在编译的时候,它会被归为BSS段的):a. 当连接地址指定为0x00000000时,那么编译的时候,编译器给i分配的地址可能是0x00000000后一小段 的的某个地址(查看反汇编可以得知);b. 当连接地址指定为0x30000000时,那么编译的时候,编译器给i分配的地址可能是0x30000000后一小段 的的某个地址(查看反汇编可以得知);c. 所以,可以感悟出,如果我们的连接地址是0x300000000,而我们在没有重定位之前,想去访问这个i变 量,那绝对会失败的。

      总结:1. 程序运行时,“应该”位于它的连接地址;2. 但是由于硬件的特性决定,程序最开始执行时,是从0x0地址开始的,所以,再最开始的几段代码里面,需要 实现重定位,这几段代码实现把程序拷贝到连接地址去,然后执行,如果不拷贝到连接地址去,那么将得不到理 想的上述的i变量;3. 既然程序应该从连接地址开始运行,那么为什么,上述的最前面的代码却可以运行呢?因为最前面的代码都是 使用的是位置无关码位置无关码--相对寻址和绝对寻址相对寻址:用到的指令:bl, b, adr指令bl, b 的反汇编:add r0, pc, #num解释:pc等于相对与当前pc+一个num数的偏移地址,相对与当前pc的一个跳转,这就是相对跳转adr 的反汇编:sub,r0,pc,#num解释:r0等于相对与当前pc减去一个num数的偏移地址,就得到程序真正从哪里开始执行的地址了,那个 num的值,是由编译器决定的注意:因为bl, b,adr只能跳转+-32MB,所以他不能够完成大的跳转(从0x04跳转到0x30000000) ! !所以一 般使用相对寻址指令时,使用的地址,任然是ram中的地址;绝对寻址:用到的指令:ldr pc, =main它的反汇编:ldr pc, [pc, #num]解释:pc等于(当前pc的地址加上一个偏移num地址后得到的相对地址)中取取到的地址数据。

      这个数据会 是由(-Ttext连接地址)指定的连接地址后边的地址! !这时候便实现了大跳转(如从0x04跳转到0x30000000) ! ! ! 因此在内存没有初始化好,或者还没有重定位之前,就执行这样的绝对寻址,那么将得不到想要的数据,那么程 序就会因此而死掉!!!问:什么是位置无关码?答:问:位置无关码,到底是用来实现相对寻址,还是绝对寻址的呢?答:位置无关码,是用来实现相对寻址的!问:怎么使用位置无关码?答:a.使用相对寻址的指令;b. C语言中不使用全局变量,静态变量问:为什么不能够使用全局变量,静态变量?答:不能使用全局变量的原因是这样的:我们的裸编程序在链接(arm-linux-ld)的时候,会进行重定位,建立符号规则,为变量,函数分配运行地址,也 就是我们在链接脚本里定义的0x30000000这个地址但问题就来了,如果我们在初始化这个阶段(也就是还没重定位到sdram之前)使用了全局变量,那么这个全局 变量的运行地址会被映射到SRAM中,这个不好的地方就是,即便以后ldr pc,=main之后跳到0x30000000地址 上去了,但在这个地址上如果要访问这个全局变量,这个变量就要在映射表中查询,发现这个变量还在SRAM 中,那么程序就会跳回到SRAM中,这个不是我们希望的。

      所谓的映射是:在编译的时候,会有个映射表,里边存的是变量,函数的地址这样当程序运行的时候,cpu方 便在表中查询相应的变量,函数地址注意:局部变量是在栈里的,而不是在这个映射表里面,所以初始化的程序里有ldr sp, =4096,是为了设置sram 的栈空间,用于保存局部变量等结论:所以我们不要在重定位之前在映射表中留有变量的痕迹,也就是说不要使用全局变量例如:(注意对比!!)例1:lowlevel_init:/* memory control configuration *//* make r0 relative the current location so that it *//* reads SMRDATA out of FLASH rather than memory ! */Idr r0, =SMRDATA //注意:用的是绝对寻址!!!!ldr r1, _TEXT_BASEsub r0, r0, r1 〃因为用的是绝对寻址,所以这里要做这样的操作!!!!!ldr r1, =BWSCON /* Bus Width Status Controller */add r2, r0, #13*40:ldr r3, [r0], #4str r3, [r1], #4cmp r2, r0bne 0b/* everything is fine now */mov pc, lr.ltorg/* the literal pools origin */SMRDATA:.word(0+(B1_BWSCONvv4)+(B2_BWSCONvv8)+(B3_BWSCONvv12)+(B4_BWSCONvv16)+(B5_BWSCONvv20)+(B6_BWSCON<<24)+(B7_BWSCON<<28)).word((B0_Tacsvv13)+(B0_Tcosvv11)+(B0_Taccvv8)+(B0_Tcohvv6)+(B0_Tahvv4)+(B0_Tacpvv2)+(B0_PMC)).word((B1_Tacsvv13)+(B1_Tcosvv11)+(B1_Taccvv8)+(B1_Tcohvv6)+(B1_Tahvv4)+(B1_Tacpvv2)+(B1_PMC)).word((B2_Tacsvv13)+(B2_Tcosvv11)+(B2_Taccvv8)+(B2_Tcohvv6)+(B2_Tahvv4)+(B2_Tacpvv2)+(B2_PMC)).word((B3_Tacsvv13)+(B3_Tcosvv11)+(B3_Taccvv8)+(B3_Tcohvv6)+(B3_Tahvv4)+(B3_Tacpvv2)+(B3_PMC)).word((B4_Tacsvv13)+(B4_Tcosvv11)+(B4_Taccvv8)+(B4_Tcohvv6)+(B4_Tahvv4)+(B4_Tacpvv2)+(B4_PMC)).word((B5_Tacsvv13)+(B5_Tcosvv11)+(B5_Taccvv8)+(B5_Tcohvv6)+(B5_Tahvv4)+(B5_Tacpvv2)+(B5_PMC)).word ((B6_MTvv15)+(B6_Trcdvv2)+(B6_SCAN)).word ((B7_MTvv15)+(B7_Trcdvv2)+(B7_SCAN)).word ((REFENvv23)+(TREFMDvv22)+(Trpvv20)+(Trcvv18)+(Tchrvv16)+REFCNT).word 0xb1.word 0x30.word 0x30例2:memsetup:@设置存储控制器以便使用SDRAM等外设mov r1, #MEM_CTL_BASE @存储控制器的13个寄存器的开始地址adrl r2, mem_cfg_val @这13个值的起始存储地址(注意:用的是相对寻址!!!!!)add r3, r1, #52 @ 13*4 = 541:ldr r4,[r2], #4@读取设置值,并让r2加4str r4,[r1], #4@将此值写入寄存器,并让r1加4cmp r1,r3@判断是否设置完所有13个寄存器bne 1b@若没有写成,继续mov pc,lr@返回.align 4mem_cfg_val:@存储控制器13个寄存器的设置值.long0x22011110@ BWSCON.long0x00000700@ BANKCON0.long0x00000700@ BANKCON1.long0x00000700@ BANKCON2.long0x00000700@ BANKCON3.long0x00000700@ BANKCON4.long0x00000700@ BANKCON5.long0x00018005@ BANKCON6.long0x00018005@ BANKCON7.long0x008C07A3@ REFRESH.long0x000000B1@ BANKSIZE.long0x00000030@ MRSRB6.long0x00000。

      点击阅读更多内容
      关于金锄头网 - 版权申诉 - 免责声明 - 诚邀英才 - 联系我们
      手机版 | 川公网安备 51140202000112号 | 经营许可证(蜀ICP备13022795号)
      ©2008-2016 by Sichuan Goldhoe Inc. All Rights Reserved.