打印

ads中的linker ro/rw的理解若干问题。

[复制链接]
4462|16
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
luocolor|  楼主 | 2007-1-24 21:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我认为我还是查了很多资料的,但是这两个值的理解总是因为不很清楚,时不时地要来困扰我.


问题1:
一个工程可以有很多个具体的文件,每个文件可以有一个或者多个段,段有ro和rw的.当linker将它们链接

为一个映像文件的时候,将所有具有ro属性的段按照某种顺序排列,所有具有rw属性的段一样.这样就会有

下面的一个结构:

---------
|    |
|    |
|    |
---------
|   rw    |
---------  <------- rw base?
|   ro    |
---------  <------- ro base?

如上表示的,ro base和rw base是指那个地方么?

问题2:
一个程序有一个加载时地址,还有一个运行时地址。
比如有一个板子,flash被map到0x0,sdram被map到0xc0000,将一个程序下载到0x0处,并可以运行。
此时,我要怎样在ads里面设置ro base和rw base呢?这个ro和rw base值指的是加载时还是运行时地址呢



具体来说,ro base和rw base这两个值是怎样在每个过程中起作用的呢?

感觉这个问题有点绞。麻烦各位了。

相关帖子

沙发
luocolor|  楼主 | 2007-1-24 22:21 | 只看该作者

ro base 和flash remap后的地址有关么?

使用特权

评论回复
板凳
luocolor|  楼主 | 2007-1-24 23:24 | 只看该作者

呵呵

我又查了些资料,上面的问题大概理解了。

但又出现新的了:

load view时跟在ro section后面的的rw section,在执行的时候,是自己(是硬件自己)将其转移的吗?还是需要程序员手工地显示地复制到rw base处呢?

使用特权

评论回复
地板
coke| | 2007-1-25 10:28 | 只看该作者

随便说说

ro:只读程序段
rw:可读写数据段
zi:未初始化数据段.
这些与你的硬件有关系.也与ARM存储结构有关系.
如44b0.在仿真调试时候.RO是0xc000000. rw是0xc5f0000
因为我们的RAM地址是从0xc000000开始的.为了速度和调试方便所以将程序下到0xc000000中.那么rw 放哪里呢?只能根据我们硬件外挂ram大小和ro大小.将数据段放到0xc5f0000地方.当然你也可以放到RAM的其他地方.只要ro limit以内就可以了.这些参数根据这两个参数在ADS下编译链接.
    IMPORT    |Image$$RO$$Limit|  ; End of ROM code (=start of ROM data)
    IMPORT    |Image$$RW$$Base|   ; Base of RAM to initialise
    IMPORT    |Image$$ZI$$Base|   ; Base and limit of area
    IMPORT    |Image$$ZI$$Limit|  ; to zero initialise;
这些对我们的启动程序有用处的.

使用特权

评论回复
5
rw99yy| | 2007-1-25 13:04 | 只看该作者

我的理解和疑问

应为程序要在ram中运行(这样速度可以快点)。所以ro base要设置成硬件的ram地址。如果你硬茧ram地址是0c000000 那么程序的ro base就要设置这个地址。

但是我觉得程序应该是从0x0开始运行的。将ro base设置成0c000000 那代码怎么执行到那去呢?

使用特权

评论回复
6
coke| | 2007-1-25 16:45 | 只看该作者

re

你仿真时候.是怎么写ro的就从哪里运行啊. 你可以在flash中烧一个程序. 然后在仿真时候将ro改为0x000000. 仿真运行后程序肯定会从flash启动.如果你仿真时候是ro=0xc00000.那就是从0xc000000开始运行.

使用特权

评论回复
7
luocolor|  楼主 | 2007-1-25 17:15 | 只看该作者

我的

arm学习报告里面有这样说:

在加载域中,IMPORT    |Image$$RO$$Limit|就是RW的开始地址,而在运行域即运行的时候, |Image$$RW$$Base|才是RW的开始地址。

我是这样理解的,不知道对不!

程序在运行时,从 |Image$$RO$$Base|开始运行,一般来说,像bootloader这样的程序,这个位置放的是转移指令。(但这个地址和入口地址,即ENTRY有啥区别呢?)。在这个运行的过程中,如果程序需要一些数据的值,一般来说,会被放到RW section里面,而在此时 |Image$$RW$$Base|值就表示的是RW section的开始地址,即linker会让程序在这个地址开始处找数据。但是,一般来说,这个地址处现在放的并不是正确的或者说合适的数据,正确的数据应该是在加载域中 |Image$$RO$$Limit|开始处的数据。所以,在访问这些数据值前,需要程序员自己手动地把 |Image$$RO$$Limit|开始处的数据复制到 |Image$$RW$$Base|处。

是这样么?

而具体到44b0来说,
ro base设置成0c000000只是为了调试,如果要让程序固化到flash中,那么还是要将这个地址设置为0x0.

是这样么?

使用特权

评论回复
8
js_wawayu| | 2007-1-25 18:41 | 只看该作者

