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