查看: 10454|回復: 6
打印 上一主題 下一主題

(ZT)RO和RW還有ZI代表什么?

[復制鏈接]
跳轉到指定樓層
樓主
發(fā)表于 2009-7-23 10:32:45 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
關(guān)鍵詞: 代表
(轉自[url]http://hi.baidu.com/hhjj1201/blog/item/297ab931972011ad5edf0ec1.html)[/url]
一般而言,一個(gè)程序包括只讀的代碼段和可讀寫(xiě)的數據段。在ARM的集成開(kāi)發(fā)環(huán)境中,只讀的代碼段和常量被稱(chēng)作RO段(ReadOnly);可讀寫(xiě)的全局變量和靜態(tài)變量被稱(chēng)作RW段(ReadWrite);RW段中要被初始化為零的變量被稱(chēng)為ZI段(ZeroInit)。對于嵌入式系統而言,程序映象都是存儲在Flash存儲器等一些非易失性器件中的,而在運行時(shí),程序中的RW段必須重新裝載到可讀寫(xiě)的RAM中。這就涉及到程序的加載時(shí)域和運行時(shí)域。簡(jiǎn)單來(lái)說(shuō),程序的加載時(shí)域就是指程序燒入Flash中的狀態(tài),運行時(shí)域是指程序執行時(shí)的狀態(tài)。對于比較簡(jiǎn)單的情況,可以在A(yíng)DS集成開(kāi)發(fā)環(huán)境的ARMLINKER選項中指定RO BASE和RWBASE,告知連接器RO和RW的連接基地址。對于復雜情況,如RO段被分成幾部分并映射到存儲空間的多個(gè)地方時(shí),需要創(chuàng )建一個(gè)稱(chēng)為“分布裝載描述文件”的文本文件,通知連接器把程序的某一部分連接在存儲器的某個(gè)地址空間。需要指出的是,分布裝載描述文件中的定義要按照系統重定向后的存儲器分布情況進(jìn)行。在引導程序完成初始化的任務(wù)后,應該把主程序轉移到RAM中去運行,以加快系統的運行速度。
什么是arm的映像文件,arm映像文件其實(shí)就是可執行文件,包括bin或hex兩種格式,可以直接燒到rom里執行。在axd調試過(guò)程中,我們調試的是axf文件,其實(shí)這也是一種映像文件,它只是在bin文件中加了一個(gè)文件頭和一些調試信息。映像文件一般由域組成,域最多由三個(gè)輸出段組成(RO,RW,ZI)組成,輸出段又由輸入段組成。所謂域,指的就是整個(gè)bin映像文件所處在的區域,它又分為加載域和運行域。加載域就是映像文件被靜態(tài)存放的工作區域,一般來(lái)說(shuō)flash里的 整個(gè)bin文件所在的地址空間就是加載域,當然在程序一般都不會(huì )放在flash里執行,一般都會(huì )搬到sdram里運行工作,它們在被搬到sdram里工作所處的地址空間就是運行域。我們輸入的代碼,一般有代碼部分和數據部分,這就是所謂的輸入段,經(jīng)過(guò)編譯后就變成了bin文件中ro段和rw段,還有所謂的zi段,這就是輸出段。對于加載域中的輸出段,一般來(lái)說(shuō)ro段后面緊跟著(zhù)rw段,rw段后面緊跟著(zhù)zi段。在運行域中這些輸出段并不連續,但rw和zi一定是連著(zhù)的。zi段和rw段中的數據其實(shí)可以是rw屬性。
   | Image$$RO$$Base| |Image$$RO$$Limit| |Image$$RW$$Base||Image$$ZI$$Base| |Image$$ZI$$Limit|這幾個(gè)變量是編譯器通知的,我們在makefile文件中可以看到它們的值。它們指示了在運行域中各個(gè)輸出段所處的地址空間| Image$$RO$$Base|就是ro段在運行域中的起始地址,|Image$$RO$$Limit|是ro段在運行域中的截止地址。其它依次類(lèi)推。我們可以在linker的output中指定,在 simple模式中,ro base對應的就是|Image$$RO$$Base|,rw base對應的是|Image$$RW$$Base|,由于rw和zi相連,|Image$$ZI$$Base| 就等于|Image$$ZI$$limit|.其它的值都是編譯器自動(dòng)計算出來(lái)的。
    下面是2410啟動(dòng)代碼的搬運部分,我給出注釋
BaseOfROM DCD |Image$$RO$$Base|
TopOfROM DCD |Image$$RO$$Limit|
BaseOfBSS DCD |Image$$RW$$Base|
BaseOfZero DCD |Image$$ZI$$Base|
EndOfBSS DCD |Image$$ZI$$Limit|
adr r0, ResetEntry;   ResetEntry是復位運行時(shí)域的起始地址,在boot
nand中一般是0
ldr r2, BaseOfROM;
cmp r0, r2
ldreq r0, TopOfROM;TopOfROM=0x30001de0,代碼段地址的結束
beq InitRam
ldr r3, TopOfROM
;part 1,通過(guò)比較,將ro搬到sdram里,搬到的目的地址從 | Image$$RO$$Base| 開(kāi)始,到|Image$$RO$$Limit|結束
0
ldmia r0!, {r4-r7}
stmia r2!, {r4-r7}
cmp r2, r3
bcc %B0;

;part 2,搬rw段到sdram,目的地址從|Image$$RW$$Base| 開(kāi)始,到|Image$$ZI$$Base|結束
sub r2, r2, r3;r2=0
sub r0, r0, r2   
InitRam ;carry rw to baseofBSS
ldr r2, BaseOfBSS ;TopOfROM=0x30001de0,baseofrw
ldr r3, BaseOfZero ;BaseOfZero=0x30001de0
0
cmp r2, r3
ldrcc r1, [r0], #4
strcc r1, [r2], #4
bcc %B0
;part 3,將sdram zi初始化為0,地址從|Image$$ZI$$Base|到|Image$$ZI$$Limit|
mov r0, #0;init 0
ldr r3, EndOfBSS;EndOfBSS=30001e40
1
cmp r2, r3
strcc r0, [r2], #4
bcc %B1
沙發(fā)
 樓主| 發(fā)表于 2009-7-23 10:34:00 | 只看該作者
關(guān)于ro(rw)的問(wèn)答  收藏
http://bbs.edw.com.cn/dispbbs.as ... age=1&skin=0&Star=1

請再解釋一個(gè)關(guān)于A(yíng)DS中ro/rw base的疑惑(已查閱資料)!

首先說(shuō)一下,我認為我還是看了不少的資料,然后再來(lái)問(wèn)這個(gè)問(wèn)題的,看起來(lái)下面我寫(xiě)的很多,其實(shí)我只是想把問(wèn)題描述清楚一點(diǎn),我認為我已經(jīng)寫(xiě)的比較詳細了,所以應該不會(huì )耽誤各位大俠多少時(shí)間,所以希望能耐心看完,謝謝 !

我的CPU是4510,我在各種資料上都看過(guò)相關(guān)的解釋?zhuān)?br /> -ro-base address(即設定Image$$RO$$Base--我的理解)
這個(gè)選項將包含有RO(Read-Only屬性)輸出段的加載地址和運行地址設置為address,
該地址必須是字對齊的,如果沒(méi)有指定這個(gè)選項,則默認的RO基地址值為0x8000。
-rw-base address
這個(gè)選項設置包含RW(Read/Write屬性)輸出段的域的運行時(shí)地址,該地址必須是字對
齊的。

