<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          ARM移植之BootLoader(4)

          作者: 時間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
          4. BootLoader第二階段

            vivi Bootloader的第二階段又分成了八個小階段,在main函數(shù)中分別調(diào)用這幾個小階段的相關(guān)函數(shù):

          int main(int argc, char *argv[])
          {
          int ret;

          /*
          * Step 1:
          */
          putstr("rn");
          putstr(vivi_banner);

          reset_handler();

          /*
          * Step 2:
          */
          ret = board_init();
          if (ret) {
          putstr("Failed a board_init() procedurern");
          error();
          }

          /*
          * Step 3:
          */
          mem_map_init();
          mmu_init();
          putstr("Succeed memory mapping.rn");

          /*
          * Now, vivi is running on the ram. MMU is enabled.
          */

          /*
          * Step 4:
          */
          /* initialize the heap area*/
          ret = heap_init();
          if (ret) {
          putstr("Failed initailizing heap regionrn");
          error();
          }

          /* Step 5:
          */
          ret = mtd_dev_init();

          /* Step 6:
          */
          init_priv_data();

          /* Step 7:
          */
          misc();

          init_builtin_cmds();

          /* Step 8:
          */
          boot_or_vivi();

          return 0;
          }

            STEP1的putstr(vivi_banner)語句在串口輸出一段字符說明vivi的版本、作者等信息,vivi_banner定義為:

          const char *vivi_banner =
          "VIVI version " VIVI_RELEASE " (" VIVI_COMPILE_BY "@"
          VIVI_COMPILE_HOST ") (" VIVI_COMPILER ") " UTS_VERSION "rn";

            reset_handler進(jìn)行相應(yīng)的復(fù)位處理:

          void
          reset_handler(void)
          {
           int pressed;

           pressed = is_pressed_pw_btn();

           if (pressed == PWBT_PRESS_LEVEL) {
            DPRINTK("HARD RESETrn");
            hard_reset_handle();
           } else {
            DPRINTK("SOFT RESETrn");
            soft_reset_handle();
           }
          }

            hard_reset_handle會clear內(nèi)存,而軟件復(fù)位處理則什么都不做:

          static void
          hard_reset_handle(void)
          {
           clear_mem((unsigned long)USER_RAM_BASE, (unsigned long)USER_RAM_SIZE);
          }

            STEP2進(jìn)行板初始化,設(shè)置時間和可編程I/O口:

          int board_init(void)
          {
           init_time();
           set_gpios();

           return 0;
          }

            STEP3進(jìn)行內(nèi)存映射及MMU初始化:

          void mem_map_init(void)
          {
           #ifdef CONFIG_S3C2410_NAND_BOOT
            mem_map_nand_boot();
           #else
            mem_map_nor();
           #endif
           cache_clean_invalidate();
           tlb_invalidate();
          }

            S3C2410A的MMU初始化只需要調(diào)用通用的arm920 MMU初始化函數(shù):

          static inline void arm920_setup(void)
          {
          unsigned long ttb = MMU_TABLE_BASE;

          __asm__(
          /* Invalidate caches */
          "mov r0, #0n"
          "mcr p15, 0, r0, c7, c7, 0n" /* invalidate I,D caches on v4 */
          "mcr p15, 0, r0, c7, c10, 4n" /* drain write buffer on v4 */
          "mcr p15, 0, r0, c8, c7, 0n" /* invalidate I,D TLBs on v4 */
          /* Load page table pointer */
          "mov r4, %0n"
          "mcr p15, 0, r4, c2, c0, 0n" /* load page table pointer */
          /* Write domain id (cp15_r3) */
          "mvn r0, #0n" /* Domains 0, 1 = client */
          "mcr p15, 0, r0, c3, c0, 0n" /* load domain access register */
          /* Set control register v4 */
          "mrc p15, 0, r0, c1, c0, 0n" /* get control register v4 */
          /* Clear out unwanted bits (then put them in if we need them) */
          /* .RVI ..RS B... .CAM */
          "bic r0, r0, #0x3000n" /* ..11 .... .... .... */
          "bic r0, r0, #0x0300n" /* .... ..11 .... .... */
          "bic r0, r0, #0x0087n" /* .... .... 1... .111 */
          /* Turn on what we want */
          /* Fault checking enabled */
          "orr r0, r0, #0x0002n" /* .... .... .... ..1. */
          #ifdef CONFIG_CPU_D_CACHE_ON
          "orr r0, r0, #0x0004n" /* .... .... .... .1.. */
          #endif
          #ifdef CONFIG_CPU_I_CACHE_ON
          "orr r0, r0, #0x1000n" /* ...1 .... .... .... */
          #endif
          /* MMU enabled */
          "orr r0, r0, #0x0001n" /* .... .... .... ...1 */
          "mcr p15, 0, r0, c1, c0, 0n" /* write control register */
          : /* no outputs */
          : "r" (ttb) );
          }

            STEP4設(shè)置堆棧;STEP5進(jìn)行mtd設(shè)備的初始化,記錄MTD分區(qū)信息;STEP6設(shè)置私有數(shù)據(jù);STEP7初始化內(nèi)建命令。

            STEP8啟動一個SHELL,等待用戶輸出命令并進(jìn)行相應(yīng)處理。在SHELL退出的情況下,啟動操作系統(tǒng):

          #define DEFAULT_BOOT_DELAY 0x30000000
          void boot_or_vivi(void)
          {
          char c;
          int ret;
          ulong boot_delay;

          boot_delay = get_param_value("boot_delay", &ret);
          if (ret) boot_delay = DEFAULT_BOOT_DELAY;
          /* If a value of boot_delay is zero,
          * unconditionally call vivi shell */
          if (boot_delay == 0) vivi_shell();


          /*
          * wait for a keystroke (or a button press if you want.)
          */
          printk("Press Return to start the LINUX now, any other key for vivin");
          c = awaitkey(boot_delay, NULL);
          if (((c != r) && (c != n) && (c != 看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();