⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 UBOOT 源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * (C) Copyright 2000 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * Add to readline cmdline-editing by * (C) Copyright 2005 * JinHua Luo, GuangDong Linux Center, <luo.jinhua@gd-linux.com> * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA *//* #define	DEBUG	*/#include <common.h>#include <watchdog.h>#include <command.h>#ifdef CONFIG_MODEM_SUPPORT#include <malloc.h>		/* for free() prototype */#endif#ifdef CFG_HUSH_PARSER#include <hush.h>#endif#include <post.h>#ifdef CONFIG_SILENT_CONSOLEDECLARE_GLOBAL_DATA_PTR;#endif#if defined(CONFIG_BOOT_RETRY_TIME) && defined(CONFIG_RESET_TO_RETRY)extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);		/* for do_reset() prototype */#endifextern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);#define MAX_DELAY_STOP_STR 32static int parse_line (char *, char *[]);#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)static int abortboot(int);#endif#undef DEBUG_PARSERchar        console_buffer[CFG_CBSIZE];		/* console I/O buffer	*/#ifndef CONFIG_CMDLINE_EDITINGstatic char * delete_char (char *buffer, char *p, int *colp, int *np, int plen);static char erase_seq[] = "\b \b";		/* erase sequence	*/static char   tab_seq[] = "        ";		/* used to expand TABs	*/#endif /* CONFIG_CMDLINE_EDITING */#ifdef CONFIG_BOOT_RETRY_TIMEstatic uint64_t endtime = 0;  /* must be set, default is instant timeout */static int      retry_time = -1; /* -1 so can call readline before main_loop */#endif#define	endtick(seconds) (get_ticks() + (uint64_t)(seconds) * get_tbclk())#ifndef CONFIG_BOOT_RETRY_MIN#define CONFIG_BOOT_RETRY_MIN CONFIG_BOOT_RETRY_TIME#endif#ifdef CONFIG_MODEM_SUPPORTint do_mdm_init = 0;extern void mdm_init(void); /* defined in board.c */#endif/*************************************************************************** * Watch for 'delay' seconds for autoboot stop or autoboot delay string. * returns: 0 -  no key string, allow autoboot *          1 - got key string, abort */#if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0)# if defined(CONFIG_AUTOBOOT_KEYED)static __inline__ int abortboot(int bootdelay){	int abort = 0;	uint64_t etime = endtick(bootdelay);	struct {		char* str;		u_int len;		int retry;	}	delaykey [] = {		{ str: getenv ("bootdelaykey"),  retry: 1 },		{ str: getenv ("bootdelaykey2"), retry: 1 },		{ str: getenv ("bootstopkey"),   retry: 0 },		{ str: getenv ("bootstopkey2"),  retry: 0 },	};	char presskey [MAX_DELAY_STOP_STR];	u_int presskey_len = 0;	u_int presskey_max = 0;	u_int i;#ifdef CONFIG_SILENT_CONSOLE	if (gd->flags & GD_FLG_SILENT) {		/* Restore serial console */		console_assign (stdout, "serial");		console_assign (stderr, "serial");	}#endif#  ifdef CONFIG_AUTOBOOT_PROMPT	printf (CONFIG_AUTOBOOT_PROMPT, bootdelay);#  endif#  ifdef CONFIG_AUTOBOOT_DELAY_STR	if (delaykey[0].str == NULL)		delaykey[0].str = CONFIG_AUTOBOOT_DELAY_STR;#  endif#  ifdef CONFIG_AUTOBOOT_DELAY_STR2	if (delaykey[1].str == NULL)		delaykey[1].str = CONFIG_AUTOBOOT_DELAY_STR2;#  endif#  ifdef CONFIG_AUTOBOOT_STOP_STR	if (delaykey[2].str == NULL)		delaykey[2].str = CONFIG_AUTOBOOT_STOP_STR;#  endif#  ifdef CONFIG_AUTOBOOT_STOP_STR2	if (delaykey[3].str == NULL)		delaykey[3].str = CONFIG_AUTOBOOT_STOP_STR2;#  endif	for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) {		delaykey[i].len = delaykey[i].str == NULL ?				    0 : strlen (delaykey[i].str);		delaykey[i].len = delaykey[i].len > MAX_DELAY_STOP_STR ?				    MAX_DELAY_STOP_STR : delaykey[i].len;		presskey_max = presskey_max > delaykey[i].len ?				    presskey_max : delaykey[i].len;#  if DEBUG_BOOTKEYS		printf("%s key:<%s>\n",		       delaykey[i].retry ? "delay" : "stop",		       delaykey[i].str ? delaykey[i].str : "NULL");#  endif	}	/* In order to keep up with incoming data, check timeout only	 * when catch up.	 */	while (!abort && get_ticks() <= etime) {		for (i = 0; i < sizeof(delaykey) / sizeof(delaykey[0]); i ++) {			if (delaykey[i].len > 0 &&			    presskey_len >= delaykey[i].len &&			    memcmp (presskey + presskey_len - delaykey[i].len,				    delaykey[i].str,				    delaykey[i].len) == 0) {#  if DEBUG_BOOTKEYS				printf("got %skey\n",				       delaykey[i].retry ? "delay" : "stop");#  endif#  ifdef CONFIG_BOOT_RETRY_TIME				/* don't retry auto boot */				if (! delaykey[i].retry)					retry_time = -1;#  endif				abort = 1;			}		}		if (tstc()) {			if (presskey_len < presskey_max) {				presskey [presskey_len ++] = getc();			}			else {				for (i = 0; i < presskey_max - 1; i ++)					presskey [i] = presskey [i + 1];				presskey [i] = getc();			}		}	}#  if DEBUG_BOOTKEYS	if (!abort)		puts ("key timeout\n");#  endif#ifdef CONFIG_SILENT_CONSOLE	if (abort) {		/* permanently enable normal console output */		gd->flags &= ~(GD_FLG_SILENT);	} else if (gd->flags & GD_FLG_SILENT) {		/* Restore silent console */		console_assign (stdout, "nulldev");		console_assign (stderr, "nulldev");	}#endif	return abort;}# else	/* !defined(CONFIG_AUTOBOOT_KEYED) */#ifdef CONFIG_MENUKEYstatic int menukey = 0;#endifstatic __inline__ int abortboot(int bootdelay){	int abort = 0;#ifdef CONFIG_SILENT_CONSOLE	if (gd->flags & GD_FLG_SILENT) {		/* Restore serial console */		console_assign (stdout, "serial");		console_assign (stderr, "serial");	}#endif#ifdef CONFIG_MENUPROMPT	printf(CONFIG_MENUPROMPT, bootdelay);#else	printf("Hit any key to stop autoboot: %2d ", bootdelay);#endif#if defined CONFIG_ZERO_BOOTDELAY_CHECK	/*	 * Check if key already pressed	 * Don't check if bootdelay < 0	 */	if (bootdelay >= 0) {		if (tstc()) {	/* we got a key press	*/			(void) getc();  /* consume input	*/			puts ("\b\b\b 0");			abort = 1; 	/* don't auto boot	*/		}	}#endif	while ((bootdelay > 0) && (!abort)) {		int i;		--bootdelay;		/* delay 100 * 10ms */		for (i=0; !abort && i<100; ++i) {			if (tstc()) {	/* we got a key press	*/				abort  = 1;	/* don't auto boot	*/				bootdelay = 0;	/* no more delay	*/# ifdef CONFIG_MENUKEY				menukey = getc();# else				(void) getc();  /* consume input	*/# endif				break;			}			udelay (10000);		}		printf ("\b\b\b%2d ", bootdelay);	}	putc ('\n');#ifdef CONFIG_SILENT_CONSOLE	if (abort) {		/* permanently enable normal console output */		gd->flags &= ~(GD_FLG_SILENT);	} else if (gd->flags & GD_FLG_SILENT) {		/* Restore silent console */		console_assign (stdout, "nulldev");		console_assign (stderr, "nulldev");	}#endif	return abort;}# endif	/* CONFIG_AUTOBOOT_KEYED */#endif	/* CONFIG_BOOTDELAY >= 0  *//****************************************************************************/void main_loop (void){#ifndef CFG_HUSH_PARSER	static char lastcommand[CFG_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 CFG_HUSH_PARSER	u_boot_hush_start ();#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 CFG_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_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_BOOTCOUNT_LIMIT	if (bootlimit && (bootcount > bootlimit)) {		printf ("Warning: Bootlimit (%u) exceeded. Using altbootcmd.\n",		        (unsigned)bootlimit);		s = getenv ("altbootcmd");	}	else#endif /* CONFIG_BOOTCOUNT_LIMIT */		s = getenv ("bootcmd");	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 CFG_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 CFG_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 */#ifdef CONFIG_AMIGAONEG3SE	{	    extern void video_banner(void);	    video_banner();	}#endif	/*	 * Main Loop for Monitor Command Processing	 */#ifdef CFG_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 (CFG_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 /*CFG_HUSH_PARSER*/}#ifdef CONFIG_BOOT_RETRY_TIME/*************************************************************************** * initialize command line timeout */void init_cmd_timeout(void){	char *s = getenv ("bootretry");	if (s != NULL)		retry_time = (int)simple_strtol(s, NULL, 10);	else		retry_time =  CONFIG_BOOT_RETRY_TIME;	if (retry_time >= 0 && retry_time < CONFIG_BOOT_RETRY_MIN)		retry_time = CONFIG_BOOT_RETRY_MIN;}/*************************************************************************** * reset command line timeout to retry_time seconds */void reset_cmd_timeout(void){	endtime = endtick(retry_time);}#endif#ifdef CONFIG_CMDLINE_EDITING/* * cmdline-editing related codes from vivi. * Author: Janghoon Lyu <nandy@mizi.com> */#define putnstr(str,n)	do {			\		printf ("%.*s", n, str);	\	} while (0)#define CTL_CH(c)		((c) - 'a' + 1)#define MAX_CMDBUF_SIZE		256#define CTL_BACKSPACE		('\b')#define DEL			((char)255)#define DEL7			((char)127)#define CREAD_HIST_CHAR		('!')#define getcmd_putch(ch)	putc(ch)#define getcmd_getch()		getc()#define getcmd_cbeep()		getcmd_putch('\a')#define HIST_MAX		20#define HIST_SIZE		MAX_CMDBUF_SIZEstatic int hist_max = 0;static int hist_add_idx = 0;static int hist_cur = -1;unsigned hist_num = 0;char* hist_list[HIST_MAX];char hist_lines[HIST_MAX][HIST_SIZE];#define add_idx_minus_one() ((hist_add_idx == 0) ? hist_max : hist_add_idx-1)static void hist_init(void){	int i;	hist_max = 0;	hist_add_idx = 0;	hist_cur = -1;	hist_num = 0;	for (i = 0; i < HIST_MAX; i++) {		hist_list[i] = hist_lines[i];		hist_list[i][0] = '\0';	}}static void cread_add_to_hist(char *line){	strcpy(hist_list[hist_add_idx], line);	if (++hist_add_idx >= HIST_MAX)		hist_add_idx = 0;	if (hist_add_idx > hist_max)		hist_max = hist_add_idx;	hist_num++;}static char* hist_prev(void){	char *ret;	int old_cur;	if (hist_cur < 0)		return NULL;	old_cur = hist_cur;	if (--hist_cur < 0)		hist_cur = hist_max;	if (hist_cur == hist_add_idx) {		hist_cur = old_cur;		ret = NULL;	} else		ret = hist_list[hist_cur];	return (ret);}static char* hist_next(void){	char *ret;	if (hist_cur < 0)		return NULL;	if (hist_cur == hist_add_idx)		return NULL;	if (++hist_cur > hist_max)		hist_cur = 0;	if (hist_cur == hist_add_idx) {		ret = "";	} else		ret = hist_list[hist_cur];	return (ret);}#ifndef CONFIG_CMDLINE_EDITINGstatic void cread_print_hist_list(void){	int i;	unsigned long n;	n = hist_num - hist_max;	i = hist_add_idx + 1;	while (1) {		if (i > hist_max)			i = 0;		if (i == hist_add_idx)			break;		printf("%s\n", hist_list[i]);		n++;		i++;	}}#endif /* CONFIG_CMDLINE_EDITING */#define BEGINNING_OF_LINE() {			\	while (num) {				\		getcmd_putch(CTL_BACKSPACE);	\		num--;				\	}					\}#define ERASE_TO_EOL() {				\	if (num < eol_num) {				\		int tmp;				\		for (tmp = num; tmp < eol_num; tmp++)	\			getcmd_putch(' ');		\		while (tmp-- > num)			\			getcmd_putch(CTL_BACKSPACE);	\		eol_num = num;				\	}						\}#define REFRESH_TO_EOL() {			\	if (num < eol_num) {			\		wlen = eol_num - num;		\		putnstr(buf + num, wlen);	\		num = eol_num;			\	}					\}static void cread_add_char(char ichar, int insert, unsigned long *num,	       unsigned long *eol_num, char *buf, unsigned long len){	unsigned long wlen;	/* room ??? */	if (insert || *num == *eol_num) {		if (*eol_num > len - 1) {			getcmd_cbeep();			return;		}		(*eol_num)++;	}	if (insert) {		wlen = *eol_num - *num;		if (wlen > 1) {			memmove(&buf[*num+1], &buf[*num], wlen-1);		}		buf[*num] = ichar;		putnstr(buf + *num, wlen);		(*num)++;		while (--wlen) {			getcmd_putch(CTL_BACKSPACE);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -