MX51 uboot 啟動流程分析 – stage1

來源:互聯網
上載者:User

uboot啟動過程分為兩個部分,一般來說,系統在執行uboot之前會執行一段固化的程式,這段固化的程式會做一些基本的初始化,然後讀取uboot的第一部分到內部記憶體中,PC指標跳轉到這個記憶體位址,執行uboot的第一部分。

uboot的第一部分要執行一些必要的硬體初始化,從我的理解至少包括外部ram的初始化,flash device的初始化,因為馬上就要把第二段uboot從flash讀入到外部ram中

有人可能會問,為什麼不把uboot全部讀入ram,然後從頭開始執行,而是費了半天勁,讀了兩次uboot?

這是因為在讀取第一部分uboot前,外部記憶體還不能使用,只能使用內部ram,從擴充性的角度,不能假定整個uboot可以裝入內部ram。因此先裝入一部分uboot,把外部ram初始化好,再把剩下的大部分uboot裝到外部ram中執行。

uboot的第一階段工作

1 硬體裝置初始化

2 載入uboot的第二段代碼到RAM空間

3 設定好棧

4 跳轉到第二階段的進入點

uboot的入口start.S

cpu/arm_cortexa8/start.S

 36 .globl _start
 37 _start: b   reset
 38     ldr pc, _undefined_instruction
 39     ldr pc, _software_interrupt
 40     ldr pc, _prefetch_abort
 41     ldr pc, _data_abort
 42     ldr pc, _not_used
 43     ldr pc, _irq
 44     ldr pc, _fiq
 45
 46 _undefined_instruction: .word undefined_instruction
 47 _software_interrupt:    .word software_interrupt
 48 _prefetch_abort:    .word prefetch_abort
 49 _data_abort:        .word data_abort
 50 _not_used:      .word not_used
 51 _irq:           .word irq
 52 _fiq:           .word fiq
 53 _pad:           .word 0x12345678 /* now 16*4=64 */
 54 .global _end_vect
 55 _end_vect:

行36 _start是GNU彙編器的預設入口標籤,.globl將_start聲明為外部程式可以訪問的標籤,.globl是GNU彙編的保留關鍵字,前面加點是GNU彙編的文法

b reset是uboot的第一條指令

38~44 ARM體繫結構規定在上電複位的起始位置後,必須有8條連續的跳轉指令,他們就是異常向量表。以後系統每當有異常出現,則CPU會根據異常號,從記憶體的0x00000000處開始查表做相應的處理

 69 _TEXT_BASE:
 70     .word   TEXT_BASE
 uboot鏡像在SDRAM中的重定位地址,.word關鍵字是指定_TEXT_BASE中存放的是WORD尺寸的資料,TEXT_BASE在mx51中定義為0x97800000

至於TEXT_BASE為什麼定義為0x97800000,這是board特定的。

首先mx51的外部ram起始地址空間是0x90000000,終結地址空間是0xb0000000總共512MB,而0x97800000指向的是120MB,一般來說板子都有128MB的SDRAM,所以把uboot的鏡像copy到120MB的位置是可以正常工作的,當然我們也可以把config.mk中的-Text修改為更大的值,畢竟我們的SDRAM一般為256MB以上

 72 .globl _armboot_start
 73 _armboot_start:
 74     .word _start

72定義_armboot_start為全域的,使得LD能夠看到這個符號

74定義_armboot_start為_start

 79 .globl _bss_start
 80 _bss_start:
 81     .word __bss_start
__bs_start是在u-boot.lds中定義的

103 reset:
104     /*
105      * set the cpu to SVC32 mode
106      */
107     mrs r0, cpsr
108     bic r0, r0, #0x1f
109     orr r0, r0, #0xd3
110     msr cpsr,r0

103 reset: 是複位後的起始地址,在CPU一上電以後就會跳到這裡執行