Image$$RO$$Base is the address of the read-only execution region (usually
contains code and read-only data).--ro運行時(shí)地址

Image$$RW$$Base is the address of the read-write execution region (usually
contains data).--rw運行時(shí)地址

所以大致意思,我是知道的,不過(guò)在還是在有幾個(gè)問(wèn)題想不明白:

    問(wèn)題1、就是這個(gè)設定的Image$$RO$$Base與我們復位時(shí)CPU讀取第一條指令的 0x0 地址有什么關(guān)系?這個(gè)“Image$$RO$$Base”到底又設定了那些源代碼的運行起始地址?比如在一個(gè)Bootloader中,往往包含同時(shí)包含匯編代碼和C語(yǔ)言代碼兩部分,這個(gè)“Image$$RO$$Base”只設定了C語(yǔ)言中RO段的運行地址 ?(拷貝RO RW段代碼到Image$$RO$$Base,Image$$RW$$Base標識的位置是我的bootloader 匯編代碼進(jìn)入C前做的最后一件事)
    如果說(shuō)也設定了匯編中ro部分代碼的運行地址,那問(wèn)題2又怎么解釋 ?

    問(wèn)題2、有人說(shuō)“請注意,將工程編譯為燒入Flash的二進(jìn)制代碼時(shí),需要將鏈接器重新設置,將調試時(shí)程序空間定位地址(RO Base地址)改為0x00000000”,但我明明剛剛編譯的Bootloader就將ro base設為了0xf00000,現在我已將其燒寫(xiě)入Flash中測試過(guò),Bootloader運行良好,而且在上電時(shí)Flash首先被映射到0地址開(kāi)始的地方,這與設定的0xf00000差的很遠,當然在程序將進(jìn)入C語(yǔ)言前,會(huì )remap SDRAM到0~16M空間,并將RO RW段拷貝到Image$$RO$$Base,Image$$RW$$Base標識的位置,問(wèn)題是這個(gè)拷貝之前我的所有代碼(比如SDRAM初始化,remap,堆棧初始化等)都運行的很正常,這又怎么解釋呢?
    這樣一來(lái)我到有個(gè)奇怪的想法就是,如果我的程序沒(méi)有C語(yǔ)言代碼,豈不是就可以不用管這個(gè)ro base的設置?因為從一開(kāi)機到拷貝ro/rw段前,我所有的匯編代碼執行良好。

    問(wèn)題3、我的vector.S中復位入口“ResetEntry”的部分代碼如下,用AXD載入ADS編譯的這個(gè).bin文件的時(shí)候可以看到,這個(gè) “ResetEntry”標號開(kāi)始的代碼被編譯到了.bin文件的最前面,因為我在鏈接設置里面把reset section放在了img的最前面。我有點(diǎn)不明白就是這個(gè)“ResetEntry”標號代表著(zhù)的一個(gè)地址與Image$$RO$$Base又有什么關(guān)系?與復位時(shí)CPU讀取第一條指令的 0x0 地址又有什么關(guān)系?因為我的Bootloader在拷貝ro段代碼時(shí)用到了這個(gè)標號,同時(shí)我的Bootloader代碼也并不是真正放在Flash的起始部分(即開(kāi)機的0地址處),只是在0地址處放了一條跳轉到Flash的高端,再執行哪里存放的Bootloader代碼。

            AREA reset, CODE, READONLY
