您的位置 首页 系统

S3C2440发动代码中应用程序履行环境的初始化

一、基础知识我们编写的源文件(c或s)经过ARM编译器的编译生成ELF格式的目标文件(后缀名为o),目标文件经过ARM连

一、基础知识

咱们编写的源文件(.c 或.s)经过ARM 编译器的编译生成ELF 格局的方针文件(后缀名为.o),方针文件经过ARM 衔接器衔接今后生成ELF 格局的映像文件(后缀名为.axf),此刻的映像文件还包括一些调试信息,咱们还需求经过fromelf 东西将其转换成适合在ROM 或RAM 中运转的二进制代码(后缀名为.bin),这时生成的二进制映像文件就能够被烧写入方针板的ROM 或FLASH 中,当方针板上电后能够经过各种方式在ROM 或RAM 中运转。
一个可履行程序的映像文件由一个或多个域组成,域分为两种:一种是映像文件在存储器中寄存的地址,称为加载域;另一种是映像文件运转时的地址,称为运转域。每个域由一个或3 个输出段组成,每个输出段则由一个或多个输入段组成。输入段包括程序代码、现已初始化的数据、未经初始化的存储区、被初始化为0 的存储区,输入段据此可分为三种特点:RO(只读,包括代码和常量)、RW(可读可写,包括现已初始化的全局变量和静态变量)、ZI(未初始化的变量,需初始化为0), 衔接器依据特点将输入段分组,组成不同的输出段。一个输出段是有具有相同特点的输入段组成的,输出段的特点与其间输入段的特点相同,因而输出段也分为三种。域由不同特点的输出段组成,输出段在域中的摆放次序为RO 输出段排在最前,然后是RW 输出段,RW 输出段和RO 输出段能够不接连,最终是ZI 输出段,ZI 输出段是紧接着RW 输出段的(加载域只包括RO、RW 输出段,原因见后述)。
可履行镜像一开端一般是存储在体系的ROM 或FLASH 中,RO 段是只读的,在运转的时分咱们不能改动它,所以RO 段在运转的时分能够驻留在ROM 或FLASH 中,也能够复制到运转速度更快的RAM 中;RW 段在运转的时分,咱们需求对其读写,在运转前这一段有必要被复制至RAM 中;ZI 段为未初始化的全局变量段,只需求在程序运转之前树立ZI 并将其所在区域悉数清零即可,因而镜像装载域不必包括ZI 输出段,但在运转域需求包括ZI,而且ZI 有必要处于RAM。
经过以上阐明,咱们知道假如某个镜像只要RO 段的话,程序能够不必复制至RAM,可是假如程序包括RW 段的话,RW 段是必需求复制至RAM 中的,假如有必要的话还需在RAM 中创立ZI 段,并将其清零。为确保程序的正确履行,而进行必要的数据复制和清零,便是运用程序履行环境的初始化。

二、S3C2440发动的根本原理

Nand Flash发动

当S3C2440 开发板选用的是Nand Flash 发动,镜像一开端是存储在Nand Flash 中,而Nand Flash只能作为存储程序和数据之用,无法在其间运转程序,所以S3C2440 开发板发动代码中运用环境初始化这一步和上述过程稍有不同。S3C2440 镜像文件加载和运转时的地址映射联系如下图所示:
S3C2440 没有上电之前映像文件存储在Nand Flash 中,Nand Flash 有专门的操控器操控,不占用存储器BANK。当开发板上电时,Nand Flash 的前4K 被复制到S3C2440 芯片内部的一块容量为4K 的SRAM(被称为“Steppingstone”),然后这块SRAM 被映射到地址0x00000000 处,程序从此处开端运转。由于Nand Flash 中不能运转程序,所以在这4K 的代码中有必要包括一段代码将Nand Flash 中的程序复制至S3C2440 的SDRAM 中(0x30000000 开端)。运用环境初始化应该包括这段代码。
Nand Flash 中的映像文件被复制至从0x30000000 开端的SDRAM,这时分映像文件还没有真实被履行,此刻是加载状况,加载域如上图所示,包括一切RO 特点的输出段和RW 特点的输出段,ZI 特点的输出段此刻还不存在。在映像文件运转时,会生成3 个运转域,如上图所示,RO 和RW 特点的运转域的开端地址和加载时是相同的,所以在运用程序履行环境初始化中不需求对其进行复制,ZI 运转域则需求在映像开端被履行前树立并被初始化为0,所以运用程序履行环境初始化中也要包括这类代码。(留意:RO 和RW 特点的运转域的开端地址和加载时是相同的,即复制到SDRAM后就不必再移动了。ADS中设置的RO Base和RW Base决议了程序的链接地址)

Nor Flash发动

当S3C2440选用Nor Flash发动时,代码能够在上面直接运转。但为了运转的功率,仍是把程序复制到SDRRAM中运转。加载时地址联系和运转时地址联系和Nand Flash的根本类似。Nand Flash发动时,会将RO段和RW段一起复制到SDRAM中,然后再树立ZI段。从Nor Flash发动时是先复制RO段,然后再复制RW段,最终树立ZI段。

