uboot 主流程分析

1.uboot入口函数main_loop所在位置: uboot_tiny4412/common/main.c

2.分析入口函数的流程

void main_loop (void)
{
//////////////////////////////////////
    unsigned int OmPin;
    OmPin = INF_REG3_REG;
//////////////////////////////////////
#ifndef CONFIG_SYS_HUSH_PARSER
    static char lastcommand[CONFIG_SYS_CBSIZE] = { 0, };
    int len;
    int rc = 1;
    int flag;
#endif

#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)
    char *s;
    int bootdelay;
#endif
#ifdef CONFIG_PREBOOT
    char *p;
#endif
#ifdef CONFIG_BOOTCOUNT_LIMIT
    unsigned long bootcount = 0;
    unsigned long bootlimit = 0;
    char *bcs;
    char bcs_set[16];
#endif /* CONFIG_BOOTCOUNT_LIMIT */

#if defined(CONFIG_VFD) && defined(VFD_TEST_LOGO)
    ulong bmp = 0;      /* default bitmap */
    extern int trab_vfd (ulong bitmap);

#ifdef CONFIG_MODEM_SUPPORT
    if (do_mdm_init)
        bmp = 1;    /* alternate bitmap */
#endif
    trab_vfd (bmp);
#endif  /* CONFIG_VFD && VFD_TEST_LOGO */

#ifdef CONFIG_BOOTCOUNT_LIMIT
    bootcount = bootcount_load();
    bootcount++;
    bootcount_store (bootcount);
    sprintf (bcs_set, "%lu", bootcount);
    setenv ("bootcount", bcs_set);
    bcs = getenv ("bootlimit");
    bootlimit = bcs ? simple_strtoul (bcs, NULL, 10) : 0;
#endif /* CONFIG_BOOTCOUNT_LIMIT */

#ifdef CONFIG_MODEM_SUPPORT
    debug ("DEBUG: main_loop:   do_mdm_init=%d\n", do_mdm_init);
    if (do_mdm_init) {
        char *str = strdup(getenv("mdm_cmd"));
        setenv ("preboot", str);  /* set or delete definition */
        if (str != NULL)
            free (str);
        mdm_init(); /* wait for modem connection */
    }
#endif  /* CONFIG_MODEM_SUPPORT */

#ifdef CONFIG_VERSION_VARIABLE
    {
        extern char version_string[];

        setenv ("ver", version_string);  /* set version variable */
    }
#endif /* CONFIG_VERSION_VARIABLE */

#ifdef CONFIG_SYS_HUSH_PARSER
    u_boot_hush_start ();
#endif

#if defined(CONFIG_HUSH_INIT_VAR)
    hush_init_var ();
#endif

#ifdef CONFIG_AUTO_COMPLETE
    install_auto_complete();/*加载自动补全功能*/
#endif

#ifdef CONFIG_PREBOOT/*配置预启动*/
    if ((p = getenv ("preboot")) != NULL) {
# ifdef CONFIG_AUTOBOOT_KEYED
        int prev = disable_ctrlc(1);    /* disable Control C checking */
# endif

# ifndef CONFIG_SYS_HUSH_PARSER
        run_command (p, 0);
# else
        parse_string_outer(p, FLAG_PARSE_SEMICOLON |
                    FLAG_EXIT_FROM_LOOP);
# endif

# ifdef CONFIG_AUTOBOOT_KEYED
        disable_ctrlc(prev);    /* restore Control C checking */
# endif
    }
#endif /* CONFIG_PREBOOT */

#if defined(CONFIG_UPDATE_TFTP)/*从tftp更新程序*/
    update_tftp ();
#endif /* CONFIG_UPDATE_TFTP */


#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)/*延时启动*/
    s = getenv ("bootdelay");
    bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY;

    debug ("### main_loop entered: bootdelay=%d\n\n", bootdelay);

# ifdef CONFIG_BOOT_RETRY_TIME
    init_cmd_timeout ();
# endif /* CONFIG_BOOT_RETRY_TIME */

#ifdef CONFIG_POST
    if (gd->flags & GD_FLG_POSTFAIL) {
        s = getenv("failbootcmd");
    }
    else
#endif /* CONFIG_POST */
#ifdef CONFIG_BOOTCOUNT_LIMIT
    if (bootlimit && (bootcount > bootlimit)) {
        printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",
                (unsigned)bootlimit);
        s = getenv ("altbootcmd");
    }
    else
