码迷,mamicode.com
首页 > 其他好文 > 详细

uboot启动第二阶段--start_armboot函数

时间:2016-05-10 12:38:07      阅读:333      评论:0      收藏:0      [点我收藏+]

标签:

uboot第二阶段应该做什么?

uboot的第二阶段就是要初始化剩下的还没被初始化的硬件,主要是SOC外部硬件(譬如inand、网卡芯片)、uboot本身的一些东西(uboot的命令、环境变量等),然后最终初始化完必要的东西后进入uboot的命令行准备接受命令。

 

uboot第二阶段完结于何处?

uboot启动后自动运行打印出很多信息,这些信息就是uboot第一和第二阶段不断进行初始化时,打印出来的信息,然后uboot进入了bootdelay然后执行bootcmd对应的启动命令,如果这时候用户不干涉,会执行bootcmd进入自动启动内核的流程了。(uboot的生命周期就结束了);所以uboot完结于命令行下,读取命令,解析命令,执行命令。命令行死循环是uboot的最终归宿

void start_armboot (void)
{
    init_fnc_t **init_fnc_ptr;
    char *s;
    int mmc_exist = 0;
#if !defined(CFG_NO_FLASH) || defined (CONFIG_VFD) || defined(CONFIG_LCD)
    ulong size;
#endif

#if defined(CONFIG_VFD) || defined(CONFIG_LCD)
    unsigned long addr;
#endif

#if defined(CONFIG_BOOT_MOVINAND)
    uint *magic = (uint *) (PHYS_SDRAM_1);
#endif

    /* Pointer is writable since we allocated a register for it */
#ifdef CONFIG_MEMORY_UPPER_CODE /* by scsuh */
    ulong gd_base;

    gd_base = CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE - sizeof(gd_t);
#ifdef CONFIG_USE_IRQ
    gd_base -= (CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ);
#endif
    gd = (gd_t*)gd_base;
#else
    gd = (gd_t*)(_armboot_start - CFG_MALLOC_LEN - sizeof(gd_t));
#endif

    /* compiler optimization barrier needed for GCC >= 3.4 */
    __asm__ __volatile__("": : :"memory");

    memset ((void*)gd, 0, sizeof (gd_t));
    gd->bd = (bd_t*)((char*)gd - sizeof(bd_t));
    memset (gd->bd, 0, sizeof (bd_t));

    monitor_flash_len = _bss_start - _armboot_start;

    for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
        if ((*init_fnc_ptr)() != 0) {
            hang ();
        }
    }

#ifndef CFG_NO_FLASH
    /* configure available FLASH banks */
    size = flash_init ();
    display_flash_config (size);
#endif /* CFG_NO_FLASH */

#ifdef CONFIG_VFD
#    ifndef PAGE_SIZE
#      define PAGE_SIZE 4096
#    endif
    /*
     * reserve memory for VFD display (always full pages)
     */
    /* bss_end is defined in the board-specific linker script */
    addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
    size = vfd_setmem (addr);
    gd->fb_base = addr;
#endif /* CONFIG_VFD */

#ifdef CONFIG_LCD
    /* board init may have inited fb_base */
    if (!gd->fb_base) {
#        ifndef PAGE_SIZE
#          define PAGE_SIZE 4096
#        endif
        /*
         * reserve memory for LCD display (always full pages)
         */
        /* bss_end is defined in the board-specific linker script */
        addr = (_bss_end + (PAGE_SIZE - 1)) & ~(PAGE_SIZE - 1);
        size = lcd_setmem (addr);
        gd->fb_base = addr;
    }
#endif /* CONFIG_LCD */

    /* armboot_start is defined in the board-specific linker script */
#ifdef CONFIG_MEMORY_UPPER_CODE /* by scsuh */
    mem_malloc_init (CFG_UBOOT_BASE + CFG_UBOOT_SIZE - CFG_MALLOC_LEN - CFG_STACK_SIZE);
#else
    mem_malloc_init (_armboot_start - CFG_MALLOC_LEN);
#endif

//******************************//
// Board Specific
// #if defined(CONFIG_SMDKXXXX)
//******************************//

