您的位置:首页 > 其它

uboot 主流程分析

2017-03-06 18:18 169 查看

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;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  u-boot