天嵌 ARM开发社区

 找回密码
 注册
查看: 5116|回复: 5

询问一下ADS工程中启动源程序2440init.s中的几行代码

[复制链接]
soder 发表于 2009-10-24 13:41:00 | 显示全部楼层 |阅读模式
看了一些资料和对ARM启动代码的解读。ARM如果从NAND Flash启动的话,会自动把NAND Flash的代码复制到BANK0地址0x00000000开始的4K空间中。
然后一般的做法是在这4K代码中会把代码搬到0x30000000开始的 SDRAM中去,这样程序执行的速度会快很多。

在2440init.s中关于启动和复制代码的关键的一段程序

;===========================================================   
    ldr    r0, =BWSCON
    ldr    r0, [r0]
    ands    r0, r0, #6        ;OM[1:0] != 0, NOR FLash boot
    bne    copy_proc_beg        ;do not read nand flash
    adr    r0, ResetEntry        ;OM[1:0] == 0, NAND FLash boot
;    cmp    r0, #0                ;if use Multi-ice,
;    bne    copy_proc_beg        ;do not read nand flash for boot
    ;nop
;===========================================================
nand_boot_beg
    mov    r0, #0
    ldr    r1, =ResetEntry
    mov    r2, #0x40000
    [ {TRUE}
        bl RdNF2SDRAM
    ]
    ldr    pc, =copy_proc_beg
;===========================================================
copy_proc_beg
    adr    r0, ResetEntry
    ldr    r2, BaseOfROM
    cmp    r0, r2
…………

其中nand_boot_beg这一段程序是调用nand_read.c中的RdNF2SDRAM函数,功能是从NAND Flash读取代码然后复制到SDRAM中去,完成之后就执行标号为copy_proc_beg的这一段代码。
copy_proc_beg的这一段代码作用也把启动代码、RO、RWs数据等复制到BaseOfROM开始的SDRAM中。一般在ADS中会把BaseOfROM设置成SDRAM中的一个地址。
不知道我上述的理解是否正确。
现在问题是
    1、如果从NAND启动的话,ARM的启动过程中把代码复制到SDRAM中去的过程执行了两遍!我觉得非常奇怪。
    2、copy_proc_beg这段代码完成之后,就是InitRam了,再之后就直接跳到Main了,我看不出程序怎么跳到0x30000000以上的区域执行代码的过程。ARM是怎么从0x0000 0000 启动执行第一条代码,然后到SDRAM中去执行程序的呢?


菜鸟提问,见笑了
zhouyg 发表于 2009-11-1 00:23:24 | 显示全部楼层
这问题问得好,有空也研究研究
回复

使用道具 举报

xuehui869 发表于 2009-11-1 13:44:20 | 显示全部楼层
mark,以前我问的这段代码的解释没人回答。。。有空自己研究下Arm汇编了
回复

使用道具 举报

tmy4711178 发表于 2009-11-5 10:36:42 | 显示全部楼层
2440内部集成了一个4K的SDRAM,并把它映射到0x0处来装载nandflash前4K的代码,而nandflash是不能直接运行程序的,所以这前4K的代码要把程序复制到SDRAM中,至于跳转到main,那就是 ldr  pc,main的功劳,main是一个绝对地址。
回复

使用道具 举报

xuehui869 发表于 2009-11-7 15:11:31 | 显示全部楼层
;===========================================================
nand_boot_beg
        [ {TRUE}                ;用于预编译
                bl RdNF2SDRAM                   ;此函数在Nand.c文件中   

Mark by xuehui869
        ]

        ldr        pc, =copy_proc_beg
;===========================================================
;以下五项由编译器输出,使用的时候根据PC的基地址偏移,注意不是固定的
;;TopOfRom在steppingstone中单步调试的时候为0X000003b8,就像编译后list显示那
;;样;在SDRAM中调试时,显示0x300060cc..根据基地址偏移可变
;反汇编显示窗口中,后面有注释的行就为地址变更之后的值。。
;BaseOfROM        DCD        |Image$$RO$$Base|
;TopOfROM        DCD        |Image$$RO$$Limit|  ;得到RW在程序存储区数据源的起始地址
;BaseOfBSS        DCD        |Image$$RW$$Base|   ;RW区在RAM里的执行区起始地址
;BaseOfZero        DCD        |Image$$ZI$$Base|   ;ZI区在RAM里面的起始地址
;EndOfBSS        DCD        |Image$$ZI$$Limit|  ;ZI区在RAM里面的结束地址加一

