u-boot(三)啟動檔案
阿新 • • 發佈:2018-11-26
目錄
title: u-boot(三)啟動檔案
tags: linux
date: 2018-09-24 20:56:05
---
u-boot(三)啟動檔案
彙編
cpu/arm920t/start.S
u-boot也是一個牛逼的微控制器程式,所以也就需要:
- 硬體相關初始化
- 看門狗
- 時鐘
- sdram
- nand copy程式
- 設定sp
- 接下去就是讀取核心,啟動核心等
程式實際的步驟是:
1.set the cpu to SVC32 mode 2.turn off the watchdog 3.mask all IRQs 4.判斷是不是從內部ram啟動還是模擬直接燒寫到連結地址,如果不在正確的載入地址的話,執行cpu_init_crit cpu_init_crit執行SDRAM初始化 flush v4 I/D caches, disable MMU stuff and caches, lowlevel_init 這個會去初始化sdram,這個函式在lowlevel_init.S in your board directory 也就是board\100ask24x0\lowlevel_init.S 5.Set up the stack 6.clock_init board\100ask24x0\boot_init.c 7.relocate 自動識別當前是nor還是nand啟動,nand啟動時自動cp到內部ram中執行,所以可寫 8.bss段清零 9.呼叫C函式 _start_armboot
堆疊設定如下
0x33F80000 | uboot程式 |
---|---|
·=-CFG_MALLOC_LEN | malloc area |
.=-CFG_GBL_DATA_SIZE | bdinfo |
.=-CONFIG_STACKSIZE_IRQ | IRQ 的棧 |
.=-CONFIG_STACKSIZE_FIQ | FRQ的棧 |
.=-12 | leave 3 words for abort-stack |
sp的初始位置 |
記憶體圖:
C:_start_armboot
檔案路徑:lib_arm\board.c
,這裡就是u-boot執行C程式碼的地方了.
分配了一個gd的結構體記憶體
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t)); //在這裡,_armboot_start=_start,根據連結指令碼,這也就是程式碼段的起始=0x33F80000 //也就是指向了記憶體圖128的地方了
init_sequence這裡執行一些初始化
board_init
中設定了gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
,設定了一個引數gd->bd->bi_boot_params = 0x30000100;
這個就是啟動核心引數的地址
flash/nand 初始化
堆疊初始化
- 環境變數的設定儲存(一種是程式碼寫死,一種在FLASH上儲存)
進入主迴圈
main_loop
程式碼摘要
void start_armboot (void)
{
//-----
/* Pointer is writable since we allocated a register for it */
gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
//-----
//函式指標,初始化裝置
for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
if ((*init_fnc_ptr)() != 0) {
hang ();
}
}
//---- flash初始化,識別
#ifndef CFG_NO_FLASH
/* configure available FLASH banks */
size = flash_init ();
display_flash_config (size);
#endif /* CFG_NO_FLASH */
////---- nand初始化
#if (CONFIG_COMMANDS & CFG_CMD_NAND)
puts ("NAND: ");
nand_init(); /* go init the NAND */
#endif
//------
//分配堆
/* armboot_start is defined in the board-specific linker script */
mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);
//-----
//uboot的環境變數
/* initialize environment */
env_relocate ();
//-----
//經過一系列的初始化
/* main_loop() can return to retry autoboot, if so just run it again. */
for (;;) {
main_loop ();
}
init_fnc_t *init_sequence[] = {
cpu_init, /* basic cpu dependent setup */
board_init, /* basic board dependent setup */
interrupt_init, /* set up exceptions */
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
#if defined(CONFIG_DISPLAY_CPUINFO)
print_cpuinfo, /* display cpu info (and speed) */
#endif
#if defined(CONFIG_DISPLAY_BOARDINFO)
checkboard, /* display board info */
#endif
dram_init, /* configure available RAM banks */
display_dram_config,
NULL,
};
int board_init (void)
{
---
/* support both of S3C2410 and S3C2440, by www.100ask.net */
if (isS3C2410)
{
/* arch number of SMDK2410-Board */
gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
}
else
{
/* arch number of SMDK2440-Board */
gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
}
/* adress of boot parameters */
gd->bd->bi_boot_params = 0x30000100;
}
C:main_loop
common/main.c
核心啟動
這裡實現了u-boot的倒計時,有列印命令,獲取環境變數等,最關鍵的程式碼是
s = getenv ("bootcmd");
if(倒計時結束)
{
printf("Booting Linux ...\n");
run_command (s, 0);
}
實際的環境變數是bootcmd=nand read.jffs2 0x30007FC0 kernel; bootm 0x30007FC0
,讀取核心,啟動核心
選單處理(自定義實現)
如果倒計時結束前輸入了空格,進入命令模式run_command("menu", 0);
命令處理
- 死迴圈
- 讀取串列埠輸入
len = readline (CFG_PROMPT);
- 執行命令
rc = run_command (lastcommand, flag);