Esempio n. 1
0
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;
}
Esempio n. 2
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();
}
Esempio n. 3
0
File: console.c Progetto: aosp/uboot
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;
	}
Esempio n. 5
0
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;
}
Esempio n. 6
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
	}