天天看點

u-boot(三)啟動檔案u-boot(三)啟動檔案

目錄

  • 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也是一個牛逼的單片機程式,是以也就需要:

  1. 硬體相關初始化
    1. 看門狗
    2. 時鐘
    3. sdram
    4. nand copy程式
  2. 設定sp
  3. 接下去就是讀取核心,啟動核心等

程式實際的步驟是:

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的初始位置

記憶體圖:

u-boot(三)啟動檔案u-boot(三)啟動檔案

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);

指令處理

  1. 死循環
  2. 讀取序列槽輸入

    len = readline (CFG_PROMPT);

  3. 執行指令

    rc = run_command (lastcommand, flag);

轉載于:https://www.cnblogs.com/zongzi10010/p/10023676.html

繼續閱讀