6410所使用的內(nèi)存為DDR 210使用的是DDR2 2440使用的是SDRAM,關(guān)于他們之間的區(qū)分,我在之前的文章中ok6410內(nèi)存及啟動(dòng)流程簡(jiǎn)單介紹過,有興趣的可以看看。
S3C6410處理器擁32位地址總線,其尋址空間為4GB。其中高2GB為保存區(qū),低2GB區(qū)域又可劃分為兩部份:主存儲(chǔ)區(qū)和外設(shè)區(qū)。
外設(shè)區(qū)主要是與6410寄存器相干,在核心初始化—外設(shè)基地址初始化中,有說明外設(shè)的寄存器的基地址為0x70000000
下面則是主存儲(chǔ)區(qū)的地址散布,在之前的課程中有介紹,現(xiàn)在貼出來加強(qiáng)理解
主存儲(chǔ)區(qū)可以分為
這個(gè)區(qū)域并沒有固定的存儲(chǔ)介質(zhì)與之對(duì)應(yīng),也就是沒有實(shí)際的映照內(nèi)存。但是可以把不同的啟動(dòng)介質(zhì)的地址映照到該區(qū)域。比如說選擇了IROM 啟動(dòng)方式后,就把IROM映照到該區(qū)域。這在之前有介紹過。
這個(gè)區(qū)域?qū)?yīng)著內(nèi)部的內(nèi)存地址,iROM和SRAM都是散布在這個(gè)區(qū)間。0x08000000~0x0bffffff對(duì)應(yīng)著內(nèi)部ROM,但是IROM實(shí)際只有32KB,選擇從IROM啟動(dòng)的時(shí)候,首先運(yùn)行就是這里面的程序BL0,這部份代碼由3星固化。0x0c000000~0x0fffffff對(duì)應(yīng)內(nèi)部SRAM,實(shí)際就是8KB的Steppingstone。
這個(gè)區(qū)域用于訪問掛在外部總線上的裝備,比如說NOR flash、oneNand等。這個(gè)區(qū)
域被分割為6個(gè)bank,每一個(gè)bank為128MB,數(shù)據(jù)寬度最大支持16bit,每一個(gè)bank由片選Xm0CS[0]~Xm0CS[5] 選中。
該區(qū)域從0x50000000~0x6fffffff,又分為2個(gè)區(qū)間,分別占256MB,可以片選Xm1CS[0]~Xm1CS[1]來進(jìn)行著2個(gè)區(qū)間的選擇。我們6410開發(fā)板上256MB的DDR內(nèi)存就安排在這個(gè)區(qū)域,這也就是為何6410的內(nèi)存地址是從0x50000000開始的緣由。
如上圖可以看到,6410的內(nèi)存是由兩塊128MB的內(nèi)存芯片連接而成,除每一個(gè)芯片的16位數(shù)據(jù)位不同,其他均相同。
根據(jù)上面的DRAM控制器初始化流程,可以得到以下步驟:
根據(jù)上面的圖,可知需要設(shè)置[2:0]位設(shè)置位0b100便可
ldr r0,=0x7e001004
mov r1,#0x4
str r1,[r0]
這1步驟的主要流程在6410的手冊(cè)中并沒有找到具體的進(jìn)程,因此主要參考內(nèi)存芯片手冊(cè)和uboot相干步驟寫的。
ldr r0, =0x7e001010 @刷新寄存器地址
ldr r1, =( ( 7800 / ( 1000000000/133000000 ) + 1 ) ) @設(shè)置刷新時(shí)間
str r1, [r0]
ldr r0, =0x7e001014 @CAS latency寄存器
mov r1, #(3 << 1)
str r1, [r0]
ldr r0, =0x7e001018 @t_DQSS寄存器
mov r1, #0x1
str r1, [r0]
ldr r0, =0x7e00101c @T_MRD寄存器
mov r1, #0x2
str r1, [r0]
ldr r0, =0x7e001020 @t_RAS寄存器
ldr r1, =( ( 45 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001024 @t_RC寄存器
ldr r1, =( ( 68 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001028 @t_RCD寄存器
ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e00102c @t_RFC寄存器
ldr r1, =( ( 80 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001030 @t_RP寄存器
ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001034 @t_rrd寄存器
ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001038 @t_wr寄存器
ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
@ ldr r2, [r0]
str r1, [r0]
ldr r0, =0x7e00103c @t_wtr寄存器
mov r1, #0x07
str r1, [r0]
ldr r0, =0x7e001040 @t_xp寄存器
mov r1, #0x02
str r1, [r0]
ldr r0, =0x7e001044 @t_xsr寄存器
ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001048 @t_esr寄存器
ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e00100c @內(nèi)存控制配置寄存器
ldr r1, =0x00010012 @配置控制器
str r1, [r0]
ldr r0, =0x7e00104c @32位DRAM配置控制寄存器
ldr r1, =0x0b45
str r1, [r0]
ldr r0, =0x7e001200 @片選寄存器
ldr r1, =0x150f8
str r1, [r0]
ldr r0, =0x7e001304 @用戶配置寄存器
mov r1, #0x0
str r1, [r0]
等待200μs 來使SDRAM 電源和時(shí)鐘穩(wěn)定。當(dāng) CPU 開始工作時(shí),電源和時(shí)鐘已被穩(wěn)定下來因此過剩 不做。
下面是step4 內(nèi)存初始化中的各個(gè)步驟
根據(jù)上圖,使[19:18]位為0b011便可滿足要求,因此轉(zhuǎn)化為16進(jìn)制為0xc0000
ldr r0,=0x7e001008
ldr r1,=0xc0000
str r1,[r0]
根據(jù)上圖,使[19:18]位為0b000便可滿足要求
ldr r0,=0x7e001008
ldr r1,=0x0
str r1,[r0]
4.3 和 4.4 為相同的操作,履行兩遍
根據(jù)上圖,使[19:18]位為0b001便可滿足要求,因此轉(zhuǎn)化為16進(jìn)制為0x40000
ldr r0,=0x7e001008
ldr r1,=0x40000
str r1,[r0]
ldr r0,=0x7e001008
ldr r1,=0x40000
str r1,[r0]
參考自u(píng)boot源碼
ldr r0,=0x7e001008
ldr r1,=0xa0000
str r1,[r0]
參考自u(píng)boot源碼
ldr r0,=0x7e001008
ldr r1,=0x80032
str r1,[r0]
如上圖所示,需要設(shè)置[2:0]位0b000便可,
ldr r0,=0x7e001004
mov r1,#0x0
str r1,[r0]
根據(jù)上圖,需要設(shè)置其為ready狀態(tài),即[1:0]為0b10
check_ready:
ldr r0,=0x7e001000
ldr r1,[r0]
mov r2,#0x3
and r1,r1,r2 @將r1與r2進(jìn)行位與操作
cmp r1,#0x1 @與0x1進(jìn)行比較
bne check_ready @不相等,跳轉(zhuǎn)到check_ready
在代碼設(shè)置之前,需要設(shè)置DDR的管腳為數(shù)據(jù)管腳,要設(shè)置第2塊內(nèi)存芯片的數(shù)據(jù)引腳,以下所示
ldr r0,=0x7e00f120 @設(shè)置為數(shù)據(jù)引腳
mov r1,#0x0
str r1,[r0]
以下是全部代碼片斷:
Makefile
all: start.o mem.o
arm-linux-ld -Tgboot.lds -o gboot.elf $^
arm-linux-objcopy -O binary gboot.elf gboot.bin
%.o : %.S
arm-linux-gcc -g -c $^
%.o : %.c
arm-linux-gcc -g -c $^
.PHONY: clean
clean:
rm *.o *.elf *.bin
start.S
@****************************
@name: start.S
@by : stone
@time: 2016.6.26
@function:
@ 異常向量表
@ 設(shè)置SVC模式
@ 關(guān)閉看門狗
@ 關(guān)閉中斷
@ 關(guān)閉MMU
@ 外設(shè)基地址初始化
@ 點(diǎn)亮LED
@ 時(shí)鐘初始化
@ 內(nèi)存初始化
@****************************
.text
.global _start @將_start聲明為全局變量
_start:
b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq
_undefined_instruction: .word undefined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word fiq
undefined_instruction: @處理未定義指令異常
nop
software_interrupt: @軟中斷
nop
prefetch_abort: @預(yù)取指令異常
nop
data_abort: @數(shù)據(jù)訪問異常
nop
not_used: @空位
nop
irq: @中斷
nop
fiq: @快速中斷
nop
reset: @reset
bl set_svc @設(shè)置為SVC模式
bl set_peri_port @外設(shè)基地址初始化
bl disable_watchdog @關(guān)閉看門狗
bl disable_interrupt @關(guān)閉中斷
bl disable_mmu @關(guān)閉mmu
bl init_clock @時(shí)鐘初始化
bl mem_init @內(nèi)存初始化
bl light_led @點(diǎn)亮LED
set_svc:
mrs r0, cpsr @將值取出cpsr寄存器
bic r0, r0, #0x1f @將后5位 即M[4:0]清零
orr r0, r0, #0xd3 @0b10011 轉(zhuǎn)化為16進(jìn)制為0x13 同時(shí)為了屏蔽irq和fiq,可以將其設(shè)置為0b11010011即0xd3
msr cpsr, r0 @將值送回cpsr寄存器
mov pc, lr @返回
set_peri_port:
ldr r0, =0x70000000 @基地址
orr r0, r0, #0x13 @256MB
mcr p15,0,r0,c15,c2,4 @寫入cp15
mov pc, lr
#define pwTCON 0x7E004000 @WTCON寄存器
disable_watchdog:
ldr r0, =pwTCON @把地址裝載到R0
mov r1, #0x0 @置0,關(guān)閉看門狗
str r1,[r0]
mov pc,lr
disable_interrupt:
mvn r1,#0x0 @0x0 取反,給r1
ldr r0,=0x71200014 @VIC0
str r1,[r0]
ldr r0,=0x71300014 @VIC1
str r1,[r0]
mov pc,lr
disable_mmu:
mcr p15,0,r0,c7,c7,0 @使ICACHE 和DCACHE 無效
mrc p15,0,r0,c1,c0,0 @read control register
bic r0,r0,#0x00000007 @mmu 和 dcache置零
mcr p15,0,r0,c1,c0,0 @write control register
mov pc,lr
#define CLK_DIV0 0x7e00f020
#define CLK_SRC 0x7e00f01c
#define OTHERS 0x7e00f900
#define MPLL_CON 0X7E00F010
#define APLL_CON 0X7E00F00c
#define PLL_VAL ((1<<31)|(266<<16)|(3<<8)|(1<<0))
#define DIV_VAL ((0X0<<0)|(0X1<<9)|(0X1<<8)|(0X3<<12))
init_clock:
ldr r0,=CLK_DIV0 @設(shè)置分頻系數(shù)
ldr r1,=DIV_VAL
str r1,[r0]
ldr r0,=OTHERS @設(shè)置異步工作模式 第7位為0 第6位為0(時(shí)鐘選擇器)
ldr r1,[r0]
bic r1,r1,#0xc0
str r1,[r0]
ldr r0,=APLL_CON @APLL設(shè)置為533Mhz
ldr r1,=PLL_VAL
str r1,[r0]
ldr r0,=MPLL_CON @MPLL設(shè)置為533Mhz
ldr r1,=PLL_VAL
str r1,[r0]
ldr r0, =CLK_SRC @選擇時(shí)鐘源為APLL MPLL還是外部
mov r1, #0x3 @APLL MPLL
str r1, [r0]
mov pc,lr
#define GPMCON 0x7F008820 @控制寄存器
#define GPMDAT 0x7F008824 @數(shù)據(jù)寄存器
light_led:
ldr r0,=GPMCON
ldr r1,=0x1111 @輸出模式
str r1,[r0]
ldr r0,=GPMDAT
ldr r1,=0x00 @低電平點(diǎn)亮
str r1,[r0]
mov pc,lr
mem.S
@*************************************
@name : mem.S
@time : 2016/06/26
@function : 內(nèi)存初始化相干代碼
@************************************
.text @代碼段
.global mem_init
mem_init:
ldr r0,=0x7e00f120 @設(shè)置為數(shù)據(jù)引腳
mov r1,#0x0
str r1,[r0]
ldr r0,=0x7e001004 @配置寄存器 使DRAM控制器進(jìn)入 config 狀態(tài)
mov r1,#0x4
str r1,[r0]
ldr r0, =0x7e001010 @刷新寄存器地址
ldr r1, =( ( 7800 / ( 1000000000/133000000 ) + 1 ) ) @設(shè)置刷新時(shí)間
str r1, [r0]
ldr r0, =0x7e001014 @CAS latency寄存器
mov r1, #(3 << 1)
str r1, [r0]
ldr r0, =0x7e001018 @t_DQSS寄存器
mov r1, #0x1
str r1, [r0]
ldr r0, =0x7e00101c @T_MRD寄存器
mov r1, #0x2
str r1, [r0]
ldr r0, =0x7e001020 @t_RAS寄存器
ldr r1, =( ( 45 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001024 @t_RC寄存器
ldr r1, =( ( 68 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001028 @t_RCD寄存器
ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e00102c @t_RFC寄存器
ldr r1, =( ( 80 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001030 @t_RP寄存器
ldr r1, =( ( 23 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001034 @t_rrd寄存器
ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001038 @t_wr寄存器
ldr r1, =( ( 15 / ( 1000000000 / 133000000 ) + 1 ) )
@ ldr r2, [r0]
str r1, [r0]
ldr r0, =0x7e00103c @t_wtr寄存器
mov r1, #0x07
str r1, [r0]
ldr r0, =0x7e001040 @t_xp寄存器
mov r1, #0x02
str r1, [r0]
ldr r0, =0x7e001044 @t_xsr寄存器
ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e001048 @t_esr寄存器
ldr r1, =( ( 120 / ( 1000000000 / 133000000 ) + 1 ) )
str r1, [r0]
ldr r0, =0x7e00100c @內(nèi)存控制配置寄存器
ldr r1, =0x00010012 @配置控制器
str r1, [r0]
ldr r0, =0x7e00104c @32位DRAM配置控制寄存器
ldr r1, =0x0b45
str r1, [r0]
ldr r0, =0x7e001200 @片選寄存器
ldr r1, =0x150f8
str r1, [r0]
ldr r0, =0x7e001304 @用戶配置寄存器
mov r1, #0x0
str r1, [r0]
ldr r0,=0x7e001008
ldr r1,=0xc0000
str r1,[r0]
ldr r0,=0x7e001008
ldr r1,=0x0
str r1,[r0]
ldr r0,=0x7e001008
ldr r1,=0x40000
str r1,[r0]
ldr r0,=0x7e001008
ldr r1,=0x40000
str r1,[r0]
ldr r0,=0x7e001008
ldr r1,=0xa0000
str r1,[r0]
ldr r0,=0x7e001008
ldr r1,=0x80032
str r1,[r0]
ldr r0,=0x7e001004
mov r1,#0x0
str r1,[r0]
check_ready:
ldr r0,=0x7e001000
ldr r1,[r0]
mov r2,#0x3
and r1,r1,r2 @將r1與r2進(jìn)行位與操作
cmp r1,#0x1 @與0x1進(jìn)行比較
bne check_ready @不相等,跳轉(zhuǎn)到check_ready
mov pc,lr
菜鳥1枚,如有毛病,多多指教。。。