打印

关于ADS1.2里设置RO Base 和RW Base的疑问?

[复制链接]
5782|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
sklar|  楼主 | 2007-4-26 14:50 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
  谢谢进来解答!
  请问在ADS1.2里设置的RO Base和RW Base是做什么用的?
  我现在只能理解为:在ADS1。2里设置的RO Base和RW Base,是不是就是设置SDRAM的分布?跟代码放哪里没关系的?代码具体放哪里是不是烧写的时候设置的? 
  比如开发板提供的BISO 在ADS工程里RO Base设置为0xc000000 RW Base设置为0xc5f0000,可是BIOS不是要放0X0000000的吗?晕了 

相关帖子

沙发
pigjiang| | 2007-4-26 16:35 | 只看该作者

我觉得你说的有道理.

这个设置对代码烧入flash以后的分布没有关系。只是把code和data分段了一下.

使用特权

评论回复
板凳
sklar|  楼主 | 2007-4-26 16:54 | 只看该作者

呵呵,进来的都发表下看法吧

   知道的说下,不清楚的也把自己的看法说说吧,大家交流啊,楼上的用什么ARM板?我用的是立YU泰的44B0

使用特权

评论回复
地板
luhuaren| | 2007-4-26 17:15 | 只看该作者

re

RO Base设置为0xc000000 RW Base设置为0xc5f0000,可是BIOS不是要放0X0000000的吗

注意:如果是用44B0,那么44B0上电复位后PC的值是0,
    AREA    Init,CODE,READONLY

    ENTRY 
ResetEntry
    b ResetHandler                ;for debug
    b HandlerUndef                ;handlerUndef
    b HandlerSWI                ;SWI interrupt handler
    b HandlerPabort                ;handlerPAbort
    b HandlerDabort                ;handlerDAbort
    b .                            ;handlerReserved
    b HandlerIRQ
    b HandlerFIQ

系统上电后第一条指令执行的是b ResetHandler    (在0地址处)这是一条相对跳转指令,也就是说,这条指令和RO的设置无关
跳转到ResetHandler处,进行一些初始化动作后,就要进行代码拷贝,就是把FLASH里的代码拷贝到RO指定的地址处,代码拷贝是这样实现的:


    ;****************************************************
    ;拷贝并粘贴 RW data/zero initialized data            *
    ;****************************************************
    adr    r0, ResetEntry        
    ldr    r1,BaseOfROM        
    cmp    r0,r1                
                                
    ldreq    r0, TopOfROM        
    beq    InitRamData            
    
    ;****************************************************
    ;计算拷贝程序在flash中的实际位置                       *
    ;****************************************************
    ldr    r2,=CopyProcBeg    
    sub    r1, r2, r1;r2-r1->r1
    add    r0, r0, r1    
    ldr    r3,=CopyProcEnd
    
    ;****************************************************
    ;将拷贝程序复制到ram中                                *
    ;****************************************************
0    
    ldmia    r0!, {r4-r7}        
    stmia    r2!, {r4-r7}        
    cmp    r2, r3
    bcc    %B0    
    
    ;********************************************************
    ;开始用ram中的拷贝程序复本将所有剩下的代码复制到ram中    *
    ;********************************************************
    ldr    r3, TopOfROM        
    ;ldr    pc, =CopyProcBeg    ;装入绝对地址(指到RAM中去的)
    b    CopyProcBeg
    ;********************************************************
    ;本段将代码由实际烧入的地址拷贝到ro-base所指定的位置    *
    ;只拷贝CopyProcEnd以后的代码                ;********************************************************
CopyProcBeg    
0    
    ldmia    r0!, {r4-r11}
    stmia    r2!, {r4-r11}
    cmp    r2, r3
    bcc    %B0    
CopyProcEnd
    
    sub    r1, r2, r3
    sub    r0, r0, r1        
    
InitRamData    
    ldr    r2, BaseOfBSS
    ldr    r3, BaseOfZero    
0
    cmp    r2, r3
    ldrcc    r1, [r0], #4
    strcc    r1, [r2], #4
    bcc    %B0    

    mov    r0,    #0
    ldr    r3,    EndOfBSS
1    
    cmp    r2,    r3
    strcc    r0, [r2], #4
    bcc    %B1            
;===================================================================
    adr    r0, ResetEntry        
    ldr    r1,BaseOfROM        
    cmp    r0,r1    
请注意这几条语句,尤其是adr    r0, ResetEntry,这条语句当你反汇编后发现是一条这样的指令
;[0xe24f0f5d]   sub      r0,pc,#0x174   ; #0xc008000
     也是一条与位置无关的指令,ResetEntry的值同PC的值相关联,
当然,PC一上电的值为0,所以这里ResetEntry的值也为0,所以
    ldr    r1,BaseOfROM        
    cmp    r0,r1
比较的结果就是R0 != R1于是进行代码拷贝,将复制程序拷贝完后,就可以跳转到RAM中去,执行RAM中的拷贝程序,将FLASH中的代码拷贝到RAM中去..

使用特权

评论回复
5
luhuaren| | 2007-4-26 17:20 | 只看该作者

RE

可以下在U-BOOT的源码看一下,感觉很多开发板上流行的BOOT代码都是从U-BOOT上改过来的

使用特权

评论回复
6
pigjiang| | 2007-4-27 08:46 | 只看该作者

有个疑问

IMPORT    |Image$$RO$$Base|    ; ROM code start    
IMPORT    |Image$$RO$$Limit|    ; RAM data starts after ROM program
IMPORT    |Image$$RW$$Base|    ; Pre-initialised variables
IMPORT    |Image$$ZI$$Base|    ; uninitialised variables
IMPORT    |Image$$ZI$$Limit|    ; End of variable RAM space
===============================================
这几行的||里面的标号是从哪里获得的?
他们是不是就是设置linker的output选项里面填入的RO和RW的值?

