新聞中心

EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 自動(dòng)識(shí)別啟動(dòng)模式Nand Or Nor

自動(dòng)識(shí)別啟動(dòng)模式Nand Or Nor

作者: 時(shí)間:2016-11-22 來(lái)源:網(wǎng)絡(luò) 收藏

UBOOT-2010-03在S3C2440上的移植<二>------------硬件初始化

http://www.linuxidc.com/Linux/2011-11/46993p2.htm

Notes:2)下面代碼段紅色部分為刪除部分

本文引用地址:http://www.butianyuan.cn/article/201611/319957.htm

Notes:3)下面代碼段綠色部分為添加部分

4.1)Notes:以下資源來(lái)自大神Tekkaman Ninja博客點(diǎn)擊查看原文

移植之前還是請(qǐng)大家先看S3C2440數(shù)據(jù)手冊(cè)<第五章存儲(chǔ)器控制器>中的(也就是那個(gè)映射圖),從理論上來(lái)講,對(duì)于0x40000000以后的內(nèi)存,只有在Nor boot的時(shí)候才存在;而在nand

boot 的時(shí)候他被映射到了0x00000000,在0x40000000以后不存在內(nèi)存。如果我們?cè)趩?dòng)的時(shí)候,將一些特定的數(shù)據(jù)寫(xiě)入0x40000000~0x40001000之間,那么按照數(shù)據(jù)手冊(cè)上的說(shuō)法,如果回讀的結(jié)果和寫(xiě)入的一致說(shuō)明是nor boot,否則就是nand boot!<寫(xiě)這個(gè)文章的時(shí)候我又看了一次。。。。。。。。。>

從上圖我們可以看出,無(wú)論是Nor boot還是nandboot ,這4K的內(nèi)部SRAM都被映射到了0x40000000,而在nandboot的時(shí)候,這塊內(nèi)存同時(shí)還被映射到了0x00000000。那么一開(kāi)始提出的辦法就不可行了,而且在nandboot 的時(shí)候,寫(xiě)入0x40000000~0x40001000還會(huì)破壞自身的程序。

但是通過(guò)上面的圖,我想到了解決的辦法:
在啟動(dòng)的時(shí)候,用程序?qū)?x40000000~0x40001000中的某些位置清零,如果回讀0x00000000~0x00001000中的相應(yīng)位置后為零,說(shuō)明是Nand boot,如果是原來(lái)的數(shù)據(jù)(一定要選非零的位置)就是Nor boot。判斷完后如果是nand boot,還要恢復(fù)被改動(dòng)的數(shù)據(jù),再進(jìn)入自拷貝階段。
只要檢測(cè)的位置合理,這方法是可行的?,F(xiàn)在的關(guān)鍵是選什么位置的數(shù)據(jù)最好呢?經(jīng)過(guò)查看源碼,我選擇了在start.S文件開(kāi)頭,全局中斷向量之后的:


.balignl 16,0xdeadbeef


選這個(gè)數(shù)據(jù)作為檢測(cè)位置的理由如下:
(1)他是非零數(shù),而且數(shù)據(jù)是確定的:0xdeadbeef;
(2)他的位置是固定的:0x0000003c(0x4000003c);
(3)他在檢測(cè)程序之前,不會(huì)影響程序的向下運(yùn)行;
(4)他不屬于程序,他是一個(gè)程序中的魔數(shù)(Magic Number),用魔數(shù)來(lái)檢測(cè)也比較合理。

所以我最后的檢測(cè)步驟是:
在啟動(dòng)的時(shí)候,將0x4000003c位置開(kāi)始的四個(gè)字節(jié)清零,然后讀取0x0000003c位置開(kāi)始的四個(gè)字節(jié)。如果回讀的結(jié)果為零,說(shuō)明是nand boot,否則就是Nor boot(為了保險(xiǎn)還可以判斷是否為0xdeadbeef,不是的話就說(shuō)明有未知錯(cuò)誤,死循環(huán)!)。但是最后有一點(diǎn)很重要:如果是Nand boot,必須要復(fù)原清零的數(shù)據(jù)。原因是:在nand boot過(guò)后,會(huì)核對(duì)內(nèi)部SRAM中的4K程序,和從Nand中拷貝到SDRAM的前4K程序是否一致,如果不一致會(huì)進(jìn)入死循環(huán)。


.globl bBootFrmNORFlash
bBootFrmNORFlash:
.word 0
4.1.2)判斷當(dāng)前代碼位置,如果在內(nèi)存,直接跳到stack_setup


#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif


adr r0, _start
ldr r1, _TEXT_BASE
cmp r0, r1
beq stack_setup

