專注電子技術(shù)學(xué)習(xí)與研究
當(dāng)前位置:單片機(jī)教程網(wǎng) >> MCU設(shè)計(jì)實(shí)例 >> 瀏覽文章

uboot之\cpu\s3c44b0\start.S文件的詳解

作者:huorr520   來源:本站原創(chuàng)   點(diǎn)擊數(shù):  更新時(shí)間:2010年12月25日   【字體:

今天總算看完了,理解完了,理解清楚了,看透了start.S~~~~~~

本來不想寫的,想想還是輕描淡寫吧:好理解的一筆帶過,難理解的重點(diǎn)介紹。

.globl _start
_start: b       reset
 add pc, pc, #0x0c000000
 add pc, pc, #0x0c000000
 add pc, pc, #0x0c000000
 add pc, pc, #0x0c000000
 add pc, pc, #0x0c000000
 add pc, pc, #0x0c000000
 add pc, pc, #0x0c000000

 .balignl 16,0xdeadbeef

_start 全局變量,uboot代碼入口,在uboot中偏移地址_start_offset=0。除了reset中斷外,其他中斷都跳到SDRAM中去執(zhí)行中斷,因此,用add指令,增加跳轉(zhuǎn)范圍。用LDR也是可以的,不過得另外定義一些變量,不如add省事,呵呵~~至于.balignl 16,0xdeadbeef網(wǎng)上都是說將地址對(duì)齊為16的倍數(shù)。為什么要對(duì)齊呢??不知道

*************************************************************************************************

_TEXT_BASE:
 .word TEXT_BASE

.globl _armboot_start
_armboot_start:
 .word _start
.globl _bss_start
_bss_start:
 .word __bss_start

.globl _bss_end
_bss_end:
 .word _end

全局變量定義聲明:

_TEXT_BASE:全局變量指示uboot將被放在SDRAM中的地址,初始化為TEXT_BASE,在uboot\board\dave\B2\config.mk中賦值

_armboot_start:全局變量,指示uboot起始地址,初始化為_start,與_bss_start共同構(gòu)成uboot的大。╯izeof(uboot)=_bss_start-_armboot_start)

_bss_start:BSS:Block Started by Symbol segment,全局變量,定義在uboot\board\dave\B2\u-boot.lds。用來存放未初始化的全局變量的一塊內(nèi)存。_bss_start:BSS段起始地址

_bss_start:BSS段結(jié)束地址,_bss_start-_bss_end=sizeof(BSS)

*************************************************************************************************

#ifdef CONFIG_USE_IRQ
/* IRQ stack memory (calculated at run-time) */
.globl IRQ_STACK_START
IRQ_STACK_START:
 .word 0x0badc0de

/* IRQ stack memory (calculated at run-time) */
.globl FIQ_STACK_START
FIQ_STACK_START:
 .word 0x0badc0de
#endif

如果要用到IRQ和FIQ就設(shè)置相應(yīng)堆棧

*************************************************************************************************

先到這~~吃飯去了

接著寫吧,有點(diǎn)難繼續(xù)下:

reset:
 mrs r0,cpsr
 bic r0,r0,#0x1f
 orr r0,r0,#0x13
 msr cpsr,r0

@系統(tǒng)上電復(fù)位后設(shè)置成SVC模式

@寄存器操作方法:讀----修改-----回寫

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 bl cpu_init_crit
 bl lowlevel_init
#endif

@如果沒有定義CONFIG_SKIP_LOWLEVEL_INIT(顧名思義:跳過底層初始化)

@沒有定義的話那就跳進(jìn)去進(jìn)行初始化吧。

@cpu_init_crit函數(shù)在本文本中 后面介紹

@lowlevel_init在\uboot\board\dave\B2\lowlevel_init.S 完成存儲(chǔ)器初始化(<1.4的uboot不是這個(gè)名稱,好像是memap.S??大概是這個(gè)名字)

#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

@如果沒有定義CONFIG_SKIP_RELOCATE_UBOOT(顧名思義:跳過重定位)

@那就要進(jìn)行重定位判斷了

@先判斷uboot放置的地址,是在flash還是在SDRAM中。如果在flash中,則要重定位,即把uboot代碼整個(gè)搬@移至SDRAM中TEXT_BASE地址處;如果在SDRAM中,則不需要搬移,直接跳到堆棧設(shè)置。

@關(guān)于怎么判斷的,詳見日志:uboot relocate

 ldr r2, _armboot_start
 ldr r3, _bss_start
 sub r2, r3, r2  /* r2 <- size of armboot            */
 add r2, r0, r2  /* r2 <- source end address         */

@如果要搬移的話,計(jì)算uboot的大小

@并將整個(gè)搬移后的地址放入r2,以進(jìn)行判斷是否搬運(yùn)完了

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

@代碼搬移,每次搬運(yùn)r3-r10個(gè)

@如果源地址和目標(biāo)地址不一樣,則說明沒搬運(yùn)完

adr r0, real_vectors
 add r2, r0, #1024
 ldr r1, =0x0c000000
 add r1, r1, #0x08
vector_copy_loop:
 ldmia r0!, {r3-r10}
 stmia r1!, {r3-r10}
 cmp r0, r2
 ble vector_copy_loop

@將flash地址中的中斷向量表搬移到SDRAM中,構(gòu)成二級(jí)中斷向量表

@當(dāng)有中斷到來時(shí),先跳轉(zhuǎn)到flash地址的中斷向量表(0x00000000),再在程序開始處的跳轉(zhuǎn)指令跳轉(zhuǎn)到

@SDRAM中的中斷向量表(0x0c000000)
#endif /* CONFIG_SKIP_RELOCATE_UBOOT */

@結(jié)束重定位,進(jìn)行堆棧設(shè)置

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           

@按照uboot存儲(chǔ)器映射圖,uboot被映射到SDRAM的高端。而在SDRAM地址減生長方向依次為

@CFG_MALLOC_LEN,CFG_GBL_DATA_SIZE,IRQ&FIQ(if define) abort_stack(12B)

@CFG_ENV_SIZE:環(huán)境變量存儲(chǔ)空間,緊接著MALLOC_LEN的前面(1024)

@MALLOC_LEN:定義在\ uboot\include\config\B2.h 為malloc()函數(shù)預(yù)留的數(shù)據(jù)空間

@同時(shí)包含CFG_ENV_SIZE,大小為(CFG_ENV_SIZE + 128*1024)

@GBL_DATA_SIZE:全局信息表gd的數(shù)據(jù)空間(128)

@IRQ&FIQ:如果定義了的話就分配
#ifdef CONFIG_USE_IRQ
 sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif

@如果定義了CONFIG_USE_IRQ 則分配IRQ和FIQ堆棧
 sub sp, r0, #12  /* leave 3 words for abort-stack    */

@分配12個(gè)字節(jié)空間為用戶棧

@注:CFG_MALLOC_LEN + CFG_GBL_DATA_SIZE + CONFIG_USE_IRQ + 12 =

@TEXT_BASE - SDRAM_start

 ldr pc, _start_armboot

_start_armboot: .word start_armboot

@跳轉(zhuǎn)到_start_armboot

@_start_armboot用start_armboot初始化,即第一個(gè)C函數(shù)

*************************************************************************************************

#define INTCON (0x01c00000+0x200000)
#define INTMSK (0x01c00000+0x20000c)
#define LOCKTIME (0x01c00000+0x18000c)
#define PLLCON (0x01c00000+0x180000)
#define CLKCON (0x01c00000+0x180004)
#define WTCON (0x01c00000+0x130000)

@cpu初始化相關(guān)的一些寄存器名宏定義

*************************************************************************************************
cpu_init_crit:
 /* disable watch dog */
 ldr  r0, =WTCON
 ldr r1, =0x0
 str r1, [r0]

@關(guān)閉看門狗

*************************************************************************************************
 ldr r1,=INTMSK
 ldr r0, =0x03fffeff
 str r0, [r1]

 ldr r1, =INTCON
 ldr r0, =0x05
 str r0, [r1]

@屏閉所有中斷,只開啟timer5做linux時(shí)鐘

*************************************************************************************************
 ldr r1, =LOCKTIME
 ldrb r0, =800
 strb r0, [r1]

@設(shè)置時(shí)鐘鎖定延遲時(shí)間

 #if CONFIG_S3C44B0_CLOCK_SPEED==66
 ldr r0, =0x34031  /* 66MHz (Quartz=11MHz) */
#elif CONFIG_S3C44B0_CLOCK_SPEED==75
 ldr r0, =0x610c1 /*B2: Xtal=20mhz Fclk=75MHz  */
#else
# error CONFIG_S3C44B0_CLOCK_SPEED undefined
#endif

@如果定義了一些系統(tǒng)時(shí)鐘的相關(guān)宏定義則設(shè)置相應(yīng)的PLLCON

@當(dāng)然自己也可以定義自己想要的時(shí)鐘 只需設(shè)置相應(yīng)的值即可

str r0, [r1]

ldr r1,=CLKCON
 ldr r0, =0x7ff8
 str r0, [r1]

@使能所有模塊的時(shí)鐘

 mov pc, lr

返回調(diào)用處
 

關(guān)閉窗口

相關(guān)文章