三、相关发动代码剖析

[plain]view plaincopy

print?

  1. ;一个arm程序是由R0,RW,ZI三个段组成。其间R0为代码段,RW是现已初始化的全局变量,ZI是未
  2. ;初始化的全局变量,发动代码要将RO段和RW段复制到RAM中并将ZI段清零。编译器运用下列变量
  3. ;来记载各段的开端地址和完毕地址。这些标号的值是经过编译器的设定来确认的如ADS中对ro-base和
  4. ;rw-base的设定。
  5. IMPORT|Image$RO$Base|;BaseofROMcode
  6. IMPORT|Image$RO$Limit|;EndofROMcode(=startofROMdata)
  7. IMPORT|Image$RW$Base|;BaseofRAMtoinitialise
  8. IMPORT|Image$ZI$Base|;Baseandlimitofarea
  9. IMPORT|Image$ZI$Limit|;tozeroinitialise
  10. ;===========================================================
  11. ldrr0,=BWSCON
  12. ldrr0,[r0]
  13. andsr0,r0,#6;经过判别OM[1:0]!=0,得知是NORFLashboot
  14. bnecopy_proc_beg;不必读取nandflash
  15. adrr0,ResetEntry;OM[1:0]==0,从NANDFLash发动
  16. cmpr0,#0;再比较进口是否为0地址处,假如不是则用了仿真器
  17. bnecopy_proc_beg;用仿真器的状况也不要用nandflash发动
  18. ;nop
  19. ;===========================================================
  20. nand_boot_beg;这一段代码完结从NAND读代码到RAM
  21. [{TRUE}
  22. blRdNF2SDRAM
  23. ]
  24. ldrpc,=copy_proc_beg;此刻的PC现已在0x30000000今后,是copy_proc_beg衔接时的地址
  25. ;这个标号下面的代码完结的功用便是把norflash的内容复制到ram傍边。
  26. ;===========================================================
  27. copy_proc_beg
  28. adrr0,ResetEntry;装载地址,ResetEntry值->r0
  29. ldrr2,BaseOfROM;BaseOfROM值
  30. cmpr0,r2;比较RO,R2
  31. ldreqr0,TopOfROM;假如持平的话(阐明在内存中运转),TopOfROM->r0当从NandFlash中发动时r0=r2,当从NorFlash发动时则不持平
  32. beqInitRam;一起跳到InitRam
  33. ;下面这个是针对代码在NORFLASH时的复制办法
  34. ;功用为把从ResetEntry起,TopOfROM-BaseOfROM巨细的数据拷到BaseOfROM
  35. ;TopOfROM和BaseOfROM为|Image$RO$Limit|和|Image$RO$Base|
  36. ;|Image$RO$Limit|和|Image$RO$Base|由衔接器生成为生成的代码的代码段运转时的起启和停止地址
  37. ;BaseOfBSS和BaseOfZero为|Image$RW$Base|和|Image$ZI$Base|
  38. ;|Image$RW$Base|和|Image$ZI$Base|也是由衔接器生成,两者之间便是初始化数据的寄存地放
  39. ldrr3,TopOfROM
  40. 0
  41. ldmiar0!,{r4-r7}
  42. stmiar2!,{r4-r7}
  43. cmpr2,r3
  44. bcc%B0
  45. subr2,r2,r3;这两句代码是修正字非对齐的状况,由于是按4个字节复制的,但RO段巨细不一定是4个字节对齐的
  46. subr0,r0,r2
  47. InitRam
  48. ldrr2,BaseOfBSS
  49. ldrr3,BaseOfZero
  50. 0
  51. cmpr2,r3
  52. ldrccr1,[r0],#4
  53. strccr1,[r2],#4
  54. bcc%B0;这一段是对ResetEntry里边界说好的数据复制到RW段。
  55. movr0,#0
  56. ldrr3,EndOfBSS
  57. 1
  58. cmpr2,r3
  59. strccr0,[r2],#4
  60. bcc%B1;初始化ZI段
  61. ldrpc,=%F2;gotocompileraddress
  62. 2
  63. ;[CLKDIV_VAL>1;meansFclk:Hclkisnot1:1.
  64. ;blMMU_SetAsyncBusMode
  65. ;|
  66. ;blMMU_SetFastBusMode;defaultvalue.
  67. ;]
  68. [:LNOT:THUMBCODE
  69. blMain;不要用main()由于main()是ADS默许进口,编译器会增加其他代码
  70. b.;跳转到Main不成功则挂起
  71. ]
  72. [THUMBCODE;forstart-upcodeforThumbmode
  73. orrlr,pc,#1
  74. bxlr
  75. CODE16
  76. blMain;Donotusemain()because……
  77. b.
  78. CODE32
  79. ]
  80. BaseOfROMDCD|Image$RO$Base|
  81. TopOfROMDCD|Image$RO$Limit|
  82. BaseOfBSSDCD|Image$RW$Base|
  83. BaseOfZeroDCD|Image$ZI$Base|
  84. EndOfBSSDCD|Image$ZI$Limit|

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/xitong/262369.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部