copy_proc_beg      ;用来初始化变量,程序实现了RW数据的拷贝和ZI区域的清零功能

adr        r0, ResetEntry      ;r0=ResetEntry,ResetEntry为复位地址,当
;JTAG时为0x30000000,当上电运行时为0x00000000,为bootstepping或者NOR Flashs首地址

ldr        r2, BaseOfROM            ;BaseOfROM根据TQ2440的对编译器的默认设置为0x30000000
        cmp        r0, r2
        ldreq        r0, TopOfROM    ;如果r0 eq r2,就执行ldr r0, TopOfROM
        beq        InitRam                ;如果r0 eq r2,就InitRam,开始执行一系列的初始化过程并启系统。
        ldr r3, TopOfROM        ;如果r0 no eq r2,就ldr r3, TopOfROM
0       
        ldmia        r0!, {r4-r7}
        stmia        r2!, {r4-r7}
        cmp        r2, r3
        bcc        %B0
       
        sub        r2, r2, r3
        sub        r0, r0, r2                               
               
InitRam       
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
感觉TQ2440提供的数据拷贝程序有问题,不完善。。其实好多开发板都是一个版本,

相互改。。。

   
   在CodeWarrior 的设置中,RW Base选项保留为空,那么在编译器编译工程所生成

的映像文件中,RO属性的输出段、RW属性的输出段以及Zi属性的输出段都包含在一个

域中,这些可以从List.txt文件中可以看出,三者定义的地址是顺序相连的,它们之

间的相对位置不用重新加载已经是正确的了。所以直接把这三个段整体拷贝到SDRAM,

就能运行,而不需要再按照各段的值进行加载,因为那样是重复的。。

  先说JTAG的情况-----程序是下载到SDRAM中执行的,根据编译器的设置(Image

entry point被设置为0x30000000),PC从ResetEntry(0x30000000)开始执行。映像文件

中,即使有PC偏移,三个段间的相对位置也已经固定和设置好,不需要重新加载(因为

和映像文件是重复的)。


  当上电从NAND FLASH启动时-----在4K steppingstone中,PC从ResetEntry

(0x00000000)处执行,在从FLAsh拷贝代码到SDRAM的之后(RdNF2SDRAM),程序执行

copy_proc_beg,但这些操作不对SDRAM有影响,因为PC的基地址是0x0。。。。
  NorFlash的情况和上面同。。。


   当然,如若RW设置某一固定值,这时就需要根据三个段的值进行加载了,以此来把

源程序和变量按照所编程序的设定放在该放的位置上,使它们的相对空间位置是正确

的。
   但是,TQ2440开发板提供的源代码还是应做些改动:
   当NAND启动的时候,要执行RdNF2SDRAM,在该函数中应该根据相应的RO、RW、ZI参

数进行拷贝,还要注意偏移量、基地址,以保证三者整体间的空间相对关系如程序所

设计的那样;当是NOR FLASN启动时,如若想把代码拷贝到SDRAM中执行,需要把

copy_proc_beg函数中的RO、RW、ZI、相对地址的偏移量根据情况加上SDRAM的首地址

(0x30000000);JTAG时,不需要改动copy_proc_beg。。。
回复

使用道具 举报

13590955160 发表于 2010-5-21 23:07:30 | 显示全部楼层
我也关注一下
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

i.MX8系列ARM cortex A53 M4 工控板上一条 /1 下一条

Archiver|手机版|小黑屋|天嵌 嵌入式开发社区 ( 粤ICP备11094220号-2 )

GMT+8, 2025-6-17 00:55 , Processed in 2.041265 second(s), 21 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表