void cli_init(void) { #ifdef CONFIG_SYS_HUSH_PARSER u_boot_hush_start(); #endif #if defined(CONFIG_HUSH_INIT_VAR) hush_init_var(); #endif }
/* * this is called from board_init() after the hardware has been set up * and is usable. That seems like a good time to do this. * Right now the return value is ignored. */ int do_auto_update(void) { block_dev_desc_t *stor_dev; long sz; int i, res = 0, bitmap_first, cnt, old_ctrlc, got_ctrlc; char *env; long start, end; #undef ERASE_EEPROM #ifdef ERASE_EEPROM int arr[18]; memset(arr, 0, sizeof(arr)); i2c_write_multiple(0x54, 64, 1, arr, sizeof(arr)); #endif au_usb_stor_curr_dev = -1; /* start USB */ if (usb_stop() < 0) { debug ("usb_stop failed\n"); return -1; } if (usb_init() < 0) { debug ("usb_init failed\n"); return -1; } /* * check whether a storage device is attached (assume that it's * a USB memory stick, since nothing else should be attached). */ au_usb_stor_curr_dev = usb_stor_scan(0); if (au_usb_stor_curr_dev == -1) { debug ("No device found. Not initialized?\n"); res = -1; goto xit; } /* check whether it has a partition table */ stor_dev = get_dev("usb", 0); if (stor_dev == NULL) { debug ("uknown device type\n"); res = -1; goto xit; } if (fat_register_device(stor_dev, 1) != 0) { debug ("Unable to use USB %d:%d for fatls\n", au_usb_stor_curr_dev, 1); res = -1; goto xit; } if (file_fat_detectfs() != 0) { debug ("file_fat_detectfs failed\n"); } /* initialize the array of file names */ memset(aufile, 0, sizeof(aufile)); aufile[IDX_PREPARE] = AU_PREPARE; aufile[IDX_PREINST] = AU_PREINST; aufile[IDX_FIRMWARE] = AU_FIRMWARE; aufile[IDX_KERNEL] = AU_KERNEL; aufile[IDX_APP] = AU_APP; aufile[IDX_DISK] = AU_DISK; aufile[IDX_POSTINST] = AU_POSTINST; /* initialize the array of flash sizes */ memset(ausize, 0, sizeof(ausize)); ausize[IDX_FIRMWARE] = (AU_FL_FIRMWARE_ND + 1) - AU_FL_FIRMWARE_ST; ausize[IDX_KERNEL] = (AU_FL_KERNEL_ND + 1) - AU_FL_KERNEL_ST; ausize[IDX_APP] = (AU_FL_APP_ND + 1) - AU_FL_APP_ST; ausize[IDX_DISK] = (AU_FL_DISK_ND + 1) - AU_FL_DISK_ST; /* * now check whether start and end are defined using environment * variables. */ start = -1; end = 0; env = getenv("firmware_st"); if (env != NULL) start = simple_strtoul(env, NULL, 16); env = getenv("firmware_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); if (start >= 0 && end && end > start) { ausize[IDX_FIRMWARE] = (end + 1) - start; aufl_layout[0].start = start; aufl_layout[0].end = end; } start = -1; end = 0; env = getenv("kernel_st"); if (env != NULL) start = simple_strtoul(env, NULL, 16); env = getenv("kernel_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); if (start >= 0 && end && end > start) { ausize[IDX_KERNEL] = (end + 1) - start; aufl_layout[1].start = start; aufl_layout[1].end = end; } start = -1; end = 0; env = getenv("app_st"); if (env != NULL) start = simple_strtoul(env, NULL, 16); env = getenv("app_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); if (start >= 0 && end && end > start) { ausize[IDX_APP] = (end + 1) - start; aufl_layout[2].start = start; aufl_layout[2].end = end; } start = -1; end = 0; env = getenv("disk_st"); if (env != NULL) start = simple_strtoul(env, NULL, 16); env = getenv("disk_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); if (start >= 0 && end && end > start) { ausize[IDX_DISK] = (end + 1) - start; aufl_layout[3].start = start; aufl_layout[3].end = end; } /* make certain that HUSH is runnable */ u_boot_hush_start(); /* make sure that we see CTRL-C and save the old state */ old_ctrlc = disable_ctrlc(0); bitmap_first = 0; /* just loop thru all the possible files */ for (i = 0; i < AU_MAXFILES; i++) { /* just read the header */ sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ()); debug ("read %s sz %ld hdr %d\n", aufile[i], sz, image_get_header_size ()); if (sz <= 0 || sz < image_get_header_size ()) { debug ("%s not found\n", aufile[i]); continue; } if (au_check_header_valid(i, sz) < 0) { debug ("%s header not valid\n", aufile[i]); continue; } sz = file_fat_read(aufile[i], LOAD_ADDR, MAX_LOADSZ); debug ("read %s sz %ld hdr %d\n", aufile[i], sz, image_get_header_size ()); if (sz <= 0 || sz <= image_get_header_size ()) { debug ("%s not found\n", aufile[i]); continue; } if (au_check_cksum_valid(i, sz) < 0) { debug ("%s checksum not valid\n", aufile[i]); continue; } #ifdef CONFIG_VFD /* now that we have a valid file we can display the */ /* bitmap. */ if (bitmap_first == 0) { env = getenv("bitmap2"); if (env == NULL) { trab_vfd(0); } else { /* not so simple - bitmap2 is supposed to */ /* contain the address of the bitmap */ env = (char *)simple_strtoul(env, NULL, 16); /* NOTE: these are taken from vfd_logo.h. If that file changes then */ /* these defines MUST also be updated! These may be wrong for bitmap2. */ #define VFD_LOGO_WIDTH 112 #define VFD_LOGO_HEIGHT 72 /* must call transfer_pic directly */ transfer_pic(3, (unsigned char *)env, VFD_LOGO_HEIGHT, VFD_LOGO_WIDTH); } bitmap_first = 1; } #endif /* this is really not a good idea, but it's what the */ /* customer wants. */ cnt = 0; got_ctrlc = 0; do { res = au_do_update(i, sz); /* let the user break out of the loop */ if (ctrlc() || had_ctrlc()) { clear_ctrlc(); if (res < 0) got_ctrlc = 1; break; } cnt++; #ifdef AU_TEST_ONLY } while (res < 0 && cnt < 3); if (cnt < 3) #else } while (res < 0); #endif /* * it doesn't make sense to update the EEPROM if the * update was interrupted by the user due to errors. */ if (got_ctrlc == 0) au_update_eeprom(i); else /* enable the power switch */ *CPLD_VFD_BK &= ~POWER_OFF; }
void main_loop(void){ #ifndef CFG_HUSH_PARSER static char lastcommand[CFG_CBSIZE] = { 0, }; int len; int rc = 1; int flag; #endif int counter = 0; int stage=0; #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) char *s; int bootdelay; #endif /* defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) */ #ifdef CFG_HUSH_PARSER u_boot_hush_start(); #endif #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) // get boot delay (seconds) s = getenv("bootdelay"); bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; // get boot command s = getenv("bootcmd"); #if !defined(CONFIG_BOOTCOMMAND) #error "CONFIG_BOOTCOMMAND not defined!" #endif if(!s){ setenv("bootcmd", CONFIG_BOOTCOMMAND); } s = getenv("bootcmd"); // are we going to run web failsafe mode, U-Boot console, U-Boot netconsole or just boot command? if(reset_button_status()){ #ifdef CONFIG_SILENT_CONSOLE if(gd->flags & GD_FLG_SILENT){ /* Restore serial console */ console_assign(stdout, "serial"); console_assign(stderr, "serial"); } /* enable normal console output */ gd->flags &= ~(GD_FLG_SILENT); #endif all_led_off(); // wait 0,5s // milisecdelay(500); printf("Press reset button for at least:\n" "- %d sec. to run upgrade from USB flash\n" "- %d sec. to run U-Boot console\n" "- %d sec. to run HTTP server\n" "- %d sec. to run netconsole\n\n", CONFIG_DELAY_TO_AUTORUN_USB, CONFIG_DELAY_TO_AUTORUN_CONSOLE, CONFIG_DELAY_TO_AUTORUN_HTTPD, CONFIG_DELAY_TO_AUTORUN_NETCONSOLE); printf("Reset button is pressed for: %2d ", counter); while(reset_button_status()){ blink_sys_led(stage); // 1 second! if(!reset_button_status()){ break; } counter++; if(counter >= CONFIG_DELAY_TO_AUTORUN_USB) { if(counter >= CONFIG_DELAY_TO_AUTORUN_CONSOLE) { if(counter >= CONFIG_DELAY_TO_AUTORUN_HTTPD) { if(counter >= CONFIG_DELAY_TO_AUTORUN_NETCONSOLE) { stage=4; } else { stage=3; } } else { stage=2; } } else { stage=1; } } // how long the button is pressed? printf("\b\b\b%2d ", counter); if(counter >= CONFIG_MAX_BUTTON_PRESSING){ stage=0; // normal boot break; } } all_led_off(); if(counter > 0){ // run web failsafe mode if(stage == 1){ printf("\n\nButton was pressed for %d sec...\nStarting upgrage from USB flash...\n\n", counter); bootdelay = -1; usb_upgrade(); } else if(stage == 2){ printf("\n\nButton was pressed for %d sec...\nStarting U-Boot console...\n\n", counter); bootdelay = -1; } else if(stage == 3){ printf("\n\nButton was pressed for %d sec...\nHTTP server is starting for firmware update...\n\n", counter); NetLoopHttpd(); bootdelay = -1; } else if(stage == 4){ printf("\n\nButton was pressed for %d sec...\nStarting U-Boot netconsole...\n\n", counter); bootdelay = -1; run_command("startnc", 0); } else { printf("\n\n## Error: button wasn't pressed long enough!\nContinuing normal boot...\n\n"); } } else { printf("\n\n## Error: button wasn't pressed long enough!\nContinuing normal boot...\n\n"); } } if(bootdelay >= 0 && s && !abortboot(bootdelay)){ try_runonce(1); try_autorun(); try_runonce(2); // try to boot #ifndef CFG_HUSH_PARSER run_command(s, 0); #else parse_string_outer(s, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); #endif // something goes wrong! printf("\n## Error: failed to execute 'bootcmd'!\nHTTP server is starting for firmware update...\n\n"); NetLoopHttpd(); } #endif /* CONFIG_BOOTDELAY */ /* * Main Loop for Monitor Command Processing */ #ifdef CFG_HUSH_PARSER parse_file_outer(); /* This point is never reached */ for (;;); #else for(;;){ 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; } 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 */ }
/* * this is called from board_init() after the hardware has been set up * and is usable. That seems like a good time to do this. * Right now the return value is ignored. */ int do_auto_update(void) { block_dev_desc_t *stor_dev; long sz; int i, res = 0, cnt, old_ctrlc; char *env; long start, end; #if 0 /* disable key-press detection to speed up boot-up time */ uchar keypad_status1[2] = {0,0}, keypad_status2[2] = {0,0}; /* * Read keypad status */ i2c_read(I2C_PSOC_KEYPAD_ADDR, 0, 0, keypad_status1, 2); mdelay(500); i2c_read(I2C_PSOC_KEYPAD_ADDR, 0, 0, keypad_status2, 2); /* * Check keypad */ if ( !(keypad_status1[1] & KEYPAD_MASK_LO) || (keypad_status1[1] != keypad_status2[1])) { return 0; } #endif au_usb_stor_curr_dev = -1; /* start USB */ if (usb_stop() < 0) { debug ("usb_stop failed\n"); return -1; } if (usb_init() < 0) { debug ("usb_init failed\n"); return -1; } /* * check whether a storage device is attached (assume that it's * a USB memory stick, since nothing else should be attached). */ au_usb_stor_curr_dev = usb_stor_scan(0); if (au_usb_stor_curr_dev == -1) { debug ("No device found. Not initialized?\n"); res = -1; goto xit; } /* check whether it has a partition table */ stor_dev = get_dev("usb", 0); if (stor_dev == NULL) { debug ("uknown device type\n"); res = -1; goto xit; } if (fat_register_device(stor_dev, 1) != 0) { debug ("Unable to use USB %d:%d for fatls\n", au_usb_stor_curr_dev, 1); res = -1; goto xit; } if (file_fat_detectfs() != 0) { debug ("file_fat_detectfs failed\n"); } /* * now check whether start and end are defined using environment * variables. */ start = -1; end = 0; env = getenv("firmware_st"); if (env != NULL) start = simple_strtoul(env, NULL, 16); env = getenv("firmware_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); if (start >= 0 && end && end > start) { ausize[IDX_FIRMWARE] = (end + 1) - start; aufl_layout[IDX_FIRMWARE].start = start; aufl_layout[IDX_FIRMWARE].end = end; } start = -1; end = 0; env = getenv("kernel_st"); if (env != NULL) start = simple_strtoul(env, NULL, 16); env = getenv("kernel_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); if (start >= 0 && end && end > start) { ausize[IDX_KERNEL] = (end + 1) - start; aufl_layout[IDX_KERNEL].start = start; aufl_layout[IDX_KERNEL].end = end; } start = -1; end = 0; env = getenv("rootfs_st"); if (env != NULL) start = simple_strtoul(env, NULL, 16); env = getenv("rootfs_nd"); if (env != NULL) end = simple_strtoul(env, NULL, 16); if (start >= 0 && end && end > start) { ausize[IDX_ROOTFS] = (end + 1) - start; aufl_layout[IDX_ROOTFS].start = start; aufl_layout[IDX_ROOTFS].end = end; } /* make certain that HUSH is runnable */ u_boot_hush_start(); /* make sure that we see CTRL-C and save the old state */ old_ctrlc = disable_ctrlc(0); /* validate the images first */ for (i = 0; i < AU_MAXFILES; i++) { ulong imsize; /* just read the header */ sz = file_fat_read(aufile[i], LOAD_ADDR, image_get_header_size ()); debug ("read %s sz %ld hdr %d\n", aufile[i], sz, image_get_header_size ()); if (sz <= 0 || sz < image_get_header_size ()) { debug ("%s not found\n", aufile[i]); ausize[i] = 0; continue; } /* au_check_header_valid() updates ausize[] */ if ((imsize = au_check_header_valid(i, sz)) < 0) { debug ("%s header not valid\n", aufile[i]); continue; } /* totsize accounts for image size and flash erase size */ totsize += (imsize + (aufl_layout[i].end - aufl_layout[i].start)); } #ifdef CONFIG_PROGRESSBAR if (totsize) { lcd_puts(" Update in progress\n"); lcd_enable(); } #endif /* just loop thru all the possible files */ for (i = 0; i < AU_MAXFILES && totsize; i++) { if (!ausize[i]) { continue; } sz = file_fat_read(aufile[i], LOAD_ADDR, ausize[i]); debug ("read %s sz %ld hdr %d\n", aufile[i], sz, image_get_header_size ()); if (sz != ausize[i]) { printf ("%s: size %ld read %ld?\n", aufile[i], ausize[i], sz); continue; } if (sz <= 0 || sz <= image_get_header_size ()) { debug ("%s not found\n", aufile[i]); continue; } if (au_check_cksum_valid(i, sz) < 0) { debug ("%s checksum not valid\n", aufile[i]); continue; } /* this is really not a good idea, but it's what the */ /* customer wants. */ cnt = 0; do { res = au_do_update(i, sz); /* let the user break out of the loop */ if (ctrlc() || had_ctrlc()) { clear_ctrlc(); break; } cnt++; #ifdef AU_TEST_ONLY } while (res < 0 && cnt < (AU_MAXFILES + 1)); if (cnt < (AU_MAXFILES + 1)) #else } while (res < 0); #endif }
static __inline__ int abortboot(int bootdelay){ char stopc; 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 if(bootdelay > 0){ #ifdef CONFIG_MENUPROMPT printf(CONFIG_MENUPROMPT, bootdelay); #else printf("Hit any key to stop autoboot: %d ", bootdelay); #endif while((bootdelay > 0) && (!abort)){ int i; --bootdelay; /* delay 100 * 10ms */ for(i = 0; !abort && i < 100; ++i){ /* we got a key press */ if(tstc()){ stopc = getc(); #ifdef CONFIG_AUTOBOOT_STOP_CHAR if (stopc == CONFIG_AUTOBOOT_STOP_CHAR) { #else if (stopc != 0) { #endif abort = 1; bootdelay = 0; break; } } udelay(10000); } printf("\b\b%d ", bootdelay); } printf("\n\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_BOOTDELAY >= 0 */ /****************************************************************************/ void main_loop(void){ #ifndef CFG_HUSH_PARSER static char lastcommand[CFG_CBSIZE] = { 0, }; int len; int rc = 1; int flag; #endif int counter = 0; #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) char *s; int bootdelay; #endif /* defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) */ #ifdef CFG_HUSH_PARSER u_boot_hush_start(); #endif #if defined(CONFIG_BOOTDELAY) && (CONFIG_BOOTDELAY >= 0) // get boot delay (seconds) s = getenv("bootdelay"); bootdelay = s ? (int)simple_strtol(s, NULL, 10) : CONFIG_BOOTDELAY; // get boot command s = getenv("bootcmd"); #if !defined(CONFIG_BOOTCOMMAND) #error "CONFIG_BOOTCOMMAND not defined!" #endif if(!s){ setenv("bootcmd", CONFIG_BOOTCOMMAND); } s = getenv("bootcmd"); // are we going to run web failsafe mode, U-Boot console, U-Boot netconsole or just boot command? if(reset_button_status()){ #ifdef CONFIG_SILENT_CONSOLE if(gd->flags & GD_FLG_SILENT){ /* Restore serial console */ console_assign(stdout, "serial"); console_assign(stderr, "serial"); } /* enable normal console output */ gd->flags &= ~(GD_FLG_SILENT); #endif // wait 0,5s milisecdelay(500); printf("Press reset button for at least:\n- %d sec. to run web failsafe mode\n- %d sec. to run U-Boot console\n- %d sec. to run U-Boot netconsole\n\n", CONFIG_DELAY_TO_AUTORUN_HTTPD, CONFIG_DELAY_TO_AUTORUN_CONSOLE, CONFIG_DELAY_TO_AUTORUN_NETCONSOLE); printf("Reset button is pressed for: %2d ", counter); while(reset_button_status()){ // LED ON and wait 0,15s all_led_on(); milisecdelay(150); // LED OFF and wait 0,85s all_led_off(); milisecdelay(850); counter++; // how long the button is pressed? printf("\b\b\b%2d ", counter); if(!reset_button_status()){ break; } if(counter >= CONFIG_MAX_BUTTON_PRESSING){ break; } } all_led_off(); if(counter > 0){ // run web failsafe mode if(counter >= CONFIG_DELAY_TO_AUTORUN_HTTPD && counter < CONFIG_DELAY_TO_AUTORUN_CONSOLE){ printf("\n\nButton was pressed for %d sec...\nHTTP server is starting for firmware update...\n\n", counter); NetLoopHttpd(); bootdelay = -1; } else if(counter >= CONFIG_DELAY_TO_AUTORUN_CONSOLE && counter < CONFIG_DELAY_TO_AUTORUN_NETCONSOLE){ printf("\n\nButton was pressed for %d sec...\nStarting U-Boot console...\n\n", counter); bootdelay = -1; } else if(counter >= CONFIG_DELAY_TO_AUTORUN_NETCONSOLE){ printf("\n\nButton was pressed for %d sec...\nStarting U-Boot netconsole...\n\n", counter); bootdelay = -1; run_command("startnc", 0); } else { printf("\n\n## Error: button wasn't pressed long enough!\nContinuing normal boot...\n\n"); } } else { printf("\n\n## Error: button wasn't pressed long enough!\nContinuing normal boot...\n\n"); } } if(bootdelay >= 0 && s && !abortboot(bootdelay)){ // try to boot #ifndef CFG_HUSH_PARSER run_command(s, 0); #else parse_string_outer(s, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); #endif // something goes wrong! printf("\n## Error: failed to execute 'bootcmd'!\nHTTP server is starting for firmware update...\n\n"); NetLoopHttpd(); } #endif /* CONFIG_BOOTDELAY */ /* * Main Loop for Monitor Command Processing */ #ifdef CFG_HUSH_PARSER parse_file_outer(); /* This point is never reached */ for (;;); #else for(;;){ 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; } 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 */ } /****************************************************************************/ /* * Prompt for input and read a line. * If CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0, * time out when time goes past endtime (timebase time in ticks). * Return: number of read characters * -1 if break * -2 if timed out */ int readline(const char * const prompt){ char *p = console_buffer; int n = 0; /* buffer index */ int plen = 0; /* prompt length */ int col; /* output column cnt */ char c; /* print prompt */ if(prompt){ plen = strlen(prompt); puts(prompt); } col = plen; for(;;){ c = getc(); /* * Special character handling */ switch(c){ case '\r': /* Enter */ case '\n': *p = '\0'; puts("\r\n"); return(p - console_buffer); case '\0': /* nul */ continue; case 0x03: /* ^C - break */ console_buffer[0] = '\0'; /* discard input */ return(-1); case 0x15: /* ^U - erase line */ while(col > plen){ puts(erase_seq); --col; } p = console_buffer; n = 0; continue; case 0x17: /* ^W - erase word */ p = delete_char(console_buffer, p, &col, &n, plen); while((n > 0) && (*p != ' ')){ p = delete_char(console_buffer, p, &col, &n, plen); } continue; case 0x08: /* ^H - backspace */ case 0x7F: /* DEL - backspace */ p = delete_char(console_buffer, p, &col, &n, plen); continue; default: /* * Must be a normal character then */ if(n < CFG_CBSIZE - 2){ if(c == '\t'){ /* expand TABs */ puts(tab_seq + (col & 07)); col += 8 - (col & 07); } else { ++col; /* echo input */ putc(c); } *p++ = c; ++n; } else { /* Buffer full */ putc('\a'); } } } }