?? 疑難解答.txt
字號:
問:
你好,首先很感謝你寫這些東西,看了你寫的bootloader,對我很有啟發。但我還是有幾個問題不是很明白,想請教一下。
首先是對于part5這塊兒有點兒疑問,這段代碼主要是把bootloader由flash拷貝到sdram中去,我的理解是只要把RO代碼段拷貝過去就可以了啊,為什么要拷貝(RO+RW)長度的代碼呢,而且我的理解是雖說拷貝了(RO+RW)長度的代碼,但是RW段的內容并沒有被拷貝到sdram中去,這么做是為什么呢?另外這里RWBase的地址是多少呢,是在ads中設置的0xA00000這個嗎?RW段代碼在flash中的地址是如何確定的呢?如果是0xA00000的話,已經超過2Mflash的大小了啊?
;Part 5
;***************************************************************
;Self copy from FLASH to SDRAM
LDR r0, =|Image$$RO$$Base|
LDR r1, =|Image$$RO$$Limit|
LDR r2, =|Image$$RW$$Base|
LDR r3, =|Image$$RW$$Limit|
SUB r1, r1, r0
SUB r3, r3, r2
ADD r1, r1, r3
LDR r2, =0x200000 ;@2M
COPY
LDR r3, [r0], #4
STR r3, [r2], #4
SUBS r1, r1, #4
BNE COPY
還有一個問題就是你是把image.ram轉換成一個數組了,那么在把bootloader燒到flash里這個數組是存在哪里的呢,是放在RW段嗎?如果是放在RW段的話,那在映射后是不是先把RW段的數據由flash拷貝到sdram中,再把位于sdram中RW段的image.ram數組拷貝到0x8000處,然后運行uclinux。
答:
part5這部分代碼的目的就是要把整個bootlaoder拷貝到sdram里去,包括RW段和RO段。在程序里,RO BASE = 0X0, RW BASE = 0XA00000, 這里需要注意一個問題:在編譯鏈接好的程序里面,RW段是放置在RO段后面的,所以|Image$$RO$$Limit|既是RO段的結束位置也是RW段的起始地址。 而RW BASE是指在運行的時候RW段的地址,因為運行時我們需要把RW段拷貝到memory里可讀寫的存儲介質上去,所以RW BASE 被設置為 0XA00000. 所以,RW BASE 大于2M并不是個問題。
其實你也可以開始指把RO段拷貝到SDRAM里去,回頭在從flash里把RW段拷貝到合適的位置上去,但為了使得實現更簡單和直接,我沒有這樣做,而是一口氣就把整個bootloader拷貝到sdram里去了,回頭就不用在管flash了。在remap后再把RW段從SDRAM里拷貝到SDRAM合適的位置去。
因為kernel[]這個數組是一個全局變量,所以肯定是被放到RW段去了。所以,在remap后,先把RW段拷貝到RW_BASE的位置上去,設置好堆棧指針,就可以調用loadkernel函數了,這個函數會把knerle[]這個數組(其實就是內核image.ram)拷貝到0x8000的位置上去,然后跳轉過去就可以啟動了。
希望能夠解釋清楚,如果有問題請發貼繼續討論。
問:
編譯出來有1M多,怎么會如此大呢?
答:
是的,大概有1M多。為了簡單起見,在把image.ram轉化為char數組前并沒有把image.ram先壓縮一下,所以編譯出來比較大。如果你感興趣的話,可以自己把壓縮和解壓縮添加進去,網上找的到壓縮和解壓縮的源代碼,應該挺容易實現的。
問:
非常清楚的說明。另外有個問題想請教,在 load kernal 完成後,uClinux kernal 會在位址 0x0 重設中斷向量嗎? thks
答:
bootloader里不用管中斷。但在kernel起來后,kernel自己肯定會設置中斷向量的。
呵呵,一個BootLoader的最小系統,簡潔、高效!真是好人!
問:
現在有一個問題:
在loadkernel.c中2097152你是怎么計算出來的呢?也就是uclinux內核字節的大小。
for(i = 0; i < 2097152; i++){
*to = *from;
to++;
from++;
}
我通過ultraEdit計算出來的是:2732523,好像差別蠻大呀?敢問大俠如何計算?
再次謝謝了!
答:
其實在這個地方我偷了個懶,呵呵,直接設置成2M了,因為flash的大小就是2M。
請問在源代碼中在管理模式下設置堆棧指針0x800000,有什么講究嗎?為什么不啟用內部RAM,將堆棧設置在3FE0000呢?
是uclinux要求必須設置在0x800000嗎?請指教。
;Part 8
;***********************************************************************
;Set stack pointer & jump to c function
LDR sp, =0x800000
IMPORT loadkernel
LDR pc, =loadkernel
這里設置的堆棧指針只是bootloader用的,可以隨便設置在那里(SDRAM or SRAM),只要不占用0x8000開始的那塊SDRAM就可以了。 因為必須把kernel轉載到0x8000處,所以我把堆棧指針設置在了SDRAM的高端。
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -