uboot移植第二天——代碼分析(2)

今天是uboot移植學習第二天,通過csdn博客記錄自己的學習過程,希望通過這個方法,使自己所學的知識得到複習和擴展,總結經驗發現不足,也希望自己的博客能夠給人啓發,疑問的到解決。

uboot中start.S相關代碼分析

這次主要對代碼分析(1)的第一階段相關代碼分析

  1. 設置爲管理模式
reset:
    /*
     * set the cpu to SVC32 mode
     */
    mrs r0,cpsr①
    bic r0,r0,#0x1f②
    orr r0,r0,#0xd3③
    msr cpsr,r0④


CPSR 是當前的程序狀態寄存器(Current Program Status Register),
而 SPSR 是保存的程序狀態寄存器(Saved Program Status Register)
1、 MRS指令
MRS指令的格式爲:
MRS{條件} 通用寄存器,程序狀態寄存器(CPSR或SPSR)
MRS指令用於將程序狀態寄存器的內容傳送到通用寄存器中。該指令一般用在以

①:將cpsr(當前程序狀態寄存器)的值讀到r0中
②:清除r0中的後5位,因爲在cpsr中第五位爲模式設置位
③:將r0第五位或上0xd3
④:將r0的值寫入cpsr,這樣就將我們的處理器設置爲了管理模式

2、turn off the watchdog——關閉看門狗

    ldr     r0, =pWTCON
    mov     r1, #0x0
    str     r1, [r0]
    解釋:往pWTCON寄存器中寫0即可

3、mask all IRQs by setting all bits in the INTMR——關閉外部中斷

    ldr r1, =0x7fff
    ldr r0, =INTSUBMSK
    str r1, [r0]
    解釋:INTSUBMSK寄存器全寫1,就把中斷給mask了。INTSUBMSK寄存器如下:

這裏寫圖片描述
4、設置時鐘比例

    /* FCLK:HCLK:PCLK = 1:2:4 */
    /* default FCLK is 120 MHz ! */
    ldr r0, =CLKDIVN
    mov r1, #3
    str r1, [r0]
解析:The S3C2440A supports selection of Dividing Ratio between FCLK, HLCK and PCLK. This ratio is determined by
HDIVN and PDIVN of CLKDIVN control register.
通過設置HDIVN and PDIVN of CLKDIVN的值確定時鐘的比例

這裏寫圖片描述

5、bl lowlevel_init——存儲控制器初始化

    ldr     r0, =SMRDATA
    ldr r1, _TEXT_BASE
    sub r0, r0, r1
    ldr r1, =BWSCON /* Bus Width Status Controller 0x48000000*/
    add     r2, r0, #13*4
解析:剛開始時代碼和數據都只是保存在norflash上內存中還沒有。
所以不能用鏈接地址讀取SMRDATA開始處的數據。
_TEXT_BASE:
.word TEXT_BASE  這個是我們的鏈接地址,即代碼運行時所在的地址。
BWSCON:存儲控制器相關寄存器的起始寄存器
SMRDATA:表示13個寄存器的值得存放的開始地址(鏈接地址)在內存中,但現在不能讀取。
sub r0, r0, r1算出SMRDATA的相對地址(在norflash上13個寄存器的值得存放的開始地址)啓動時是可以讀取的,使得板子啓動時不在連接地址上時也能取SMRDATA中的值進行初始化存儲控制器。

注:
在重定位後,在我們的內存中(sdram)會有我們flash中的內容,在編譯時是按鏈接地址編譯,ldr r0, =SMRDATA中r0的值爲內存中的地址(即在內存中13個寄存器的值得存放的開始地址,在flash中也有,TEXT_BASE 鏈接地址也是內存的地址,因此我們要計算出SMRDATA對於TEXT_BASE的相對偏移,這個相對偏移的值就是SMRDATA在flash的起始地址)。

6、重定位——即就是把falsh中的代碼複製到ram中,本開發板複製到sdram中;

7、stack_setup——設置堆棧,因爲接下來要調c函數,來進行更復雜的處理。

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  

解析: 
r0
= TEXT_BASE
= 0x33D00000
而關於sub指令:
SUB : 減法
(Subtraction)
SUB{條件}{S} <dest>, <op 1>, <op 2>
dest = op_1 - op_2
SUB 用操作數 one 減去操作數 two,把結果放置到目的寄存器中。操作數 1 是一
個寄存器,操作數 2 可以是一個寄存器,被移位的寄存器,或一個立即值:
SUB R0, R1, R2 ; R0 = R1 - R2
SUB R0, R1, #256 ; R0 = R1 - 256
SUB R0, R2, R3,LSL#1 ; R0 = R2 - (R3 << 1)
減法可以在有符號和無符號數上進行

#CFG_MALLOC_LEN、#CFG_GBL_DATA_SIZE是宏定義

8、clear_bss——清bss段,該段存放的是初始化爲零或爲未初始化的變量,只要額外的放在一個段就行,使用時取就行;
進入uboot的第二階段

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, #4
    cmp r0, r1
    ble clbss_l

解析:
此處的_bss_start是:
.globl _bss_start
_bss_start:
.word __bss_start
而_bss_end,是:
.globl _bss_end
_bss_end:
.word _end
對應的,__bss_start和_end,都在前面提到過的那個鏈接腳本里面:
u-boot-1.1.6\board\smdk2410\u-boot.lds中的:
__bss_start = .;
.bss : { *(.bss) }
_end = .;
即bss段的起始地址和結束地址
往裏面的值全部賦值爲0

以上對uboot做了個非常粗略的分析,因本人初學記錄下的學習筆記,也希望能夠幫到正在學習uboot移植的學子,若有不對之處,望各位指出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章