uboot移植之啓動過程--彙編過程start.s
說明:本文基於uboot-1.16,代碼來源其中,代碼版權歸原作者所有。
代碼版權:Copyright (C) 2001 - 2011 by Wolfgang Denk, DENX Software Engineering.
Copyright (C) 2003 - 2011 by Detlev Zundel, DENX Software Engineering.
Copyright (C) 2003 - 2011 by contributing authors
出處:http://blog.csdn.net/hail100
uboot啓動大致分2步: 第一步主要是完成關wacthdog、mmu,系統時鐘的初始化,mem初始化,最後是uboot代碼複製到RAM中,跳到c語言函數,這階段主要用匯編在start.S,lowlevel_init.S中完成。第二步完成複雜設備的初始化,開啓命令行,其主要由c語言完成。本文介紹smdk2410的start.S。
正文:
smdk2410使用arm920T的內核,可以到arm官網上下載用戶手冊。http://infocenter.arm.com/help/index.jsp 。本文將結合用戶手冊和uboot代碼介紹uboot啓動第一階段。主要代碼在uboot-1.1.6/cpu/arm920t/start.S,注意是(.S)這文件在編譯時要先經過預處理、有頭文件的包含、宏定義的替代,(.s)不會預處理。
/*
*************************************************************************
*
* Jump vector table as in table 3.1 in [1]
* arm 都是通過跳轉向量完成啓動、中斷
*
*************************************************************************
*/
.globl _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
.balignl 16,0xdeadbeef ====================================================================================================================================
/*
*/
@ 重啓從這開始
reset:
/*
* set the cpu to SVC32 mode
*/
@ uboot需要在管理模式中執行,msr和mrs 都是僞指令
@ 並禁止fiq 和irq
bic r0, r0, #0x1f
orr r0, r0, #0xd3
msr cpsr, r0
@ 關watchdog
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
@ 關中斷
/*
* mask all IRQs by setting all bits in the INTMR - default
*/
mov r1, #0xffffffff
ldr r0, =INTMSK
str r1, [r0]
# if defined(CONFIG_S3C2410)
ldr r1, =0x3ff
ldr r0, =INTSUBMSK
str r1, [r0]
# endif
@ 設置時鐘,設置其分頻
@ 時鐘的配置是很重要的,將對以後的其他配置產生影響
@ 因此要爲後面的配置考慮好時序,儘量做到容易修改,用宏定義
@ 看好各個時鐘所控制的設備,知道其頻率
/* default FCLK is 120 MHz ! */
ldr r0, =CLKDIVN
mov r1, #3
str r1, [r0]
#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 */
@ cpu初始化, 後面分析
/*
* we do sys-critical inits only at reboot,
* not when booting from ram!
*/
#ifndef CONFIG_SKIP_LOWLEVEL_INIT
bl cpu_init_crit
#endif
@ 判斷uboot是不是在RAM中啓動
#ifndef CONFIG_SKIP_RELOCATE_UBOOT
relocate: /* relocate U-Boot to RAM */
adr r0, _start /* r0 <- current position of code */
ldr r1, _TEXT_BASE /* test if we run from flash or RAM */
cmp r0, r1 /* don't reloc during debug */
beq stack_setup
@ 可以在前面找到_armboot_start,_bss_start的定義
@ __bss_start 在u-boot.lds 裏
@ 這是從nor flash啓動時, 完成uboot到ram的複製
@nand flash 的複製要複雜的多,需要控制nand分塊複製
ldr r3, _bss_start
sub r2, r3, r2 /* r2 <- size of armboot */
add r2, r0, r2 /* r2 <- source end address */
copy_loop:
ldmia r0!, {r3-r10} /* copy from source address [r0] */
stmia r1!, {r3-r10} /* copy to target address [r1] */
cmp r0, r2 /* until source end addreee [r2] */
ble copy_loop
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */
@ 設置堆棧指針
/* Set up the stack */
stack_setup:
ldr r0, _TEXT_BASE /* upper 128 KiB: relocated uboot */
sub r0, r0, #CFG_MALLOC_LEN /* malloc area */
sub r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo */
#ifdef CONFIG_USE_IRQ
sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
sub sp, r0, #12 /* leave 3 words for abort-stack */
@ 清零bss區
clear_bss:
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end /* stop here */
mov r2, #0x00000000 /* clear */
clbss_l:
str r2, [r0] /* clear loop... */
add r0, r0, #4cmp r0, r1
ble clbss_l
@ 從這開始跳到c語言入口
ldr pc, _start_armboot
_start_armboot: .word start_armboot
====================================================================================================================================
cache和mmu的操作都是在協處理器中完成的,協處理器 p15的操作可以看arm920t用戶手冊。
cpu_init_crit:
@ 刷新cache
/*
* flush v4 I/D caches
*/
mov r0, #0
mcr p15, 0, r0, c7, c7, 0 /* flush v3/v4 cache */
mcr p15, 0, r0, c8, c7, 0 /* flush v4 TLB */
@ 禁止MMU 和 caches,這是cp15中的c1寄存器控制的
/*
* disable MMU stuff and caches
*/
mrc p15, 0, r0, c1, c0, 0
bic r0, r0, #0x00002300 @ clear bits 13, 9:8 (--V- --RS)
bic r0, r0, #0x00000087 @ clear bits 7, 2:0 (B--- -CAM)
orr r0, r0, #0x00000002 @ set bit 2 (A) Align
orr r0, r0, #0x00001000 @ set bit 12 (I) I-Cache
mcr p15, 0, r0, c1, c0, 0
/*
* before relocating, we have to setup RAM timing
* because memory timing is board-dependend, you will
* find a lowlevel_init.S in your board directory.
*/
mov ip, lr
@ 跳到 lowlevel_init.S中,完成RAM時序配置
bl lowlevel_init
mov lr, ip
mov pc, lr
====================================================================================================================================
在u-boot-1.1.6/board/smdk2410/lowlevel_init.S中完成RAM時序的配置,這需要看系統頻率和所用RAM工作時序,來配置smdk2410的RAM控制器。
_TEXT_BASE:
.word TEXT_BASE
.globl lowlevel_init
lowlevel_init:
@對於sdram的控制,主要是設置其控制器。其中有時序的配置,
@需要看ram的手冊查詢,要配置好系統時鐘,計算出是多個ram控制器時鐘
@還有就是看soc手冊講解的控制器配置流程
/* memory control configuration */
/* make r0 relative the current location so that it */
/* reads SMRDATA out of FLASH rather than memory ! */
ldr r0, =SMRDATA
ldr r1, _TEXT_BASE
sub r0, r0, r1
ldr r1, =BWSCON /* Bus Width Status Controller */
add r2, r0, #13*4
0:
ldr r3, [r0], #4
str r3, [r1], #4
cmp r2, r0
bne 0b
/* everything is fine now */
mov pc, lr
.ltorg
/* the literal pools origin */
SMRDATA:
.word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+(B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))
.word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+(B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))
.word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+(B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))
.word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+(B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))
.word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+(B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))
.word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+(B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))
.word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+(B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))
.word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))
.word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))
.word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)
.word 0x32
.word 0x30
.word 0x30
====================================================================================================================================
start.S最後中斷的入口,中斷的宏完成現場保存,跳到中斷處理函數。do_xxx 都在 interrupt.c中處理。