luocolor说的很对

代码的搬移可以自己写代码完成,也可以由__main()完成,__main()会把所有装载域和运行域不一致的region从装载域搬到运行域中。

使用特权

评论回复
9
luocolor|  楼主 | 2007-1-25 20:10 | 只看该作者

嘿嘿

刚看到篇**,不敢独享。
http://blog.csdn.net/city_lovelace/archive/2006/11/24/1412574.aspx
使用ADS1.2进行嵌入式软件开发(上) 
下可以自己搜一下。

里面所介绍的,反正对于我,可以说是正中下怀。哈哈

使用特权

评论回复
10
rw99yy| | 2007-1-26 12:37 | 只看该作者

luocolor来看看

请问:
代码的搬移可以自己写代码完成,也可以由__main()完成,__main()会把所有装载域和运行域不一致的region从装载域搬到运行域中。

也可以由__main(),完成是什么意思 ?? 是连接器做了手脚么?

使用特权

评论回复
11
啊粒狗肉| | 2007-1-26 13:58 | 只看该作者

看原版的英文档吧

到www.arm.com下个armlink的标准文档看看就解决了,说得再清楚不过了,DUI0151A_ADS1_2_LinkUt.pdf,就这个,搜索。

至于代码搬移,启动代码里面有这样一段,就是实现搬移的    

    adr    r0, ResetEntry
    ldr    r1,    BaseOfROM
    cmp    r0,    r1
    ldreq    r0, TopOfROM
    beq    InitRamData
            
    ldr    r2,    =CopyProcBeg
    sub    r1, r2, r1
    add    r0, r0, r1    
    ldr    r3,    =CopyProcEnd    
0    
    ldmia    r0!, {r4-r7}
    stmia    r2!, {r4-r7}
    cmp    r2, r3
    bcc    %B0    
    
    ldr    r3, TopOfROM        
    ldr    pc, =CopyProcBeg
    
;***********************************************
CopyProcBeg    
0    
    ldmia    r0!, {r4-r11}
    stmia    r2!, {r4-r11}
    cmp    r2, r3
    bcc    %B0    
CopyProcEnd

至于__main()看DUI0067D_ADS1_2_CompLib.pdf,功能上也说清楚了,我这上面的代码也实现__main()的功能,

使用特权

评论回复
12
啊粒狗肉| | 2007-1-26 14:18 | 只看该作者

不过感觉现在都不用__main()这个库函数了

反正我也没见着源码,用起来不爽
直接自己写初始化代码,跳入void Main(void),不是int main()

哪位大侠知道__main()源码在哪里,ADS的安装路径好像没有

使用特权

评论回复
13
js_wawayu| | 2007-1-27 13:48 | 只看该作者

__main用不用看各人需要了

__main不光做代码搬移,如果自己写搬移程序的话和__main的搬移代码是类似的,__main还做C库和C++库的初始化工作。如果没有用到标准C库函数的话就不需要用__main。

使用特权

评论回复
14
啊粒狗肉| | 2007-1-27 14:35 | 只看该作者

to js_wawayu

 js_wawayu 发表于 2007-1-25 18:41 ARM 论坛 ←返回版面    

8楼: luocolor说的很对 

代码的搬移可以自己写代码完成,也可以由__main()完成,__main()会把所有装载域和运行域不一致的region从装载域搬到运行域中。 

“__main()会把所有装载域和运行域不一致的region从装载域搬到运行域中” 这个怎么知道的呢,好像ARM的文档也没解释这么详细,只是说copy code and data,


js_wawayu大侠能不能整个源码看看?

使用特权

评论回复
15
js_wawayu| | 2007-1-27 14:45 | 只看该作者

这个可以用仿真器看,或者就用软件仿真看

AXD就可以啊,我也没见过源码,只能看到汇编,可以自己做个试验,在bootloader里B __main,然后用axd load image,也不用接开发板,就这样软件仿真,一点点跟下去。

使用特权

评论回复
16
luocolor|  楼主 | 2007-1-27 19:46 | 只看该作者

呵呵

在axd中看bl __main后的情况,有些循环之类的。

使用特权

评论回复
17
williamt| | 2007-2-14 13:14 | 只看该作者

代码搬移、加载、运行

代码搬移、加载、运行
1、    代码搬移:为了使程序运行更快,需要将代码从Flash内搬到RAM或SDRAM内,这叫代码搬移,比较容易理解。
2、    加载:不太明白,这一步是什么时候开始?什么时候结束?它跟上一步代码搬移有何区别,因为把代码搬入SDRAM后,只要改变当前寄存器PC的值,让他指向SDRAM中存放代码的起始地址,就可开始运行程序。加载这一步到底是什么作用?
3、    运行:把代码搬入SDRAM后,改变当前寄存器PC的值,从代码的起始地址开始执行(一般是这样), 就算是运行。

使用特权

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

本版积分规则

40

主题

105

帖子

0

粉丝