u boot啟動過程分析

2021-08-25 14:08:49 字數 3792 閱讀 4068

備註:本文中使用的u-boot版本是2010.3

第一階段:初始化soc相關的配置,例如:系統時鐘、mmu、看門狗等;並為c語言提供執行環境
1、第一階段:組合語言階段
.globl _start

_start: b reset //復位異常 --> 進入管理模式:復位電平有效時觸發

ldr pc, _undefined_instruction //未定義指令異常 --> 未定義指令模式:cpu無法識別的指令時觸發

ldr pc, _software_interrupt //軟中斷異常 -->管理模式:swi指令觸發

ldr pc, _prefetch_abort //預取指令異常 -->中止模式:獲取指令不存在時觸發

ldr pc, _data_abort //資料異常 --> 中止模式:獲取資料不存在時觸發

ldr pc, _not_used //保留位

ldr pc, _irq //中斷異常 -->irq模式

ldr pc, _fiq //快速中斷異常 -->fiq模式

1.1進入管理模式

當cpu上電時,復位電平有效,cpu當做是復位異常處理,因此在此異常向量表中將執行一下指令,使得進入管理模式(supervisor):

b   reset 

reset:

/* * set the cpu to svc32 mode and irq & fiq disable

*/mrs r0, cpsr

bic r0, r0, #0x1f

orr r0, r0, #0xd3

msr cpsr,r0

1.2 關閉資料cache 和 mmu
為什麼要關閉資料cache呢,這是因為在裝置剛上電的時候,記憶體的初始化會比較慢,當cpu初始化完成後,

記憶體此時還沒做好準備,如果此時對記憶體進行資料讀取,會導致資料預取異常。

為什麼要關閉mmu?在裝置剛上電時,mmu並為初始化;其次,在會組合語言階段一般是通過操作暫存器的實際實體地址

進行配置。因此為了避免mmu的干擾,把其給遮蔽。

1.3 lowlevel_init

跳轉至符號標籤『lowlevel_init』,關閉看門狗、對系統時鐘、sdram等進行初始:

bl system_clock_init        //系統時鐘初始化

bl mem_ctrl_asm_init_ddr3 //初始化ddr3

bl uart_asm_init //初始化串列埠

/* 初始化串列埠會先後列印『o』、『k』 兩個字元 */

/* print 'o' */

ldr r1, =0x4f4f4f4f

str r1, [r0, #utxh_offset]

/* print 'k' */

ldr r0, =elfin_uart_console_base

ldr r1, =0x4b4b4b4b

str r1, [r0, #utxh_offset]

1.4 重定位
mmu_table:

…….set __base,0x400

//實體地址

// 512mb for sdram with cacheable

.rept 0x600 - 0x400

//虛擬位址範圍

fl_section_entry __base,3,0,1,1

.set __base,__base+1

.endr

……

1.5 初始化c語言執行環境

初始化棧stack_setup:為c語言提供執行環境

清除bss段:bss段用於存放初始化值為0的全域性變數和未初始化的全域性變數;並將未初始化的全域性變數初始化為0,這也是為什麼在c語言中為什麼乙個未初始化全域性變數其值為0的原因。

跳轉到c語言執行階段:start_armboot

stack_setup:

ldr sp, =(cfg_uboot_base + cfg_uboot_size - 0x1000)

clear_bss:

ldr r0, _bss_start /* find start of bss segment */

ldr r1, _bss_end /* stop here */

movr2, #0x00000000 /* clear */

clbss_l:

str r2, [r0] /* clear loop... */

addr0, r0, #4

cmp r0, r1

ble clbss_l

ldr pc, _start_armboot //將pc指標指向start_armboot函式的位址

_start_armboot:

.word start_armboot

2、第二階段:c語言階段

c語言的啟動階段的啟動函式:start_armboot,在該函式中中實現了板子相關的初始化配置

重要結構:init_sequence指標陣列,包含了板級初始化的相關函式,以下列出了函式的呼叫關係和功能:

start_armboot:

init_sequence指標陣列

board_init,板級相關的初始化(board/samsung/smdkc210),例如網絡卡驅動

interrupt_init,中斷相關的初始化

env_init,環境變數相關的初始化

init_baudrate,波特率初始化

serial_init,串列埠初始化

console_init_f,控制台第一階段初始化

display_banner,列印uboot相關的資訊

print_cpuinfo,列印cpu相關的資訊

checkboard,列印開發板相關的資訊

dram_init,配置可用記憶體大小

display_dram_config,顯示記憶體大小函式:

env_relocate (),初始化環境變數

enable_interrupts,啟動中斷

main_loop:根據啟動延時進行判斷,是進入啟動kernel階段,還是進行u-boot命令解析控制台

2.1 命令解析、並將引數傳遞給kernel

main_loop函式:通過呼叫run_command函式,執行命令解析

void main_loop (void)

……for (;;)

}

下面列出了解析名後的函式呼叫關係:

run_command-->(cmdtp->cmd) (cmdtp, flag, argc, argv):『s = getenv ("bootcmd")』-->do_bootm函式

do_bootm

do_bootm_linux<-->boot_fn(0, argc, argv, &images)(typedef 型別重新命名)

do_bootm_linux:

thekernel = (void (*)(int, int, uint))images->ep;//指向kernel的起始位址

thekernel(0,machid,bd->bi_boot_params);//將3個引數傳分別寫入暫存器r0,r1,r2傳遞給kernel

u boot 啟動過程

u boot 分為兩個階段第一階段是彙編,入口是 arch arm cpu armv7 start.s,第二階段是 c 語言,入 口是 board.c 第一階段 1.異常向量表定義 2.設定 svc32 模式 arm 七種工作模式 3.呼叫 cpu init crit 進行 cpu 相關初始化 1 ...

u boot啟動過程 1

u boot的啟動過程 1.start.s檔案 此彙編檔案是u boot啟動的第乙個檔案,首先確定是冷啟動還是熱啟動,boot cold or boot warm 通過對r21寫0x01 cold or ox02 warm 完成。接著在boot warm中 1 判斷是否定義config cogent...

u boot 原始碼分析 1 啟動過程分析

kbuild 啟動過程 第二階段 總結參考 對於uboot,我一直是雲裡霧裡的乙個狀態,這部分讓我感到自己很菜,不用縱向深入地掌握uboot整個細節,但是相對它有乙個整體流程上的把握,包括uboot的啟動啟動過程,在整個啟動過程中會涉及到哪些檔案,以此的呼叫過程是什麼?抱著這幾個問題,大量蒐集資料,...