目錄
- u-boot(三)啟動檔案
- 彙編
- C:_start_armboot
- 代碼摘要
- C:main_loop
- 核心啟動
- 菜單處理(自定義實作)
- 指令處理
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的初始位置 |
記憶體圖:
![](https://img.laitimes.com/img/__Qf2AjLwojIjJCLyojI0JCLicmbw5SOxEzMyITNykDM4EzLcR3bvJ3LcJXZ0NXYt9CX3Fmcvw1YpB3LclHd5FGbvwVbvNmLlVGdpd2Lc9CX6MHc0RHaiojIsJye.png)
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);
轉載于:https://www.cnblogs.com/zongzi10010/p/10023676.html