Bootloaderソース分析

3091 ワード

BootloaderはLinuxシステムの起動前のハードウェア初期化を完了し、C実行エントリにジャンプしてfirmwareの初期化部分を行う.ここでは主にアセンブリ部分を分析します.
U-boot起動プロセスは多段階タイプに属する.第1段階はCPUアーキテクチャの初期化を完了し、通常アセンブリによって完了する.第2段階は初期化ハードウェア、メモリマッピング、TFT P伝送、シリアルポートデバッグ、カーネルパラメータ伝達などの複雑な機能を実現し、通常C言語で実現される.
1.第一段階コード分析
第1段階のソースファイルは、CPU初期化関連および開発ボード初期化関連のそれぞれに対応する/cpu/arm 920 t/startを含む.Sとboard/**/lowlevel_init.Sファイル.
1.1. ハードウェア初期化
CPUの正常な動作を完了するには、クロック、動作モード、MMUなどの初期化動作が必要です.
reset:
    /*
     *   CPU          (SVC32)
     */
     mrs r0,cpsr
    bic r0,r0,#0x1f
    orr r0,r0,#0xd3
    msr cpsr,r0
    ldr     r0, =pWTCON /*     */
    mov     r1, #0x0
     str     r1, [r0]
   .....
bl  cpu_init_crit /*        CPU   MMU Cache */

1.2 SDRAMコントローラの初期化
Bootloaderの第2段階コードRAM空間を準備します.
lowlevel_init:
    ldr     r0, =SMRDATA /*13         */
    ldr r1, _TEXT_BASE
    sub r0, r0, r1      /*    */
    ldr r1, =BWSCON /* Bus Width Status Controller */
    add     r2, r0, #13*4   /*SMRDATA     */
    0:                          /*      */
    ldr     r3, [r0], #4
    str     r3, [r1], #4
    cmp     r2, r0
    bne     0b

    /* everything is fine now */
    mov pc, lr
    .ltorg
  /* the literal pools origin */
SMRDATA:
   .word ....


1.3スタックの設定
stack_setup:
    ldr r0, _TEXT_BASE  /*            */
    sub r0, r0, #CFG_MALLOC_LEN/*   malloc     */
    sub r0, r0, #CFG_GBL_DATA_SIZE /*       */

#ifdef CONFIG_USE_IRQ
    sub r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
    /*IRQ FIQ    */
#endif
    sub sp, r0, #12     /*   12   abord    */

1.4 Bootloader第二段階プログラムをRAM空間にコピーする
relocate:               /*  U-boot   RAM  */
    adr r0, _start      /*             r0 */
    ldr r1, _TEXT_BASE/*              r1 */
    cmp     r0, r1         /* don't reloc during debug */
    beq     clear_bss    /*     RAM   ,      */
    ldr r2, _armboot_start /*    */
    ldr r3, _bss_start  /*BSS               */
    sub r2, r3, r2      /*        r2*/
    bl  CopyCode2Ram    /*Nand   (  bord/boot_init.c )
                                  r0: source, r1: dest, r2: size*/
    add r2, r0, r2  /* r2 

1.5 C入口へジャンプ
ジャンプする前にスタックスペースをクリアし、PCポインタを/lib_にジャンプします.arm/board.cのstart_armboot()関数はbootloaderの第2段階コードの実行を開始する.
ldr pc, _start_armboot
_start_armboot: .word start_armboot

2.第2段階コード分析
Bootloaderの第2段階の仕事はlibから完成しますarm/board.cのstart_armboot()関数は、第1のフェーズがジャンプしたアドレスである実行を開始します.この部分から以下はすべてCで作成して完成して、分析するのは比較的に容易で、あまり紹介しないで、順次完成する主な仕事:
  • size = flash_init ();
  • nand_init();/* go init the NAND */
  • env_relocate ();/* initialize environment */
  • devices_init ();/* get the devices list going. */
  • jumptable_init ();/* ジャンプリストの初期化*/
  • console_init_r ();/* fully init console as a device */
  • enable_interrupts ();/* 割り込みイネーブル*/
  • board_late_init ();
  • eth_initialize(gd->bd);/* 初期化ポート*/
  • main_loop()でデッドループし,ユーザのインタラクションを待つ.
  • for (;;)
    {
      main_loop ();
    }