ENTRY
           ;復位和上電啟動(dòng)的入口
ResetEntry
           b SYS_RST_HANDLER
           b UDF_INS_HANDLER
.........................................


    4、我在A(yíng)XD調試程序時(shí)還發(fā)現,調試過(guò)程中我可以把ADS生成的.bin文件載入SDRAM中任何位置,然后修改pc值執行之,不論你的 Image$$RO$$Base,Image$$ROW$$Base設定在什么地方,當然我的這個(gè)調試的程序肯定沒(méi)有對ro/rw段做任何的拷貝操作。這讓我更對RW段運行時(shí)地址和Image$$ROW$$Base的關(guān)系感到疑惑,因為rw段中不是保存有程序需要的變量或數據么?Image$$ROW$$Base設定了rw段的運行地址,那豈不是也就設定了運行時(shí)變量或數據在內存中的存在位置?那我用AXD加載的這個(gè)程序又在哪里獲得的程序運行需要的變量和數據呢 ?

    上面的問(wèn)題其實(shí)一直就困擾了我好久,不過(guò)因為項目方面比較急,所以也就一直放在哪里沒(méi)有對其深究,現在稍微有點(diǎn)空,才放到網(wǎng)上來(lái),請各位解惑,非常感謝 !
    我的表達能力也不怎么好,上面的問(wèn)題也許有點(diǎn)羅嗦,如果還有什么沒(méi)有說(shuō)清楚的也希望能提出來(lái),3KS  ag !


