U-Boot启动引导内核分析(三)

标签:ARM   bootloader   U-Boot   代码分析 抵岸科技

do_bootm_linux()函数位于lib_arm/Bootm.c文件中,主要流程分析如下:

void do_bootm_linux ( cmd_tbl_t * cmdtp , int flag , int argc , char * argv [],
             bootm_headers_t * images)
{
    ulong    initrd_start , initrd_end;
    ulong    ep = 0;
    bd_t    * bd = gd -> bd;
    char    *s;
    int    machid = bd -> bi_arch_number;
    void    ( * theKernel)( int zero , int arch , uint params);
    int    ret;

#ifdef CONFIG_CMDLINE_TAG
    char * commandline = getenv ( "bootargs");
#endif

    /* find kernel entry point */
    if ( images -> legacy_hdr_valid) {
        ep = image_get_ep ( & images -> legacy_hdr_os_copy);
#if defined(CONFIG_FIT)
    } else if ( images -> fit_uname_os) {
        ret = fit_image_get_entry ( images -> fit_hdr_os ,
                    images -> fit_noffset_os , & ep);
        if ( ret) {
            puts ( "Can't get entry point property! /n ");
            goto error;
        }
#endif
    } else {
        puts ( "Could not find kernel entry point! /n ");
        goto error;
    }
    theKernel = ( void ( *)( int , int , uint)) ep;

    s = getenv ( "machid");
    if (s) {
        machid = simple_strtoul (s , NULL , 16);
        printf ( "Using machid 0x%x from environment /n " , machid);
    }

    ret = boot_get_ramdisk ( argc , argv , images , IH_ARCH_ARM ,
            & initrd_start , & initrd_end);
    if ( ret)
        goto error;

    show_boot_progress ( 15);

    debug ( "## Transferring control to Linux (at address %08lx) ... /n " ,
           ( ulong) theKernel);

#if defined (CONFIG_SETUP_MEMORY_TAGS) || /
    defined (CONFIG_CMDLINE_TAG) || /
    defined (CONFIG_INITRD_TAG) || /
    defined (CONFIG_SERIAL_TAG) || /
    defined (CONFIG_REVISION_TAG) || /
    defined (CONFIG_LCD) || /
defined (CONFIG_VFD)
    /* 初始化TAG结构体开始 */
    setup_start_tag ( bd);
#ifdef CONFIG_SERIAL_TAG
    setup_serial_tag ( & params);
#endif
#ifdef CONFIG_REVISION_TAG
    setup_revision_tag ( & params);
#endif
#ifdef CONFIG_SETUP_MEMORY_TAGS
    /* 设置RAM参数 */
    setup_memory_tags ( bd);
#endif
#ifdef CONFIG_CMDLINE_TAG
    setup_commandline_tag ( bd , commandline);
#endif
#ifdef CONFIG_INITRD_TAG
    if ( initrd_start && initrd_end)
        setup_initrd_tag ( bd , initrd_start , initrd_end);
#endif
#if defined (CONFIG_VFD) || defined (CONFIG_LCD)
    setup_videolfb_tag (( gd_t *) gd);
#endif
    /* 初始化TAG结构体结束 */
    setup_end_tag ( bd);
#endif

    /* we assume that the kernel is in place */
    printf ( " /n Starting kernel ... /n/n ");

#ifdef CONFIG_USB_DEVICE
    {
        extern void udc_disconnect ( void);
        udc_disconnect ();
    }
#endif

    cleanup_before_linux ();

    /* 将控制权交给内核,让内核自解压启动 */
    /* 传给KERNEL的参数:(struct tag *)bd->bi_boot_params */
    /* 在board/atmel/at91sam9g20ek/At91sam9g20ek.c文件中有如下定义:
    gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;(PHYS_SDRAM = 0x20000000)
    */
    theKernel ( 0 , machid , bd -> bi_boot_params);
    /* does not return */
    return;

error:
    do_reset ( cmdtp , flag , argc , argv);
    return;
}

 

文件历史记录

版本            编制                    日期                        更改内容

-----------------------------------------------------------------------------------

V1.0           抵岸科技              2010-7-20              首发

你可能感兴趣的:(U-Boot启动引导内核分析(三))