#if defined(CONFIG_SMDK6410)
    #if defined(CONFIG_GENERIC_MMC)
    puts ("SD/MMC:  ");
    mmc_exist = mmc_initialize(gd->bd);
    if (mmc_exist != 0)
    {
        puts ("0 MB\n");
    }
    #else
    #if defined(CONFIG_MMC)
    puts("SD/MMC:  ");

    if (INF_REG3_REG == 0)
        movi_ch = 0;
    else
        movi_ch = 1;

    movi_set_capacity();
    movi_init();
    movi_set_ofs(MOVI_TOTAL_BLKCNT);
    #endif
    #endif

    if (INF_REG3_REG == BOOT_ONENAND) {
    #if defined(CONFIG_CMD_ONENAND)
        puts("OneNAND: ");
        onenand_init();
    #endif
        /*setenv("bootcmd", "onenand read c0008000 80000 380000;bootm c0008000");*/
    } else {
        puts("NAND:    ");
        nand_init();

        if (INF_REG3_REG == 0 || INF_REG3_REG == 7)
            setenv("bootcmd", "movi read kernel c0008000;movi read rootfs c0800000;bootm c0008000");
        else
            setenv("bootcmd", "nand read c0008000 80000 380000;bootm c0008000");
    }
#endif    /* CONFIG_SMDK6410 */

#if defined(CONFIG_SMDKC100)

    #if defined(CONFIG_GENERIC_MMC)
        puts ("SD/MMC:  ");
        mmc_exist = mmc_initialize(gd->bd);
        if (mmc_exist != 0)
        {
            puts ("0 MB\n");
        }
    #endif

    #if defined(CONFIG_CMD_ONENAND)
        puts("OneNAND: ");
        onenand_init();
    #endif

    #if defined(CONFIG_CMD_NAND)
        puts("NAND:    ");
        nand_init();
    #endif

#endif /* CONFIG_SMDKC100 */

#if defined(CONFIG_X210)

    #if defined(CONFIG_GENERIC_MMC)
        puts ("SD/MMC:  ");
        mmc_exist = mmc_initialize(gd->bd);
        if (mmc_exist != 0)
        {
            puts ("0 MB\n");
#ifdef CONFIG_CHECK_X210CV3
            check_flash_flag=0;//check inand error!
#endif
        }
#ifdef CONFIG_CHECK_X210CV3
        else
        {
            check_flash_flag=1;//check inand ok! 
        }
#endif
    #endif

    #if defined(CONFIG_MTD_ONENAND)
        puts("OneNAND: ");
        onenand_init();
        /*setenv("bootcmd", "onenand read c0008000 80000 380000;bootm c0008000");*/
    #else
        //puts("OneNAND: (FSR layer enabled)\n");
    #endif

    #if defined(CONFIG_CMD_NAND)
        puts("NAND:    ");
        nand_init();
    #endif

#endif /* CONFIG_X210 */

#if defined(CONFIG_SMDK6440)
    #if defined(CONFIG_GENERIC_MMC)
    puts ("SD/MMC:  ");
    mmc_exist = mmc_initialize(gd->bd);
    if (mmc_exist != 0)
    {
        puts ("0 MB\n");
    }
    #else
    #if defined(CONFIG_MMC)
    if (INF_REG3_REG == 1) {    /* eMMC_4.3 */
        puts("eMMC:    ");
        movi_ch = 1;
        movi_emmc = 1;

        movi_init();
        movi_set_ofs(0);
    } else if (INF_REG3_REG == 7 || INF_REG3_REG == 0) {    /* SD/MMC */
        if (INF_REG3_REG & 0x1)
            movi_ch = 1;
        else
            movi_ch = 0;

        puts("SD/MMC:  ");

        movi_set_capacity();
        movi_init();
        movi_set_ofs(MOVI_TOTAL_BLKCNT);

    } else {

    }
    #endif
    #endif

    if (INF_REG3_REG == 2) {
            /* N/A */
    } else {
        puts("NAND:    ");
        nand_init();
        //setenv("bootcmd", "nand read c0008000 80000 380000;bootm c0008000");
    }
#endif /* CONFIG_SMDK6440 */

#if defined(CONFIG_SMDK6430)
    #if defined(CONFIG_GENERIC_MMC)
    puts ("SD/MMC:  ");
    mmc_exist = mmc_initialize(gd->bd);
    if (mmc_exist != 0)
    {
        puts ("0 MB\n");
    }
    #else
    #if defined(CONFIG_MMC)
    puts("SD/MMC:  ");

    if (INF_REG3_REG == 0)
        movi_ch = 0;
    else
        movi_ch = 1;

    movi_set_capacity();
    movi_init();
    movi_set_ofs(MOVI_TOTAL_BLKCNT);
    #endif
    #endif

    if (INF_REG3_REG == BOOT_ONENAND) {
    #if defined(CONFIG_CMD_ONENAND)
        puts("OneNAND: ");
        onenand_init();
    #endif
        /*setenv("bootcmd", "onenand read c0008000 80000 380000;bootm c0008000");*/
    } else if (INF_REG3_REG == BOOT_NAND) {
        puts("NAND:    ");
        nand_init();
    } else {
    }

    if (INF_REG3_REG == 0 || INF_REG3_REG == 7)
        setenv("bootcmd", "movi read kernel c0008000;movi read rootfs c0800000;bootm c0008000");
    else
        setenv("bootcmd", "nand read c0008000 80000 380000;bootm c0008000");