#endif /* CONFIG_BOOTCOUNT_LIMIT */
////////////////////////////////////////////////////////////////////////////
        if(OmPin==BOOT_EMMC_4_4)/*执行EMMC启动则按不同系统选择启动的文件系统*/
        {
            char *p = (char*)0x43000000;
            char *cmd_buf;
            int flags;
            cmd_buf = strdup("fatload mmc 1:1 0x43000000 tiny4412.ini;");
            if((flags = run_command(cmd_buf,0))==0)
            {
                //      printf("debug-1");
                if(strstr(p,"version=4.2.2")){
                    s = strdup("movi read kernel 0 40008000;movi read rootfs4_2 0 41000000 100000;bootm 40008000 41000000");
                }else if(strstr(p,"version=4.0.4")){
                    s = strdup("movi read kernel 0 40008000;movi read rootfs4_0 0 41000000 100000;bootm 40008000 41000000");
                }else{
                    s = strdup("movi read kernel 0 40008000;movi read rootfs4_2 0 41000000 100000;bootm 40008000 41000000");
                }
#ifdef DEBUG
                printf(s);
#endif
            }// ConfigBootCmd();
        }else{
            s = getenv ("bootcmd");
        }
//      printf("\n bootcmd:%s\n",s);
////////////////////////////////////////////////////////////////////////////        
    debug ("### main_loop: bootcmd=\"%s\"\n", s ? s : "<UNDEFINED>");

    if (bootdelay >= 0 && s && !abortboot (bootdelay)) {
# ifdef CONFIG_AUTOBOOT_KEYED
        int prev = disable_ctrlc(1);    /* disable Control C checking */
# endif

# ifndef CONFIG_SYS_HUSH_PARSER    /*解析串口命令*/
        run_command (s, 0);
# else
        parse_string_outer(s, FLAG_PARSE_SEMICOLON |
                    FLAG_EXIT_FROM_LOOP);
# endif

# ifdef CONFIG_AUTOBOOT_KEYED
        disable_ctrlc(prev);    /* restore Control C checking */
# endif
    }

# ifdef CONFIG_MENUKEY       /*配置启动菜单*/
    if (menukey == CONFIG_MENUKEY) {
        s = getenv("menucmd");
        if (s) {
# ifndef CONFIG_SYS_HUSH_PARSER
        run_command (s, 0);
# else
        parse_string_outer(s, FLAG_PARSE_SEMICOLON |
                    FLAG_EXIT_FROM_LOOP);
# endif
        }
    }
#endif /* CONFIG_MENUKEY */
#endif /* CONFIG_BOOTDELAY */

    /*
     * Main Loop for Monitor Command Processing
     */

//////////////////////////////////////////////
if(OmPin == BOOT_MMCSD) /*SD卡启动则显示菜单*/
{
    run_command("menu",0);
}
///////////////////////////////////////////////
#ifdef CONFIG_SYS_HUSH_PARSER
    parse_file_outer();
    /* This point is never reached */
    for (;;);