4.1.3)如果代碼當(dāng)前位置不在內(nèi)存中,就判斷啟動(dòng)方式為Nand Flash或者Nor Flash

Notes:沒(méi)有說(shuō)明就默認(rèn)在以上代碼的后面添加


ldr r1, =( (4<<28)|(3<<4)|(3<<2) )
mov r0, #0
str r0, [r1]


mov r1, #0x3c
ldr r0, [r1]
cmp r0, #0
bne relocate


ldr r0, =(0xdeadbeef)
ldr r1, =( (4<<28)|(3<<4)|(3<<2) )
str r0, [r1]

4.1.4)在Nand Flash中啟動(dòng)的話,那么Nand Flash搬移代碼如下:

Notes:定義u-boot在Nand flash中存放的長(zhǎng)度為#define LENGTH_UBOOT 0x100000<1M>,可以方便修改u-boot因?yàn)椴眉艉驮鎏泶笮〉母淖兌嫉拈L(zhǎng)度。



#define LENGTH_UBOOT 0x100000
#define NAND_CTL_BASE 0x4E000000

#ifdef CONFIG_S3C2440

#define oNFCONF 0x00
#define oNFCONT 0x04
#define oNFCMD 0x08
#define oNFSTAT 0x20

@ reset NAND
mov r1, #NAND_CTL_BASE
ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]

ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control
str r2, [r1, #oNFCONT]
ldr r2, [r1, #oNFCONT]

ldr r2, =(0x6) @ RnB Clear
str r2, [r1, #oNFSTAT]
ldr r2, [r1, #oNFSTAT]

mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]

mov r3, #0 @ wait
nand1:
add r3, r3, #0x1
cmp r3, #0xa
blt nand1

nand2:
ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x4
beq nand2


ldr r2, [r1, #oNFCONT]
orr r2, r2, #0x2 @ Flash Memory Chip Disable
str r2, [r1, #oNFCONT]

@ get read to call C functions (for nand_read())
ldr sp, DW_STACK_START @ setup stack pointer
mov fp, #0 @ no previous frame, so fp=0

@ copy U-Boot to RAM
ldr r0, =TEXT_BASE
mov r1, #0x0
mov r2, #LENGTH_UBOOT
bl nand_read_ll
tst r0, #0x0
beq ok_nand_read

bad_nand_read:
loop2:
b loop2 @ infinite loop
ok_nand_read:
@ verify
mov r0, #0
ldr r1, =TEXT_BASE
mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes
go_next:
ldr r3, [r0], #4
ldr r4, [r1], #4
teq r3, r4
bne notmatch
subs r2, r2, #4
beq stack_setup
bne go_next

notmatch:
loop3:
b loop3 @ infinite loop
#endif

4.1.5)在Nor Flash中啟動(dòng)的話,那么Nor Flash搬移代碼如下:


relocate:

ldr r1, =(0xdeadbeef)
cmp r0, r1
bne loop3

adr r0, _start
ldr r1, _TEXT_BASE
ldr r2, _armboot_start
ldr r3, _bss_start
sub r2, r3, r2
add r2, r0, r2

copy_loop:
ldmia r0!, {r3-r10}
stmia r1!, {r3-r10}
cmp r0, r2
ble copy_loop

SetBootFlag:
ldr r0, =bBootFrmNORFlash
mov r1, #1
str r1, [r0]

4.1.6)刪除下面這段代碼

//#ifndef CONFIG_SKIP_RELOCATE_UBOOT
//relocate:
// adr r0, _start
// ldr r1, _TEXT_BASE
// cmp r0, r1
// beq stack_setup

// ldr r2, _armboot_start
// ldr r3, _bss_start
// sub r2, r3, r2
// add r2, r0, r2

//copy_loop:
// ldmia r0!, {r3-r10}
// stmia r1!, {r3-r10}
// cmp r0, r2
// ble copy_loop
//#endif

4.2.1)在_start_armboot: .word start_armboot 后面添加:

#define STACK_BASE 0x33f00000
#define STACK_SIZE 0x10000
.align 2
DW_STACK_START: .word STACK_BASE+STACK_SIZE-4

Notes1):如果你不是第一次移植UBOOT那么建議好好的理解一下上面這些代碼<當(dāng)然加入你還是第一次的話那么好了直接COPY吧很管用的>

Notes2):上面用到了一個(gè)nand_read_ll函數(shù),該函數(shù)用來(lái)讀NANDFLASH的<下一篇就是實(shí)現(xiàn)這個(gè)UBOOT對(duì)NAND的支持了先休息一下吧>



評(píng)論


技術(shù)專區(qū)

關(guān)閉