新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM移植之BootLoader(4)

        ARM移植之BootLoader(4)

        作者: 時間:2016-11-10 來源:網絡 收藏
        4. BootLoader第二階段

          vivi Bootloader的第二階段又分成了八個小階段,在main函數中分別調用這幾個小階段的相關函數:

        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進行相應的復位處理:

        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內存,而軟件復位處理則什么都不做:

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

          STEP2進行板初始化,設置時間和可編程I/O口:

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

         return 0;
        }

          STEP3進行內存映射及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初始化只需要調用通用的arm920 MMU初始化函數:

        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設置堆棧;STEP5進行mtd設備的初始化,記錄MTD分區信息;STEP6設置私有數據;STEP7初始化內建命令。

          STEP8啟動一個SHELL,等待用戶輸出命令并進行相應處理。在SHELL退出的情況下,啟動操作系統:

        #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 != 主站蜘蛛池模板: 淳化县| 桃园市| 丰都县| 同江市| 洞头县| 苗栗市| 且末县| 抚远县| 凤城市| 峨边| 荆门市| 化德县| 石泉县| 大余县| 云和县| 金沙县| 临汾市| 安阳市| 额敏县| 长子县| 宜丰县| 屏山县| 昭觉县| 裕民县| 库车县| 阜平县| 苗栗市| 务川| 买车| 图片| 哈密市| 贵南县| 南部县| 蓬安县| 来宾市| 玉林市| 荥阳市| 乡宁县| 资中县| 长汀县| 阜平县|