136 #ifndef CONFIG_SKIP_LOWLEVEL_INIT
137     bl  cpu_init_crit
138 #endif

執行CPU初始化,bl完成跳轉後會把後面的一條指令地址儲存到串連寄存器LR(R14)中,以便使得子程式執行完後正常返回

40 #ifndef CONFIG_SKIP_RELOCATE_UBOOT
141 relocate:               @ relocate U-Boot to RAM
142     adr r0, _start      @ r0 <- current position of code
143     ldr r1, _TEXT_BASE      @ test if we run from flash or RAM
144     cmp r0, r1          @ don't reloc during debug
145     beq stack_setup
146
147     ldr r2, _armboot_start
148     ldr r3, _bss_start
149     sub r2, r3, r2      @ r2 <- size of armboot
150     add r2, r0, r2      @ r2 <- source end address
151
152 copy_loop:              @ copy 32 bytes at a time
153     ldmia   r0!, {r3 - r10}     @ copy from source address [r0]
154     stmia   r1!, {r3 - r10}     @ copy to   target address [r1]
155     cmp r0, r2          @ until source end addreee [r2]
156     ble copy_loop
157 #endif  /* CONFIG_SKIP_RELOCATE_UBOOT */

141~157 此時外部記憶體已經初始化完畢,已經可以使用外部記憶體,需要重定位代碼,即將uboot搬運到_TEXT_BASE位置處
142 ~145比較當前位置和_TEXT_BASE,如果相同則直接跳轉到stack設定即可

149 armboot尺寸應該是資料區段起始位置減去程式碼片段起始位置,也就是_bss_start - _armboot_start

150 source結束位址是_start加armboot的尺寸,也就是_start + armboot_size

152 ~ 156 r0是源地址,r1是目標地址,把源地址的內容複寫到目標地址,複製數目由r2定義

153 從源地址r0讀取8個寄存器32 bytes到r3~r10

154 把r3~r10共8個寄存器32bytes拷貝到r1指向的記憶體位址

155~156 迴圈操作,直到armboot的尺寸

159     /* Set up the stack */
160 stack_setup:
161     ldr r0, _TEXT_BASE      @ upper 128 KiB: relocated uboot
162     sub r0, r0, #CONFIG_SYS_MALLOC_LEN @ malloc area
163     sub r0, r0, #CONFIG_SYS_GBL_DATA_SIZE @ bdinfo
164 #ifdef CONFIG_USE_IRQ
165     sub r0, r0, #(CONFIG_STACKSIZE_IRQ + CONFIG_STACKSIZE_FIQ)
166 #endif
167     sub sp, r0, #12     @ leave 3 words for abort-stack
168     and sp, sp, #~7     @ 8 byte alinged for (ldr/str)d

162 將從_TEXT_BASE - CONFIG_SYS_MALLOC_LEN開始到_TEXT_BASE的記憶體空間預留給malloc

163 又在malloc區下面預留了CONFIG_SYS_GBL_DATA_SIZE的空間給global data

164 ~ 168 最下面的空間預留給了堆棧,看來uboot中堆棧是從低地址向高地址增長的

170     /* Clear BSS (if any). Is below tx (watch load addr - need space) */
171 clear_bss:
172     ldr r0, _bss_start      @ find start of bss segment
173     ldr r1, _bss_end        @ stop here
174     mov r2, #0x00000000     @ clear value
175 clbss_l:
176     str r2, [r0]        @ clear BSS location
177     cmp r0, r1          @ are we at the end yet
178     add r0, r0, #4      @ increment clear index pointer
179     bne clbss_l         @ keep clearing till at end
bss段用來存放全域未初始設定變數,清除這個地區,使得這些全域變數的初始值為0

184     ldr pc, _start_armboot  @ jump to C code
185
186 _start_armboot: .word start_armboot

184 跳轉到C代碼入口start_armboot,start_armboot在lib_arm/board.c中

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.