AvbDefs__ErrorCode sendCommand(string_t cmd) { int returnValue = e_EC_SUCCESS; /* Invoke the HUSH parser on the command */ printf("Mailbox sendCommand: \"%s\", strlen = %d\n", cmd, strlen(cmd)); if(parse_string_outer(cmd, (FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP)) != 0) { returnValue = e_EC_NOT_EXECUTED; } return(returnValue); }
int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){ int rcode = 0; #ifndef CFG_HUSH_PARSER if(run_command (getenv ("bootcmd"), flag) < 0){ rcode = 1; } #else if(parse_string_outer(getenv("bootcmd"), FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0){ rcode = 1; } #endif return(rcode); }
/* * Run a command using the selected parser. * * @param cmd Command to run * @param flag Execution flags (CMD_FLAG_...) * @return 0 on success, or != 0 on error. */ int run_command(const char *cmd, int flag) { #ifndef CONFIG_SYS_HUSH_PARSER /* * builtin_run_command can return 0 or 1 for success, so clean up * its result. */ if (builtin_run_command(cmd, flag) == -1) return 1; return 0; #else return parse_string_outer(cmd, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); #endif }
/* * Run a command using the selected parser, and check if it is repeatable. * * @param cmd Command to run * @param flag Execution flags (CMD_FLAG_...) * @return 0 (not repeatable) or 1 (repeatable) on success, -1 on error. */ int run_command_repeatable(const char *cmd, int flag) { #ifndef CONFIG_SYS_HUSH_PARSER return cli_simple_run_command(cmd, flag); #else /* * parse_string_outer() returns 1 for failure, so clean up * its result. */ if (parse_string_outer(cmd, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP)) return -1; return 0; #endif }
int executeFirmwareUpdate(void) { if (doCrcCheck() == FALSE) { *state = UPDATE_CORRUPT_IMAGE; return(1); } /* Invoke the HUSH parser on the command */ if(parse_string_outer(fwUpdateCtxt.cmd, (FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP)) != 0) { *state = UPDATE_NOT_EXECUTED; return(1); } *state = UPDATE_SUCCESS; return(0); }
/* * Run a command using the selected parser. * * @param cmd Command to run * @param flag Execution flags (CMD_FLAG_...) * @return 0 on success, or != 0 on error. */ int run_command(const char *cmd, int flag) { #ifndef CONFIG_SYS_HUSH_PARSER /* * cli_run_command can return 0 or 1 for success, so clean up * its result. */ if (cli_simple_run_command(cmd, flag) == -1) return 1; return 0; #else int hush_flags = FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP; if (flag & CMD_FLAG_ENV) hush_flags |= FLAG_CONT_ON_NEWLINE; return parse_string_outer(cmd, hush_flags); #endif }
int run_command_list(const char *cmd, int len, int flag) { int need_buff = 1; char *buff = (char *)cmd; /* cast away const */ int rcode = 0; if (len == -1) { len = strlen(cmd); #ifdef CONFIG_SYS_HUSH_PARSER /* hush will never change our string */ need_buff = 0; #else /* the built-in parser will change our string if it sees \n */ need_buff = strchr(cmd, '\n') != NULL; #endif } if (need_buff) { buff = malloc(len + 1); if (!buff) return 1; memcpy(buff, cmd, len); buff[len] = '\0'; } #ifdef CONFIG_SYS_HUSH_PARSER rcode = parse_string_outer(buff, FLAG_PARSE_SEMICOLON); #else /* * This function will overwrite any \n it sees with a \0, which * is why it can't work with a const char *. Here we are making * using of internal knowledge of this function, to avoid always * doing a malloc() which is actually required only in a case that * is pretty rare. */ rcode = builtin_run_command_list(buff, flag); if (need_buff) free(buff); #endif return rcode; }
static void do_option(const struct option *option) { int seconds, next; bm_printf(ANSI_CLEAR ANSI_GOTOYX, 1, 1); redirect_console(1); if (option->fn) { option->fn(option->user); } else { #ifndef CONFIG_SYS_HUSH_PARSER run_command(option->user, 0); #else parse_string_outer(option->user, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP); #endif } redirect_console(0); seconds = get_var_positive_int("after_command_wait", AFTER_COMMAND_WAIT); if (seconds) bm_printf("\n%s to %s.", setup->next_key_action, option ? "return to boot menu" : "power off"); next = 1; /* require up-down transition */ while (seconds) { int tmp; tmp = setup->next_key(setup->user); if (tmp && !next) break; next = tmp; if (setup->seconds(setup->user)) seconds--; } if (!option) setup->idle_action(setup->idle_action); show_bootmenu(); }
int do_run(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]){ int i; if(argc < 2){ #ifdef CFG_LONGHELP if(cmdtp->help != NULL){ printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->help); } else { printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage); } #else printf("Usage:\n%s %s\n", cmdtp->name, cmdtp->usage); #endif return(1); } for(i=1; i<argc; ++i){ char *arg; if((arg = getenv(argv[i])) == NULL){ printf("## Error: \"%s\" not defined\n", argv[i]); return(1); } #ifndef CFG_HUSH_PARSER if(run_command(arg, flag) == -1){ return(1); } #else if (parse_string_outer(arg, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0){ return(1); } #endif /* CFG_HUSH_PARSER */ } return(0); }
int au_do_update(int idx, long sz) { image_header_t *hdr; char *addr; long start, end; int off, rc; uint nbytes; hdr = (image_header_t *)LOAD_ADDR; #if defined(CONFIG_FIT) if (genimg_get_format ((void *)hdr) != IMAGE_FORMAT_LEGACY) { puts ("Non legacy image format not supported\n"); return -1; } #endif /* disable the power switch */ *CPLD_VFD_BK |= POWER_OFF; /* execute a script */ if (image_check_type (hdr, IH_TYPE_SCRIPT)) { addr = (char *)((char *)hdr + image_get_header_size ()); /* stick a NULL at the end of the script, otherwise */ /* parse_string_outer() runs off the end. */ addr[image_get_data_size (hdr)] = 0; addr += 8; parse_string_outer(addr, FLAG_PARSE_SEMICOLON); return 0; } start = aufl_layout[FIDX_TO_LIDX(idx)].start; end = aufl_layout[FIDX_TO_LIDX(idx)].end; /* unprotect the address range */ /* this assumes that ONLY the firmware is protected! */ if (idx == IDX_FIRMWARE) { #undef AU_UPDATE_TEST #ifdef AU_UPDATE_TEST /* erase it where Linux goes */ start = aufl_layout[1].start; end = aufl_layout[1].end; #endif flash_sect_protect(0, start, end); } /* * erase the address range. */ debug ("flash_sect_erase(%lx, %lx);\n", start, end); flash_sect_erase(start, end); wait_ms(100); /* strip the header - except for the kernel and ramdisk */ if (image_check_type (hdr, IH_TYPE_KERNEL) || image_check_type (hdr, IH_TYPE_RAMDISK)) { addr = (char *)hdr; off = image_get_header_size (); nbytes = image_get_image_size (hdr); } else { addr = (char *)((char *)hdr + image_get_header_size ()); #ifdef AU_UPDATE_TEST /* copy it to where Linux goes */ if (idx == IDX_FIRMWARE) start = aufl_layout[1].start; #endif off = 0; nbytes = image_get_data_size (hdr); } /* copy the data from RAM to FLASH */ debug ("flash_write(%p, %lx %x)\n", addr, start, nbytes); rc = flash_write(addr, start, nbytes); if (rc != 0) { printf("Flashing failed due to error %d\n", rc); return -1; } /* check the dcrc of the copy */ if (crc32 (0, (uchar *)(start + off), image_get_data_size (hdr)) != image_get_dcrc (hdr)) { printf ("Image %s Bad Data Checksum After COPY\n", aufile[idx]); return -1; } /* protect the address range */ /* this assumes that ONLY the firmware is protected! */ if (idx == IDX_FIRMWARE) flash_sect_protect(1, start, end); return 0; }
int autoscript (ulong addr, const char *fit_uname) { ulong len; image_header_t *hdr; ulong *data; char *cmd; int rcode = 0; int verify; #if defined(CONFIG_FIT) const void* fit_hdr; int noffset; const void *fit_data; size_t fit_len; #endif verify = getenv_yesno ("verify"); switch (genimg_get_format ((void *)addr)) { case IMAGE_FORMAT_LEGACY: hdr = (image_header_t *)addr; if (!image_check_magic (hdr)) { puts ("Bad magic number\n"); return 1; } if (!image_check_hcrc (hdr)) { puts ("Bad header crc\n"); return 1; } if (verify) { if (!image_check_dcrc (hdr)) { puts ("Bad data crc\n"); return 1; } } if (!image_check_type (hdr, IH_TYPE_SCRIPT)) { puts ("Bad image type\n"); return 1; } /* get length of script */ data = (ulong *)image_get_data (hdr); if ((len = uimage_to_cpu (*data)) == 0) { puts ("Empty Script\n"); return 1; } /* * scripts are just multi-image files with one component, seek * past the zero-terminated sequence of image lengths to get * to the actual image data */ while (*data++); break; #if defined(CONFIG_FIT) case IMAGE_FORMAT_FIT: if (fit_uname == NULL) { puts ("No FIT subimage unit name\n"); return 1; } fit_hdr = (const void *)addr; if (!fit_check_format (fit_hdr)) { puts ("Bad FIT image format\n"); return 1; } /* get script component image node offset */ noffset = fit_image_get_node (fit_hdr, fit_uname); if (noffset < 0) { printf ("Can't find '%s' FIT subimage\n", fit_uname); return 1; } if (!fit_image_check_type (fit_hdr, noffset, IH_TYPE_SCRIPT)) { puts ("Not a image image\n"); return 1; } /* verify integrity */ if (verify) { if (!fit_image_check_hashes (fit_hdr, noffset)) { puts ("Bad Data Hash\n"); return 1; } } /* get script subimage data address and length */ if (fit_image_get_data (fit_hdr, noffset, &fit_data, &fit_len)) { puts ("Could not find script subimage data\n"); return 1; } data = (ulong *)fit_data; len = (ulong)fit_len; break; #endif default: puts ("Wrong image format for autoscript\n"); return 1; } debug ("** Script length: %ld\n", len); if ((cmd = malloc (len + 1)) == NULL) { return 1; } /* make sure cmd is null terminated */ memmove (cmd, (char *)data, len); *(cmd + len) = 0; #ifdef CONFIG_SYS_HUSH_PARSER /*?? */ rcode = parse_string_outer (cmd, FLAG_PARSE_SEMICOLON); #else { char *line = cmd; char *next = cmd; /* * break into individual lines, * and execute each line; * terminate on error. */ while (*next) { if (*next == '\n') { *next = '\0'; /* run only non-empty commands */ if (*line) { debug ("** exec: \"%s\"\n", line); if (run_command (line, 0) < 0) { rcode = 1; break; } } line = next + 1; } ++next; } if (rcode == 0 && *line) rcode = (run_command(line, 0) >= 0); } #endif free (cmd); return rcode; }
/* run_pipe_real() starts all the jobs, but doesn't wait for anything * to finish. See checkjobs(). * * return code is normally -1, when the caller has to wait for children * to finish to determine the exit status of the pipe. If the pipe * is a simple builtin command, however, the action is done by the * time run_pipe_real returns, and the exit code is provided as the * return value. * * The input of the pipe is always stdin, the output is always * stdout. The outpipe[] mechanism in BusyBox-0.48 lash is bogus, * because it tries to avoid running the command substitution in * subshell, when that is in fact necessary. The subshell process * now has its stdout directed to the input of the appropriate pipe, * so this routine is noticeably simpler. */ static int run_pipe_real(struct pipe *pi) { int i; int nextin; int flag = do_repeat ? CMD_FLAG_REPEAT : 0; struct child_prog *child; char *p; #if __GNUC__ /* Avoid longjmp clobbering */ (void) &i; (void) &nextin; (void) &child; #endif nextin = 0; /* Check if this is a simple builtin (not part of a pipe). * Builtins within pipes have to fork anyway, and are handled in * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. */ if (pi->num_progs == 1) child = & (pi->progs[0]); if (pi->num_progs == 1 && child->group) { int rcode; debug_printf("non-subshell grouping\n"); rcode = run_list_real(child->group); return rcode; } else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) { for (i=0; is_assignment(child->argv[i]); i++) { /* nothing */ } if (i!=0 && child->argv[i]==NULL) { /* assignments, but no command: set the local environment */ for (i=0; child->argv[i]!=NULL; i++) { /* Ok, this case is tricky. We have to decide if this is a * local variable, or an already exported variable. If it is * already exported, we have to export the new value. If it is * not exported, we need only set this as a local variable. * This junk is all to decide whether or not to export this * variable. */ int export_me=0; char *name, *value; name = xstrdup(child->argv[i]); debug_printf("Local environment set: %s\n", name); value = strchr(name, '='); if (value) *value=0; free(name); p = insert_var_value(child->argv[i]); set_local_var(p, export_me); if (p != child->argv[i]) free(p); } return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */ } for (i = 0; is_assignment(child->argv[i]); i++) { p = insert_var_value(child->argv[i]); set_local_var(p, 0); if (p != child->argv[i]) { child->sp--; free(p); } } if (child->sp) { char * str = NULL; str = make_string((child->argv + i)); parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING); free(str); return last_return_code; } /* check ";", because ,example , argv consist from * "help;flinfo" must not execute */ if (strchr(child->argv[i], ';')) { printf("Unknown command '%s' - try 'help' or use " "'run' command\n", child->argv[i]); return -1; } /* Process the command */ return cmd_process(flag, child->argc, child->argv, &flag_repeat, NULL); } return -1; }
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 */ }
int do_stage_boot(cmd_tbl_t * cmdtb, int flag, int argc, char *argv[]) { char *path_to_image, *path_to_scr, *path_to_initrd, *all_partions; ulong addr; int j,i=1,step=0,len,index,device,initrd=0; char * kernel_addr, *bootargs; char * args_to_func[5]; char device_prt[4]; if(argc < 2){ printf("No args, try help stage_boot\n"); return 0; } path_to_initrd = (char *)malloc((strlen(SCRIPT_PATH)+strlen(getenv("initrd_name")))*sizeof(char)); strcpy(path_to_initrd,SCRIPT_PATH); strcat(path_to_initrd,getenv("initrd_name")); path_to_image = (char *)malloc((strlen(SCRIPT_PATH)+strlen(getenv("image_name")))*sizeof(char)); strcpy(path_to_image,SCRIPT_PATH); strcat(path_to_image,getenv("image_name")); path_to_scr = (char *)malloc((strlen(SCRIPT_PATH)+strlen(getenv("script_name")))*sizeof(char)); strcpy(path_to_scr,SCRIPT_PATH); strcat(path_to_scr,getenv("script_name")); all_partions = (char *)malloc(strlen(getenv("device_partition"))*sizeof(char)); strcpy(all_partions,getenv("device_partition")); kernel_addr = getenv("kernel_addr_r"); #if !defined(CONFIG_MACH_AVANTA_LP_FPGA) ide_init(); #endif for(device=1;device<argc;device++) { #if !defined(CONFIG_MACH_AVANTA_LP_FPGA) /* step 1 load script from ide */ len=strlen(all_partions); for(index=0;index<len && i==1 && strcmp(argv[device],"hd_scr")==0 ;index++) { step=1; for(j=0;j<3;j++,index++) device_prt[j]=all_partions[index]; device_prt[3]='\0'; printf("\ntry to load script from ide %s\n",device_prt); args_to_func[0]="ext2load"; args_to_func[1]=INTERFACE_HD; args_to_func[2]=device_prt; args_to_func[3]=LOAD_ADDR; args_to_func[4]=path_to_scr; i = do_ext2load(cmdtb, 1, 5 , args_to_func); addr = simple_strtoul(args_to_func[3], NULL, 16); } /* finish step 1 */ /* step 2 boot PXE */ if (i== 1 && strcmp(argv[device],"pxe") == 0) { step = 2; save_env(); setenv("boot_from_pxe","1"); setenv("autoload","no"); setenv("pxefile_addr_r",LOAD_ADDR); args_to_func[0]="dhcp"; args_to_func[1]=getenv("pxefile_addr_r"); i = do_dhcp(cmdtb, 1, 1, args_to_func); if(i==0) i = do_pxe_get(cmdtb, 1 , 1, args_to_func); setenv("boot_from_pxe","0"); if(i==1) restore_env(); } /* finish step 2 */ /* step 3 load linux image from ide */ if( i == 1 && strcmp(argv[device],"hd_img")==0 ) { step = 3; len=strlen(all_partions); for(index=0;index<len && i==1 ;index++) { for(j=0;j<3;j++,index++) device_prt[j]=all_partions[index]; device_prt[3]='\0'; printf("\ntry to load image from ide %s\n", device_prt); args_to_func[0]="ext2load"; args_to_func[1]=INTERFACE_HD; args_to_func[2]=device_prt; args_to_func[3]=getenv("kernel_addr_r"); args_to_func[4]=path_to_image; i = do_ext2load(cmdtb, 1, 5 , args_to_func); addr = simple_strtoul(args_to_func[3], NULL, 16); if( i==0 ){ int temp; args_to_func[3]=getenv("ramdisk_addr_r"); args_to_func[4]=path_to_initrd; temp = do_ext2load(cmdtb, 1, 5 , args_to_func); if(temp == 0) { initrd = 1; args_to_func[1] = getenv("kernel_addr_r"); args_to_func[2] = getenv("ramdisk_addr_r"); } } } } /* finish step 3 */ /*step 4 load script from tftp */ if( i == 1 && strcmp(argv[device],"net_scr")==0 ) { printf("\ntry to load script from tftp\n"); step = 4; args_to_func[0]="tftp"; args_to_func[1]=LOAD_ADDR; args_to_func[2]=getenv("script_name"); i = do_tftpb(cmdtb, 1, 3,args_to_func); addr = simple_strtoul(args_to_func[1], NULL, 16); } #endif /* finish step 4 */ /*step 5 load linux image from tftp */ if( i == 1 && strcmp(argv[device],"net_img")==0 ) { printf("\ntry to load image from tftp\n"); step = 5; args_to_func[0]="tftp"; args_to_func[1]=getenv("kernel_addr_r"); args_to_func[2]=getenv("image_name"); i = do_tftpb(cmdtb, 1, 3,args_to_func); addr = simple_strtoul(args_to_func[1], NULL, 16); } /* finish step 5 */ } free(path_to_image); free(path_to_scr); path_to_image = getenv("bootargs_dflt"); if(!path_to_image) { printf("missing environment variable: bootargs_dflt\n"); return 0; } if (step == 3 && initrd ==1){ setenv("bootargs_dflt","console=ttyS0,115200 earlyprintk=ttyS0 root=/dev/sda2 ro pm_disable"); } bootargs = (char *)malloc(sizeof(char)*(strlen(getenv("bootargs_dflt"))+17)); strcpy(bootargs,"setenv bootargs "); #ifndef CONFIG_SYS_HUSH_PARSER if (run_command(strcat(bootargs,getenv("bootargs_dflt")), flag) < 0) { printf("missing environment variable: bootargs_dflt\n"); return 0; } #else marvell_recursive_parse = 1; if (parse_string_outer(strcat(bootargs,getenv("bootargs_dflt")), FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0){ printf("missing environment variable: bootargs_dflt\n"); marvell_recursive_parse = 0; return 0; } marvell_recursive_parse = 0; #endif if(i==0) { if(step == 1 || step == 4) source(addr,NULL); else if ((step == 3 && initrd ==0 )|| step == 5) do_bootm(cmdtb, 1,1,(char * const*)kernel_addr); else if (step ==2) do_pxe_boot(cmdtb, 2, 1,(char * const *)NULL); else if (step == 3 && initrd ==1){ do_bootm(cmdtb, 1,2,args_to_func); } } else { printf("Unable to load image/script\n"); } return 1; }
/* run_pipe_real() starts all the jobs, but doesn't wait for anything * to finish. See checkjobs(). * * return code is normally -1, when the caller has to wait for children * to finish to determine the exit status of the pipe. If the pipe * is a simple builtin command, however, the action is done by the * time run_pipe_real returns, and the exit code is provided as the * return value. * * The input of the pipe is always stdin, the output is always * stdout. The outpipe[] mechanism in BusyBox-0.48 lash is bogus, * because it tries to avoid running the command substitution in * subshell, when that is in fact necessary. The subshell process * now has its stdout directed to the input of the appropriate pipe, * so this routine is noticeably simpler. */ static int run_pipe_real(struct pipe *pi) { int i; int nextin; int flag = do_repeat ? CMD_FLAG_REPEAT : 0; struct child_prog *child; cmd_tbl_t *cmdtp; char *p; # if __GNUC__ /* Avoid longjmp clobbering */ (void) &i; (void) &nextin; (void) &child; # endif nextin = 0; /* Check if this is a simple builtin (not part of a pipe). * Builtins within pipes have to fork anyway, and are handled in * pseudo_exec. "echo foo | read bar" doesn't work on bash, either. */ if (pi->num_progs == 1) child = &(pi->progs[0]); if (pi->num_progs == 1 && child->group) { int rcode; debug_printf("non-subshell grouping\n"); rcode = run_list_real(child->group); return rcode; } else if (pi->num_progs == 1 && pi->progs[0].argv != NULL) { for (i = 0; is_assignment(child->argv[i]); i++) { /* nothing */ } if (i != 0 && child->argv[i] == NULL) { /* assignments, but no command: set the local environment */ for (i = 0; child->argv[i] != NULL; i++) { /* Ok, this case is tricky. We have to decide if this is a * local variable, or an already exported variable. If it is * already exported, we have to export the new value. If it is * not exported, we need only set this as a local variable. * This junk is all to decide whether or not to export this * variable. */ int export_me = 0; char *name, *value; name = xstrdup(child->argv[i]); debug_printf("Local environment set: %s\n", name); value = strchr(name, '='); if (value) *value = 0; free(name); p = insert_var_value(child->argv[i]); set_local_var(p, export_me); if (p != child->argv[i]) free(p); } return EXIT_SUCCESS; /* don't worry about errors in set_local_var() yet */ } for (i = 0; is_assignment(child->argv[i]); i++) { p = insert_var_value(child->argv[i]); set_local_var(p, 0); if (p != child->argv[i]) { child->sp--; free(p); } } if (child->sp) { char * str = NULL; str = make_string((child->argv + i)); parse_string_outer(str, FLAG_EXIT_FROM_LOOP | FLAG_REPARSING); free(str); return last_return_code; } /* check ";", because ,example , argv consist from * "help;flinfo" must not execute */ if (strchr(child->argv[i], ';')) { printf_err("unknown command '%s' - try 'help' or use 'run' command\n", child->argv[i]); return -1; } /* Look up command in command table */ if ((cmdtp = find_cmd(child->argv[i])) == NULL) { printf_err("unknown command '%s' - try 'help'\n", child->argv[i]); return -1; /* give up after bad command */ } else { int rcode; #if defined(CONFIG_CMD_BOOTD) extern int do_bootd (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]); /* avoid "bootd" recursion */ if (cmdtp->cmd == do_bootd) { if (flag & CMD_FLAG_BOOTD) { printf_err("'bootd' recursion detected!\n"); return -1; } else { flag |= CMD_FLAG_BOOTD; } } #endif /* CONFIG_CMD_BOOTD */ /* found - check max args */ if ((child->argc - i) > cmdtp->maxargs) { print_cmd_help(cmdtp); return -1; } child->argv += i; /* XXX horrible hack */ /* OK - call function to do the command */ rcode = (cmdtp->cmd)(cmdtp, flag, child->argc - i, &child->argv[i]); if (!cmdtp->repeatable) flag_repeat = 0; child->argv -= i; /* XXX restore hack so free() can work right */ return rcode; } } return -1; }
int dump_regions_from_environment(void) { Elf32_Ehdr *elfhdr_addr; int rc = 0; char *orig_bootargs; char *bootargs; char *p; char *memargs_cmd; char *memargs; int nuf_ph; range_t ck = {0, 0}; range_t *regions; char *crashkernel; unsigned int i; unsigned int region_no; /* Right now getenv("crashkernel") has a value on the form "crashkernel=nn[KMG]@ss[KMG]" but this is expanded into "crashkernel=${crashkernel}" when constructing the kernel commandline, amounting to: "crashkernel=crashkernel=nn[KMG]@ss[KMG]" This might get fixed so this code can handle both. */ crashkernel = getenv("crashkernel"); if(crashkernel == NULL) { debug("checkcrash: no crashkernel environment variable\n"); rc = 1; goto out5; } crashkernel = strdup(crashkernel); if(crashkernel == NULL) { debug("checkcrash: could not strdup crashkernel variable\n"); rc = 1; goto out5; } p = strchr(crashkernel, '='); if (p != NULL) { p++; suffixed_addr_toul(p, &ck); } else { suffixed_addr_toul(crashkernel, &ck); } /* Make copy of bootargs, if it exists */ orig_bootargs = getenv("bootargs"); if(orig_bootargs != NULL) { orig_bootargs = strdup(orig_bootargs); if(orig_bootargs == NULL) { debug("checkcrash: could not strdup bootargs variable to reset to\n"); rc = 1; goto out4; } } /* Unset bootargs */ if (setenv("bootargs", "") != 0) { debug("checkcrash: could not unset bootargs variable\n"); rc = 1; goto out3; } /* Run memargs to set bootargs */ memargs_cmd = getenv("memargs"); if(memargs_cmd == NULL) { debug("checkcrash: no memargs_cmd environment variable\n"); rc = 1; goto out3; } #ifndef CONFIG_SYS_HUSH_PARSER if (run_command(memargs_cmd, 0) < 0) { debug("checkcrash: failed to run memargs\n"); rc = 1; goto out3; } #else if (parse_string_outer(memargs_cmd, FLAG_PARSE_SEMICOLON | FLAG_EXIT_FROM_LOOP) != 0) { debug("checkcrash: failed to run memargs\n"); rc = 1; goto out3; } #endif memargs = bootargs = strdup(getenv("bootargs")); if(bootargs == NULL) { debug("checkcrash: could not strdup bootargs variable to manipulate it\n"); rc = 1; goto out3; } /* Restore bootargs */ if (orig_bootargs && setenv("bootargs", orig_bootargs)) { debug("checkcrash: could not reset bootargs variable\n"); rc = 1; goto out2; } /* Calculate the number of regions */ nuf_ph = 1; // One extra since the crashkernel is likely to split one of the regions p = memargs; while (*p != '\0') { if (match_region(p)) {nuf_ph++;} while (!isspace(*p)) { p++; } while (isspace(*p)) { p++; } } /* Add one entry for SOC_AVS_BACKUPRAM */ nuf_ph += 1; printf ("nuf_ph %d\n", nuf_ph); regions = malloc(nuf_ph*sizeof(*regions)); if (regions == NULL) { debug("checkcrash: could not allocate array of ranges\n"); rc = 1; goto out2; } region_no = 0; while (memargs != NULL) { size_t len; p = strsep(&memargs, " \t"); len = match_region(p); if (!len) continue; p += len; suffixed_addr_toul(p, ®ions[region_no]); if (ck.start==(regions[region_no].start) && (ck.start+ck.size)==(regions[region_no].start+regions[region_no].size)) { /* Skip */ } else if (ck.start==(regions[region_no].start) && (ck.start+ck.size)<(regions[region_no].start+regions[region_no].size)) { /* Skip beginning */ regions[region_no].start = ck.start+ck.size; regions[region_no].size -= ck.size; } else if (ck.start>(regions[region_no].start) && (ck.start+ck.size)==(regions[region_no].start+regions[region_no].size)) { /* Skip end */ regions[region_no].size -= ck.size; } else if (ck.start>=(regions[region_no].start) && (ck.start+ck.size)<=(regions[region_no].start+regions[region_no].size)) { /* Split */ regions[region_no+1].start = ck.start + ck.size; regions[region_no+1].size = (regions[region_no].start + regions[region_no].size) - regions[region_no+1].start; regions[region_no].size = ck.start - regions[region_no].start; region_no++; } region_no++; } /* Add SOC_AVS_BACKUPRAM */ regions[region_no].start = SOC_AVS_BACKUPRAM; regions[region_no].size = SOC_AVS_BACKUPRAM_LEN; region_no++; for (i=0;i<region_no;i++) { debug("%lu placed at %lu\n", regions[i].size, regions[i].start); } elfhdr_addr = create_elfhdr(regions, region_no); if (elfhdr_addr == NULL) { debug("Could not create elfhdr\n"); rc = 1; goto out1; } if (crashdump(elfhdr_addr) != 0) { rc = 1; } free(elfhdr_addr); out1: free(regions); out2: free(bootargs); out3: free(orig_bootargs); out4: free(crashkernel); out5: return rc; }
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'); } } } }