#endif    /* CONFIG_SMDK6430 */

#if defined(CONFIG_SMDK6442)
    #if defined(CONFIG_GENERIC_MMC)
    puts ("SD/MMC:  ");
    mmc_exist = mmc_initialize(gd->bd);
    if (mmc_exist != 0)
    {
        puts ("0 MB\n");
    }
    #else
    #if defined(CONFIG_MMC)
    puts("SD/MMC:  ");

    movi_set_capacity();
    movi_init();
    movi_set_ofs(MOVI_TOTAL_BLKCNT);

    #endif
    #endif

    #if defined(CONFIG_CMD_ONENAND)
    if (INF_REG3_REG == BOOT_ONENAND) {
        puts("OneNAND: ");
        onenand_init();
        }
    #endif

#endif    /* CONFIG_SMDK6442 */

#if defined(CONFIG_SMDK2416) || defined(CONFIG_SMDK2450)
    #if defined(CONFIG_NAND)
    puts("NAND:    ");
    nand_init();
    #endif

    #if defined(CONFIG_ONENAND)
    puts("OneNAND: ");
    onenand_init();
    #endif

    #if defined(CONFIG_BOOT_MOVINAND)
    puts("SD/MMC:  ");

    if ((0x24564236 == magic[0]) && (0x20764316 == magic[1])) {
        printf("Boot up for burning\n");
    } else {
            movi_init();
            movi_set_ofs(MOVI_TOTAL_BLKCNT);
    }
    #endif
#endif    /* CONFIG_SMDK2416 CONFIG_SMDK2450 */

#ifdef CONFIG_HAS_DATAFLASH
    AT91F_DataflashInit();
    dataflash_print_info();
#endif

    /* initialize environment */
    env_relocate ();

#ifdef CONFIG_VFD
    /* must do this after the framebuffer is allocated */
    drv_vfd_init();
#endif /* CONFIG_VFD */

#ifdef CONFIG_SERIAL_MULTI
    serial_initialize();
#endif

    /* IP Address */
    gd->bd->bi_ip_addr = getenv_IPaddr ("ipaddr");

    /* MAC Address */
    {
        int i;
        ulong reg;
        char *s, *e;
        char tmp[64];

        i = getenv_r ("ethaddr", tmp, sizeof (tmp));
        s = (i > 0) ? tmp : NULL;

        for (reg = 0; reg < 6; ++reg) {
            gd->bd->bi_enetaddr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
            if (s)
                s = (*e) ? e + 1 : e;
        }

#ifdef CONFIG_HAS_ETH1
        i = getenv_r ("eth1addr", tmp, sizeof (tmp));
        s = (i > 0) ? tmp : NULL;

        for (reg = 0; reg < 6; ++reg) {
            gd->bd->bi_enet1addr[reg] = s ? simple_strtoul (s, &e, 16) : 0;
            if (s)
                s = (*e) ? e + 1 : e;
        }
#endif
    }

    devices_init ();    /* get the devices list going. */

#ifdef CONFIG_CMC_PU2
    load_sernum_ethaddr ();
#endif /* CONFIG_CMC_PU2 */

    jumptable_init ();
#if !defined(CONFIG_SMDK6442)
    console_init_r ();    /* fully init console as a device */
#endif

#if defined(CONFIG_MISC_INIT_R)
    /* miscellaneous platform dependent initialisations */
    misc_init_r ();
#endif

    /* enable exceptions */
    enable_interrupts ();

    /* Perform network card initialisation if necessary */
#ifdef CONFIG_DRIVER_TI_EMAC
extern void dm644x_eth_set_mac_addr (const u_int8_t *addr);
    if (getenv ("ethaddr")) {
        dm644x_eth_set_mac_addr(gd->bd->bi_enetaddr);
    }
#endif

#ifdef CONFIG_DRIVER_CS8900
    cs8900_get_enetaddr (gd->bd->bi_enetaddr);
#endif

#if defined(CONFIG_DRIVER_SMC91111) || defined (CONFIG_DRIVER_LAN91C96)
    if (getenv ("ethaddr")) {
        smc_set_mac_addr(gd->bd->bi_enetaddr);
    }