********************************************************************************************

四個(gè)問(wèn)題其實(shí)就是一個(gè),即鏈接器到底指定了什么東西。簡(jiǎn)單地說(shuō),linker把對函數的調用轉成向某一地址的跳轉,把對變量的讀寫(xiě)轉成對某一地址的訪(fǎng)問(wèn)。

但是,一段正在執行的代碼本身,從本質(zhì)上來(lái)說(shuō),并不需要知道自己運行在什么地址。只要PC指針有一個(gè)初值(比如0x0),然后每次加4之后,能取到下一條指令就行了。與此相關(guān)的另一個(gè)概念就是PIC(Position Independent Code,與位置無(wú)關(guān)的代碼)。

只有當代碼中調用了函數,向某個(gè)symbol跳轉或訪(fǎng)問(wèn)了變量,才需要知道真實(shí)的地址。所以Image$$RO$$Base是否起作用,并不取決于C代碼和匯編代碼的區別,而在于PIC與PDC的區別。
********************************************************************************************

版主和TALISKER已經(jīng)回答了樓主的問(wèn)題。我也說(shuō)說(shuō)自己的看法,希望對你有幫助。
1. Image$$RO$$Base is the address of the read-only execution region
   你仔細琢磨RO BASE的意思,RO BASE指定的只是RO段的起始地址,注意:并沒(méi)
   有說(shuō)始第一條指令的地址。所以,如果你的程序包括多個(gè)段的時(shí)候,有可能別
   的段放到了RO BASE指定的地址上,而并不是期望執行的第一條指令。在調試
   的時(shí)候,這不會(huì )造成什么問(wèn)題,因為DEBUGGER會(huì )把PC指向程序的第一條指令。
   如果你把程序燒寫(xiě)到FLASH里面后,這可能會(huì )造成問(wèn)題,因為CPU在RESET后只
   從地址0x0處開(kāi)始取指令。所以,如果你寫(xiě)一個(gè)程序,期望程序從地址0x0開(kāi)始
   執行,要滿(mǎn)足兩個(gè)條件:1-RO BASE要為0x0,2-告訴linker,把包括你希望
   執行的第一天指令SECTION鏈接到RO段的最前面。
  
2. 對于你說(shuō)到的第二個(gè)問(wèn)題,為什么你把RO BASE設置為0xF0000000還能從地址
   0x0開(kāi)始執行?這是因為4510的地址繞卷問(wèn)題造成的,其實(shí)地址0xF0000000就是
   地址0x0,不信你可以自己測試一下,從地址0xF00000讀出來(lái)的指令和地址0x0
   的指令一樣。所以,你的第二個(gè)問(wèn)題不是問(wèn)題,這和RO BASE沒(méi)什么關(guān)系。
  
3. 前面說(shuō)過(guò)了,一個(gè)程序包括了RO段,但程序可能包括了很多個(gè)SECTION,在編譯
   的時(shí)候,各個(gè)section的RO段都是被鏈接到你指定的RO BASE開(kāi)始的地方的,這
   就涉及到另外一個(gè)問(wèn)題:在RO段里面,你怎么安排各個(gè)sedtion在RO段的順序?
   如果你寫(xiě)的是BOOTLOADER的話(huà),你必須要把包括你要執行的第一條指令的段放
   在最前面,這樣才能保證板子上電后能正常運行。
  
4. 我不知道你的程序里面是否有RW段?程序分為RO段和RW段,但并不是每個(gè)程序
   都一定有RW段,如果你的程序里面沒(méi)有全局變量等,那編譯后,肯定是沒(méi)有RW
   段的,在這種情況下,你不進(jìn)行RW段的拷貝,程序也能正常運行的。OK,在來(lái)
   看看你的問(wèn)題,你說(shuō)在編譯生成bin文件后,在bin文件里如何定位RW段?答案
   是:?jiǎn)螁我蕾?lài)bin文件是無(wú)法定位RW段的。所以 - 如果你的程序有RW段的話(huà),
   你必須在自己程序里面處理RW段的拷貝。
