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

📄 auto_update.c

📁 嵌入式试验箱S3C2410的bootloader源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
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;	/* disable the power switch */	*CPLD_VFD_BK |= POWER_OFF;	/* execute a script */	if (hdr->ih_type == IH_TYPE_SCRIPT) {		addr = (char *)((char *)hdr + sizeof(*hdr));		/* stick a NULL at the end of the script, otherwise */		/* parse_string_outer() runs off the end. */		addr[ntohl(hdr->ih_size)] = 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 (hdr->ih_type == IH_TYPE_KERNEL || hdr->ih_type == IH_TYPE_RAMDISK) {		addr = (char *)hdr;		off = sizeof(*hdr);		nbytes = sizeof(*hdr) + ntohl(hdr->ih_size);	} else {		addr = (char *)((char *)hdr + sizeof(*hdr));#ifdef AU_UPDATE_TEST		/* copy it to where Linux goes */		if (idx == IDX_FIRMWARE)			start = aufl_layout[1].start;#endif		off = 0;		nbytes = ntohl(hdr->ih_size);	}	/* 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), ntohl(hdr->ih_size)) != ntohl(hdr->ih_dcrc)) {		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;}intau_update_eeprom(int idx){	image_header_t *hdr;	int off;	uint32_t val;	/* special case for prepare.img */	if (idx == IDX_PREPARE) {		/* enable the power switch */		*CPLD_VFD_BK &= ~POWER_OFF;		return 0;	}	hdr = (image_header_t *)LOAD_ADDR;	/* write the time field into EEPROM */	off = auee_off[idx].time;	val = ntohl(hdr->ih_time);	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));	/* write the size field into EEPROM */	off = auee_off[idx].size;	val = ntohl(hdr->ih_size);	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));	/* write the dcrc field into EEPROM */	off = auee_off[idx].dcrc;	val = ntohl(hdr->ih_dcrc);	i2c_write_multiple(0x54, off, 1, &val, sizeof(val));	/* enable the power switch */	*CPLD_VFD_BK &= ~POWER_OFF;	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. */intdo_auto_update(void){	block_dev_desc_t *stor_dev;	long sz;	int i, res, 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");		return -1;	}	/* check whether it has a partition table */	stor_dev = get_dev("usb", 0);	if (stor_dev == NULL) {		debug ("uknown device type\n");		return -1;	}	if (fat_register_device(stor_dev, 1) != 0) {		debug ("Unable to use USB %d:%d for fatls\n",			au_usb_stor_curr_dev, 1);		return -1;	}	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, sizeof(image_header_t));		debug ("read %s sz %ld hdr %d\n",			aufile[i], sz, sizeof(image_header_t));		if (sz <= 0 || sz < sizeof(image_header_t)) {			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, sizeof(image_header_t));		if (sz <= 0 || sz <= sizeof(image_header_t)) {			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;	}	usb_stop();	/* restore the old state */	disable_ctrlc(old_ctrlc);	return 0;}#endif /* CONFIG_AUTO_UPDATE */

⌨️ 快捷键说明

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