#endif /* CONFIG_DRIVER_SMC91111 || CONFIG_DRIVER_LAN91C96 */

    /* Initialize from environment */
    if ((s = getenv ("loadaddr")) != NULL) {
        load_addr = simple_strtoul (s, NULL, 16);
    }
#if defined(CONFIG_CMD_NET)
    if ((s = getenv ("bootfile")) != NULL) {
        copy_filename (BootFile, s, sizeof (BootFile));
    }
#endif

#ifdef BOARD_LATE_INIT
    board_late_init ();
#endif
#if defined(CONFIG_CMD_NET)
#if defined(CONFIG_NET_MULTI)
    puts ("Net:   ");
#endif
    eth_initialize(gd->bd);
#if defined(CONFIG_RESET_PHY_R)
    debug ("Reset Ethernet PHY\n");
    reset_phy();
#endif
#endif

#if defined(CONFIG_CMD_IDE)
    puts("IDE:   ");
    ide_init();
#endif

/****************lxg added**************/
#ifdef CONFIG_MPAD
    extern int x210_preboot_init(void);
    x210_preboot_init();
#endif
/****************end**********************/

    /* check menukey to update from sd */
    extern void update_all(void);
    if(check_menu_update_from_sd()==0)//update mode
    {
        puts ("[LEFT DOWN] update mode\n");
        run_command("fdisk -c 0",0);
        update_all();
    }
    else
        puts ("[LEFT UP] boot mode\n");

    /* main_loop() can return to retry autoboot, if so just run it again. */
    for (;;) {
        main_loop ();
    }

    /* NOTREACHED - no way out of command loop except booting */
}

 

start_armboot分析(uboot\uboot_jiuding\uboot\lib_arm 444行):

① init_fnc_t **init_fnc_ptr;

解析:

typedef int (init_fnc_t) (void);

这是一个函数类型,init_fnc_ptr就是一个二重函数指针,这里是用来指向一个函数指针数组。

这个文件开头有一个宏: DECLARE_GLOBAL_DATA_PTR;

跳到定义处:

#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")

定义了一个全局变量gd,这个变量是一个指针类型,占四个字节,用volatile和register修饰,后面asm ("r8"),是gcc支持的;把gd放到r8中;

将这些全局变量定义成结构体gd,然后放到寄存器中,定义为register变量完全是为了访问效率的提高。

gd_t定义在include/asm-arm

typedef    struct    global_data {
    bd_t        *bd;
    unsigned long    flags;
    unsigned long    baudrate;
    unsigned long    have_console;    /* serial_init() was called */
    unsigned long    reloc_off;    /* Relocation Offset */
    unsigned long    env_addr;    /* Address  of Environment struct */
    unsigned long    env_valid;    /* Checksum of Environment valid? */
    unsigned long    fb_base;    /* base address of frame buffer */
#ifdef CONFIG_VFD
    unsigned char    vfd_type;    /* display type */
#endif

    void        **jt;        /* jump table */
} gd_t;

/*
 * Global Data Flags
 */
#define    GD_FLG_RELOC    0x00001        /* Code was relocated to RAM        */
#define    GD_FLG_DEVINIT    0x00002        /* Devices have been initialized    */
#define    GD_FLG_SILENT    0x00004        /* Silent mode                */
#define    GD_FLG_POSTFAIL    0x00008        /* Critical POST test failed        */
#define    GD_FLG_POSTSTOP    0x00010        /* POST seqeunce aborted        */
#define    GD_FLG_LOGINIT    0x00020        /* Log Buffer has been initialized    */

#define DECLARE_GLOBAL_DATA_PTR     register volatile gd_t *gd asm ("r8")

 

#ifndef _U_BOOT_H_
#define _U_BOOT_H_    1

typedef struct bd_info {
    int            bi_baudrate;    /* serial console baudrate */
    unsigned long    bi_ip_addr;    /* IP Address */
    unsigned char    bi_enetaddr[6]; /* Ethernet adress */
    struct environment_s           *bi_env;
    ulong            bi_arch_number;    /* unique id for this board */
    ulong            bi_boot_params;    /* where this board expects params */
    struct                /* RAM configuration */
    {
    ulong start;
    ulong size;
    }            bi_dram[CONFIG_NR_DRAM_BANKS];
#ifdef CONFIG_HAS_ETH1
    /* second onboard ethernet port */
    unsigned char   bi_enet1addr[6];
#endif
} bd_t;

#define bi_env_data bi_env->data
#define bi_env_crc  bi_env->crc

#endif    /* _U_BOOT_H_ */

 

uboot启动第二阶段--start_armboot函数

标签:

原文地址:http://www.cnblogs.com/yr-linux/p/5477103.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!