#else
    for (;;) {
#ifdef CONFIG_BOOT_RETRY_TIME   /*启动失败则尝试重复启动*/
        if (rc >= 0) {
            /* Saw enough of a valid command to
             * restart the timeout.
             */
            reset_cmd_timeout();
        }
#endif
        len = readline (CONFIG_SYS_PROMPT);

        flag = 0;   /* assume no special flags for now */
        if (len > 0)
            strcpy (lastcommand, console_buffer);
        else if (len == 0)
            flag |= CMD_FLAG_REPEAT;
#ifdef CONFIG_BOOT_RETRY_TIME
        else if (len == -2) {
            /* -2 means timed out, retry autoboot
             */
            puts ("\nTimed out waiting for command\n");
# ifdef CONFIG_RESET_TO_RETRY
            /* Reinit board to run initialization code again */
            do_reset (NULL, 0, 0, NULL);
# else
            return;     /* retry autoboot */
# endif
        }
#endif
                /*命令的处理*/
        if (len == -1)
            puts ("<INTERRUPT>\n");
        else
            rc = run_command (lastcommand, flag);

        if (rc <= 0) {
            /* invalid command or not repeatable, forget it */
            lastcommand[0] = 0;
        }
    }
#endif /*CONFIG_SYS_HUSH_PARSER*/
}

3.按键检测

源文件目录:iTop4412_uboot_scp/common/cmd_mdmupgrade.c

int do_mdmup (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
    int ret = 0;
    int val;
/*
#define HSIC_HOST_ACTIVE    EXYNOS4_GPC0(3)
#define HSIC_SLAVE_WAKEUP   EXYNOS4_GPC0(4)
#define HSIC_HOST_WAKEUP    EXYNOS4_GPX2(5)
#define HSIC_HOST_SUSREQ    EXYNOS4_GPX1(6)
all set to input
*/
    val = readl(GPC0CON);
    val &= ~(0x0f<<12 | 0x0f<<16);
    writel(val, GPC0CON);

    val = readl(GPX2CON);
    val &= ~(0x0f<<20);
    writel(val, GPX2CON);

    val = readl(GPX1CON);
    val &= ~(0x0f<<24);
    writel(val, GPX1CON);
/*
#define GPIO_MD_PWON    EXYNOS4_GPC0(0)
#define GPIO_MD_RSTN    EXYNOS4_GPC0(2)
#define GPIO_MD_RESETBB EXYNOS4_GPL2(1)
 */
    val = readl(GPC0CON);
    val &= ~(0x0f<<0 | 0x0f<<8);
    val |= (0x01<<0 | 0x01<<8);
    writel(val, GPC0CON);

    val = readl(GPL2CON);
    val &= ~(0x0f<<4);
    val |= (0x01<<4);
    writel(val, GPL2CON);

    val = readl(GPC0DAT);
    val |= (0x01<<0 | 0x01<<2); 
    writel(val,GPC0DAT);

    val = readl(GPL2DAT);
    val |= (0x01<<1); 
    writel(val,GPL2DAT);
    udelay(50000);

    val = readl(GPC0DAT);
    val &= ~(0x01<<2); 
    writel(val,GPC0DAT);
    udelay(500000);

    val = readl(GPC0DAT);
    val |= (0x1<<2); 
    writel(val,GPC0DAT);

    printf("Now you can update Modem\n");
    return ret;
}

4.开机启动项

源文件目录: iTop4412_uboot_public/iTop4412_uboot_scp/cpu/arm_cortexa9/s5pc210/recovery.c

int recovery_preboot(void)
{
    unsigned int reset_mode;
    reset_mode = INF_REG5_REG;

    if(reset_mode ==FACTORY_RESET_MODE)
    {
            printf("SYSTEM ENTER FACTORY RESET MODE[0x%x]\n",reset_mode);   
            INF_REG5_REG = reset_mode&(~0xff);
            if(factory_reset(1))
            {
                printf("[ERROR]: Factory Reset Fail..");
                return -1;
            }
            return 0;
    }   
    else
    {
        /* add by cym 20141211 GPX1_1 */
        int value = 0;

        char run_cmd[50];

        value = __REG(GPX1DAT);

        if(0x2 == (value & 0x2))//not press
        {
            printf("SYSTEM ENTER NORMAL BOOT MODE\n");
        }
        else    //press
        {
            printf("SYSTEM ENTER Updating MODE\n");

            sprintf(run_cmd, "sdfuse flashall");
            run_command(run_cmd, 0);
        }
        /* end add */

        return 0;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值