使用特权

评论回复
7
wowow| | 2007-4-27 09:58 | 只看该作者

RO/RW

RO/RW地址在debug/release设置不同的值,一个用于仿真器加载到ram运行,一个用于flash中运行。如果你用了中断,并且ARM不支持REMAP,调ram程序时flash里必须也烧进中断向量表。


|Image$$RO$$Base| 之类是linker生成的,但有些情况下不生成。最好自己读一读关于linker的pdf

使用特权

评论回复
8
sklar|  楼主 | 2007-4-27 12:28 | 只看该作者

to luhuaren

   你的这些代码我在44Binit.S文件里没有,不过有点懂你说的意思了,ADS里设置的这些地址就是把代码考到SDRAM里的地址?
    adr    r0, ResetEntry        
    ldr    r1,BaseOfROM        
    cmp    r0,r1      //??这里没怎么没说跳到哪里?

使用特权

评论回复
9
luhuaren| | 2007-4-27 15:02 | 只看该作者

re

当然,PC一上电的值为0,所以这里ResetEntry的值也为0;
不好意思,这句话写的不对..........ResetEntry的值得应该是|Image$$RO$$Base| 

如果RO的值和你程序烧录起始地址的值不同,(如:你设置的RO=0xc000000,注意这个地址是在指向RAM,而你烧录的代码是在0地址处),这样就需要你烧录在0地址开始处的一小部分启动代码把程序从烧录地址搬运到RO设置的地址中去,但要注意,连接器为你连接的地址是以RO为基准的,这样你可能会有个疑问,为什么程序的运行域是以RO(0xc000000)为基准,但处于FLASH(0地址开始)里的一小部分启动代码还能运行呢,这就是因为程序中用了与地址无关的指令,使得一上电,能够顺利的执行0地址处的启动代码
注意
ENTRY 
ResetEntry
    b ResetHandler                ;for debug
这条指令并不是跳转到RO处,它还是跳到了FLASH里,
再注意以下几句
 adr    r0, ResetEntry        这里并不是把真正的ResetEntry的值装入了R0,其实装入R0的值是0,可以看看反汇编,你自然明白        
    ldr    r1,BaseOfROM        
    cmp    r0,r1    
想必应该可以理解了,如果再不理解,那建议多看看书.

使用特权

评论回复
10
sklar|  楼主 | 2007-4-27 16:09 | 只看该作者

收了

    恩,还得多看了!

使用特权

评论回复
11
时宗| | 2007-4-27 19:21 | 只看该作者

参考一下CPU datasheet

以24102440为例:SDRAM 一般用的是CPU的BANK6和BANK7(各64M),从BANK0到BANK6正好是0X30000000也就是所谓的0地址ResetEntry。

使用特权

评论回复
12
luhuaren| | 2007-4-27 19:56 | 只看该作者

RE

 没搞懂楼上的说的意思。

使用特权

评论回复
13
sklar|  楼主 | 2007-4-27 21:22 | 只看该作者

11楼可以详细点吗

   呵呵,11楼说的我也不明白!
期待详细点!

使用特权

评论回复
14
pigjiang| | 2007-4-27 22:20 | 只看该作者

to luhuaren还有个疑问

    ;****************************************************
    ;计算拷贝程序在flash中的实际位置                       *
    ;****************************************************
 -->ldr    r2,=CopyProcBeg    
    sub    r1, r2, r1;r2-r1->r1
    add    r0, r0, r1    
    ldr    r3,=CopyProcEnd

如你所说,前面比较r0和r1结果自然是不等,所以直接运行到这里来了。
请问:CopyProcBeg  是44binit.s里面的一个标号,它所代表的地址到底应该是在flash里还是在ram里?如果在flash里,那么r2应该小于r1,因为r1=BaseOfROM,那么sub    r1, r2, r1这个减法是不是有问题?

主要是觉得这个时候标号CopyProcBeg  应该是在flash里的某一个地址。
今天看了一天这段代码也没明白,谢谢指点!

使用特权

评论回复
15
luhuaren| | 2007-4-27 22:51 | 只看该作者

RE

ldr    r2,=CopyProcBeg    
注意用的是LDR指令

由ADS生成的代码的标号是以设置的RO为基准的,也就是说CopyProcBeg是RAM中的一个地址 。


但是如果你用ADR    r2,=CopyProcBeg    
这条指令就不一样了,具体怎么不一样,看看指令的解释,但很多地方只是一笔带过,没有很详细的解释,我是看了汇编后代码才明白的
它会生成一条类似下面的指令
sub      r0,pc,#0x174   ; #0xc008000

以上我理解的应该没有错误,因为我已经在板子上验证过。

在我不理解这些的时候,到网上搜索过很多资料,但是没有谁确切的解释过这些东东,后来等我弄明白了以后,在LINUX论坛上发现有讨论U-BOOT的帖子对这些做了很明确的解释。
为什么程序的运行域和加载域不同,但启动代码还能在加载域运行,并将加载域的代码拷贝到运行域中去,然后将PC指到运行域中去,在运行域中执行代码,可能是每一个初学者看启动代码时最难理解的地方。理解了这些,其他的,都相对好弄一些/

使用特权

评论回复
16
pigjiang| | 2007-4-28 11:09 | 只看该作者

谢谢luhuaren的解释。

还需进一步参透:)

使用特权

评论回复
17
TalentHRX| | 2016-4-1 16:36 | 只看该作者
初学嵌入式,多多指教,前来观贴。。。。。正好遇到同样的问题

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

136

帖子

1

粉丝