static int console_tstc(int file) { int i, ret; struct stdio_dev *dev; #if defined CONFIG_BOARD_POLL /* Generic polling function */ board_poll_devices(); #endif disable_ctrlc(1); for (i = 0; i < cd_count[file]; i++) { dev = console_devices[file][i]; if (dev->tstc != NULL) { ret = dev->tstc(); if (ret > 0) { tstcdev = dev; disable_ctrlc(0); return ret; } } } disable_ctrlc(0); return 0; }
/* * Runs the given boot command securely. Specifically: * - Doesn't run the command with the shell (run_command or parse_string_outer), * since that's a lot of code surface that an attacker might exploit. * Because of this, we don't do any argument parsing--the secure boot command * has to be a full-fledged u-boot command. * - Doesn't check for keypresses before booting, since that could be a * security hole; also disables Ctrl-C. * - Doesn't allow the command to return. * * Upon any failures, this function will drop into an infinite loop after * printing the error message to console. */ void cli_secure_boot_cmd(const char *cmd) { cmd_tbl_t *cmdtp; int rc; if (!cmd) { printf("## Error: Secure boot command not specified\n"); goto err; } /* Disable Ctrl-C just in case some command is used that checks it. */ disable_ctrlc(1); /* Find the command directly. */ cmdtp = find_cmd(cmd); if (!cmdtp) { printf("## Error: \"%s\" not defined\n", cmd); goto err; } /* Run the command, forcing no flags and faking argc and argv. */ rc = (cmdtp->cmd)(cmdtp, 0, 1, (char **)&cmd); /* Shouldn't ever return from boot command. */ printf("## Error: \"%s\" returned (code %d)\n", cmd, rc); err: /* * Not a whole lot to do here. Rebooting won't help much, since we'll * just end up right back here. Just loop. */ hang(); }
static int console_tstc(int file) { int i, ret; struct stdio_dev *dev; disable_ctrlc(1); for (i = 0; i < cd_count[file]; i++) { dev = console_devices[file][i]; if (dev->tstc != NULL) { ret = dev->tstc(); if (ret > 0) { tstcdev = dev; disable_ctrlc(0); return ret; } } } disable_ctrlc(0); return 0; }
/* * 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; }
static int __doUsbUpgrade(int nStorMode) { int nRet = FALSE; int nOldCtrlc = 0; int nReadLength = 0; PacketInfo_S * psPacketInfo = NULL; char acReadFileName[32]={0}; char *pcDeviceName = NULL; unsigned int extension_id = get_extension_chip_id(); switch (extension_id) { case ARCH_EXID_AT91SAM9G25: pcDeviceName = "sam9g25ek"; break; case ARCH_EXID_AT91SAM9G35: pcDeviceName = "sam9g35ek"; break; case ARCH_EXID_AT91SAM9X25: pcDeviceName = "sam9x25ek"; break; case ARCH_EXID_AT91SAM9X35: pcDeviceName = "sam9x35ek"; break; default: printf("Warning: extension_id[0x%X] not support! Take sam9x25ek.dtb as default.", extension_id); pcDeviceName = "sam9x25ek"; break; } memset(acReadFileName, 0, sizeof(acReadFileName)); sprintf(acReadFileName, "usbupgrad_%s.dt", pcDeviceName); if (nStorMode==1) { nRet = initMMCDevice(); if (nRet == FALSE) { printf("MMC upgrade initialize MMC failed.\n"); return FALSE; } } else { nRet = initUsbDevice(); if (nRet == FALSE) { printf("USB upgrade initialize USB failed.\n"); return FALSE; } } nRet = initFatFileSystem(); if (nRet == FALSE) { printf("USB upgrade initialize FAT filesystem failed.\n"); return FALSE; } nOldCtrlc = disable_ctrlc(0); nReadLength = 100*1024*1024; nRet = loadImageFromUsbToRam(acReadFileName, (void *)LOAD_RAM_ADDRESS, &nReadLength); if (nRet == FALSE) { printf("[doUsbUpgrade] loadImageFromUsbToRam upgrade usbupgrad.dt failed.\n"); return FALSE; } psPacketInfo = parsePacketInfo((const void *)LOAD_RAM_ADDRESS, nReadLength); if (psPacketInfo==NULL) { printf("[doUsbUpgrade] parsePacketInfo upgrade usbupgrad.dt failed.\n"); return FALSE; } nRet = writeImageFromRamToFlash(psPacketInfo, (void *)LOAD_RAM_ADDRESS, nReadLength); if (nRet == FALSE) { printf("[doUsbUpgrade] writeImageFromRamToFlash upgrade usbupgrad.dt (%p) failed.\n", (void *)LOAD_RAM_ADDRESS); free(psPacketInfo); return FALSE; } free(psPacketInfo); disable_ctrlc(nOldCtrlc); return 0; }
/* * 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 }