********************************************************************************************

首先謝謝各位兄弟、大哥的回復,非常感謝 !

其次針對各位的回復,再綜合我所知道的別人給的解釋?zhuān)蚁朐僬勔幌挛易约含F在的想法:
to Talisker:我不知道你想設定ro base在0x04的意思是什么?

to Twentyone:
針對你的回答1:
“在調試的時(shí)候,這不會(huì )造成什么問(wèn)題,因為DEBUGGER會(huì )把PC指向程序的第一條指令!保艺{試的時(shí)候采用的是ADW載入ADS編譯的二進(jìn)制bin文件的方式,所以pc值或bin文件載入地址都是由我指定的,但都與ro base設定的值不同。
針對你的回答2:“對于你說(shuō)到的第二個(gè)問(wèn)題,為什么你把RO BASE設置為0xF0000000還能從地址0x0開(kāi)始執行?這是因為4510的地址繞卷問(wèn)題造成的,其實(shí)地址0xF0000000就是地址 0x0”---你說(shuō)的沒(méi)錯,0xF0000000地址最終會(huì )對應到0地址,不過(guò)我是將ro base設在了0xf00000,即15M內存的地方,而調試使用的obey xxx.ini命令將0~16M的內存都分配給了SDRAM,所以將ro base 設在0xf00000,還沒(méi)有到地址卷繞的地方。
針對你的回答4:
我調試的程序首先是比較簡(jiǎn)單,那是不錯,不過(guò)變量肯定是有的,不論全局、局部變量,都有 !是一個(gè)同時(shí)包含串口和IO口簡(jiǎn)單測試的程序。
板凳
 樓主| 發(fā)表于 2009-7-23 10:34:18 | 只看該作者
另外有人回答說(shuō):

解答問(wèn)題1&2:這說(shuō)明你的bootloader是基于相對地址的,也就是說(shuō)與地址無(wú)關(guān),而這也是對bootloader的一個(gè)基本要求。一般的bootloader都設計成地址無(wú)關(guān)的。

解答問(wèn)題4:這說(shuō)明你的程序比較小,或者函數調用不復雜,堆棧操作不頻繁等。也就是說(shuō),不按照你的設置的ro和rw基址調入程序,有可能數據空間不夠,或者代碼和數據重疊,程序執行就可能出錯。

------我看這個(gè)回答好像是對的,不知道各位對此有什么理解或看法 ?

********************************************************************************************
Twentyone:

文后附的是一個(gè)測試程序,這個(gè)程序可以驗證RW的影響。
測試的之前,你把你的板子的MEMORY給配置好,把SDRAM配置到地址0X0開(kāi)始的地方。

測試1:程序的RO_BASE = 0x0,RW_BASE不設置,你用仿真器單步運行程序,然后觀(guān)察
內存0x800的內容變化,變化順序應該是0x0 -> 0x1 -> 0x2 ... -> 0x9

測試2:程序的R0_BASE不變,還是RO_BASE = 0x0,RW_BASE設置為0x400,單步運行程
序,觀(guān)察內存0x800的內容變化,看看結果和第一次測試的是否一樣

我:

我試過(guò)了,也基本上清楚了,按照你的實(shí)驗設定測試2會(huì )看到0x800地址的數據不規則的變化,我又看了一下對應的匯編代碼(我是指編譯后的匯編代碼),發(fā)現程序在讀取array數組值時(shí),是從rw base開(kāi)始的地方讀取數據的,因此如果一開(kāi)始沒(méi)有將rw段放到rw base開(kāi)始的地方,則程序執行后讀取的數據肯定是不對的,這也符合rw base本身的意思,現在我應該說(shuō)是徹底的清楚了,謝謝 !
    我以前的問(wèn)題是:我在程序中使用變量前首先就先改變了變量的值,因此RW段首先就被我程序先修改了,也就是說(shuō)雖然我沒(méi)有搬移RW 段的操作,但是我重新修改了rw base開(kāi)始的數據的值,對應到你的這個(gè)測試程序,也就是說(shuō)本來(lái)我沒(méi)做搬移RW段的操作,則0x400地址開(kāi)始的數據(在你這個(gè)測試程序中存放的是 array數組的值)是不確定的,但后來(lái)程序一開(kāi)始我就修改了array數組的數據,也即修改了0x400開(kāi)始的數據,因此RW段雖然我沒(méi)有搬移操作,但其實(shí)也就被我重新設定正確了,然后再讀取使用,當然執行起來(lái),當然就沒(méi)有什么問(wèn)題了,不過(guò)這里有一點(diǎn):就是我的程序本來(lái)就比較小,RW段也很小,所以沒(méi)有什么問(wèn)題,但如果程序大一點(diǎn),RW段太大,我不能夠一一重新指定,那程序就會(huì )出錯了,問(wèn)題解決,非常感謝 !
    不過(guò)關(guān)于RO段的問(wèn)題:RO base 設定值與bin程序載入值不同,但程序仍能正確執行的問(wèn)題 。
    我想可能只能用我得代碼都是“地址無(wú)關(guān)”的這個(gè)來(lái)解釋了,對吧 ?
    這東西有點(diǎn)絞,不知道我上面的表達清楚沒(méi)? 呵呵,如果沒(méi)什么問(wèn)題,我想就把上面這段話(huà)轉到電子產(chǎn)品世界去了,然后我那個(gè)帖子也就可以方封貼了,呵呵,不過(guò)真的非常感謝你的幫助,謝謝 !

Twentyone:

不用客氣!

你說(shuō)的很清楚,你的理解是正確的,關(guān)于RO_BASE的問(wèn)題,如果程序完全運行正確的話(huà)
,只能用與地址無(wú)關(guān)來(lái)解釋。

如果你想做一個(gè)RO_BASE的測試的話(huà),你可以寫(xiě)一個(gè)測試程序,在程序里面包括一些絕
對尋址的指令,你就會(huì )發(fā)現程序運行時(shí)用不同的RO_BASE的話(huà),運行會(huì )有問(wèn)題的(可能
不影響結果,但中間肯定是有地方和你期望的不一樣的)。


ft,忘了貼代碼了,Twentyone大俠的測試程序如下:

init.s:

AREA    Init, CODE, READONLY
CODE32
ENTRY
ARM
LDR SP, =0xC00
IMPORT CTEST
B    CTEST
END


test.c:

unsigned int array[] = {0,1,2,3,4,5,6,7,8,9};

int CTEST(void)
{
int i;
unsigned int base;
i = 0;
base = 0x800;
for(i = 0; i < 10; i++){
  *((unsigned int*)(base)) = array[i];
}
return 0;
}
地板
 樓主| 發(fā)表于 2009-7-23 10:37:04 | 只看該作者
|Image$$RO$$Limit||Image$$RW$$Base||Image$$ZI$$Ba|

引自http://hi.baidu.com/liudefang888 ... 0ecc3b86947378.html

對于剛學(xué)習ARM的人來(lái)說(shuō),如果分析它的啟動(dòng)代碼,往往不明白下面幾個(gè)變量的含義:|Image$$RO$$Limit|、|Image$$RW$$Base|、|Image$$ZI$$Base|。

首先申明我使用的調試軟件為ADS1.2,當我們把程序編寫(xiě)好以后,就要進(jìn)行編譯和鏈接了,在A(yíng)DS1.2中選擇MAKE按鈕,會(huì )出現一個(gè)Errors and Warnings 的對話(huà)框,在該欄中顯示編譯和鏈接的結果,如果沒(méi)有錯誤,在文件的最后應該能看到Image component sizes,后面緊跟的依次是Code,RO Data ,RW Data ,ZI Data ,Debug 各個(gè)項目的字節數,最后會(huì )有他們的一個(gè)統計數據:

Code 163632 ,RO Data 20939 ,RW Data 53 ,ZI Data 17028

Tatal RO size (Code+ RO Data)             184571 (180.25kB)

Tatal RW size(RW Data+ ZI Data)           17081(16.68 kB)

Tatal ROM size(Code+ RO Data+ RW Data)   184624(180.30 kB)

后面的字節數是根據用戶(hù)不同的程序而來(lái)的,下面就以上面的數據為例來(lái)介紹那幾個(gè)變量的計算。

在A(yíng)DS的Debug Settings中有一欄是Linker/ARM Linker,在output選項中有一個(gè)RO base選項,下面應該有一個(gè)地址,我這里是0x0c100000,后面的RW base 地址是0x0c200000,然后在Options選項中有Image entry point ,是一個(gè)初始程序的入口地址,我這里是0x0c100000 。

有了上面這些信息我們就可以完全知道這幾個(gè)變量是怎么來(lái)的了:

|Image$$RO$$Base| = Image entry point = 0x0c100000 ;表示程序代碼存放的起始地址

|Image$$RO$$Limit|=程序代碼起始地址+代碼長(cháng)度+1=0x0c100000+Tatal RO size+1

= 0x0c100000 + 184571 + 1 = 0x0c100000 +0x2D0FB + 1

= 0x0c12d0fc

|Image$$RW$$Base| = 0x0c200000 ;由RW base 地址指定

|Image$$RW$$Limit| =|Image$$RW$$Base|+ RW Data 53 = 0x0c200000+0x37(4的倍數,0到55,共56個(gè)單元)

=0x0c200037

|Image$$ZI$$Base| = |Image$$RW$$Limit| + 1 =0x0c200038

|Image$$ZI$$Limit| = |Image$$ZI$$Base| + ZI Data 17028

                            =0x0c200038 + 0x4284

                            =0x0c2042bc

也可以由此計算:

|Image$$ZI$$Limit| = |Image$$RW$$Base| +TatalRWsize(RWData+ZIData) 17081

                            =0x0c200000+0x42b9+3(要滿(mǎn)足4的倍數)

                            =0x0c2042bc
地下室
 樓主| 發(fā)表于 2009-7-23 10:38:07 | 只看該作者
這是一位用戶(hù)的問(wèn)題,這里轉發(fā)一下答復(也是摘自北航書(shū)“44binit.s初始化程序研究”一節中的一部分內容)

一個(gè)簡(jiǎn)易的映像文件包括以下幾個(gè)部分:
○ 一個(gè)只讀(RO)區域;
○ 一個(gè)讀寫(xiě)(RW)區域;
○ 一個(gè)被0初始化(ZI)的區域。
我們采用如下的方法,在鏈接器中指定每個(gè)區域在執行時(shí)的定位地址:
-RO-base   exec_address1    指示鏈接器將只讀(RO)區域定位在exec_address1地址處(例如,定位在ROM空間的起始地址上);
-RW-base   exec_address2   指示鏈接器將讀寫(xiě)(RW)區域定位在exec_address2地址處。
在RW(數據)區域中,也可能含有程序代碼,這是因為程序有時(shí)候需要自我修改(或產(chǎn)生新的代碼),類(lèi)似的,RO(代碼)區域中可能包含只讀的數據(例如字符串,常數等)。
鏈接器在創(chuàng )建上述區域的同時(shí)產(chǎn)生相應的“符號”并把地址信息傳遞給這些符號,從而允許將區域從它的加載地址拷貝到執行地址。這些符號描述了每個(gè)區域的起始地址和大小限制。這些符號的列舉和定義,請參考附圖。

在這里,exec_address1是RO區域的執行地址,它與RO區域在代碼加載時(shí)的地址相同。exec_address2是RW的代碼執行地址,它與RW區在加載時(shí)的地址是不一樣的,RW在加載時(shí)是緊接在R0區域后面的,因此在C程序執行之前,它必須被移到正確的地址上去。同時(shí),ZI區域也必須重新創(chuàng )建(因為在加載階段,不存在ZI區域)。

在一個(gè)簡(jiǎn)單的image里面:
Image$$RO$$Base:是RO段的執行地址開(kāi)始和裝載地址開(kāi)始,由-RO-BASE這個(gè)參數指定的
Image$$RO$$Limit:是RO段的裝載地址結束的后一個(gè)地址,也就是RW的裝載地址的開(kāi)始。(在一個(gè)simple image里面,裝載的時(shí)候,RO段被裝載在-RO-BASE指定的地址,后面緊跟著(zhù)的是RW的數據,注意,在simple image執行的時(shí)候,因為ro段的裝載地址和執行地址相同,所以不需要移動(dòng),而RW的執行地址是由-RW-BASE指定的,所以需要移動(dòng)。
Image$$RW$$Base:是rw段的執行地址,由-rw-base這個(gè)參數指定!
總結一下:
沒(méi)運行前:flash中的ro段是ro-base指定的地址開(kāi)始,等ro段完了(也就是Image$$RO$$Base~Image$$RO$$limit-1),后面緊接著(zhù)就是rw段(也就是Image$$RO$$limit~。。。)!
運行時(shí):flash中的ro段地址沒(méi)有動(dòng),還是Image$$RO$$Base~Image$$RO$$limit-1,原來(lái)flash中的rw段移到了sdram中,地址為Image$$RW$$Base~Image$$ZI$$Base,然后又初始化了一段ZI區!
呵呵!寫(xiě)點(diǎn)這個(gè)就當和我一樣的弱人共勉吧!如有不對之處,請大家指正!共同進(jìn)步

在一個(gè)簡(jiǎn)單的image里面:
Image$$RO$$Base:是RO段的執行地址開(kāi)始和裝載地址開(kāi)始,由-RO-BASE這個(gè)參數指定的
Image$$RO$$Limit:是RO段的裝載地址結束的后一個(gè)地址,也就是RW的裝載地址的開(kāi)始。(在一個(gè)simple image里面,裝載的時(shí)候,RO段被裝載在-RO-BASE指定的地址,后面緊跟著(zhù)的是RW的數據,注意,在simple image執行的時(shí)候,因為ro段的裝載地址和執行地址相同,所以不需要移動(dòng),而RW的執行地址是由-RW-BASE指定的,所以需要移動(dòng)。
Image$$RW$$Base:是rw段的執行地址,由-rw-base這個(gè)參數指定!
總結一下:
沒(méi)運行前:flash中的ro段是ro-base指定的地址開(kāi)始,等ro段完了(也就是Image$$RO$$Base~Image$$RO$$limit-1),后面緊接著(zhù)就是rw段(也就是Image$$RO$$limit~。。。)!
運行時(shí):flash中的ro段地址沒(méi)有動(dòng),還是Image$$RO$$Base~Image$$RO$$limit-1,原來(lái)flash中的rw段移到了sdram中,地址為Image$$RW$$Base~Image$$ZI$$Base,然后又初始化了一段ZI區!
呵呵!寫(xiě)點(diǎn)這個(gè)就當和我一樣的弱人共勉吧!如有不對之處,請大家指正!共同進(jìn)步
6
發(fā)表于 2009-8-2 11:55:41 | 只看該作者
好東西,很多ARM新手就是對這些東西不理解

俺當初也是折騰這個(gè)折騰了N久才明白
7
發(fā)表于 2009-8-14 09:48:23 | 只看該作者
RO 代表只讀段,也就是代碼段,裝載域和運行域都有
RW代表是數據段,包括DATA和BSS,裝載域和運行域都有
ZI代表是堆棧段,只有在運行域中有,
您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

關(guān)于我們  -  服務(wù)條款  -  使用指南  -  站點(diǎn)地圖  -  友情鏈接  -  聯(lián)系我們
電子工程網(wǎng) © 版權所有   京ICP備16069177號 | 京公網(wǎng)安備11010502021702
快速回復 返回頂部 返回列表
午夜高清国产拍精品福利|亚洲色精品88色婷婷七月丁香|91久久精品无码一区|99久久国语露脸精品|动漫卡通亚洲综合专区48页