image.c

来自「uboot详细解读可用启动引导LINUX2.6内核」· C语言 代码 · 共 2,365 行 · 第 1/5 页

C
2,365
字号
static void genimg_print_size (uint32_t size){#ifndef USE_HOSTCC	printf ("%d Bytes = ", size);	print_size (size, "\n");#else	printf ("%d Bytes = %.2f kB = %.2f MB\n",			size, (double)size / 1.024e3,			(double)size / 1.048576e6);#endif}#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)static void genimg_print_time (time_t timestamp){#ifndef USE_HOSTCC	struct rtc_time tm;	to_tm (timestamp, &tm);	printf ("%4d-%02d-%02d  %2d:%02d:%02d UTC\n",			tm.tm_year, tm.tm_mon, tm.tm_mday,			tm.tm_hour, tm.tm_min, tm.tm_sec);#else	printf ("%s", ctime(&timestamp));#endif}#endif /* CONFIG_TIMESTAMP || CONFIG_CMD_DATE || USE_HOSTCC *//** * get_table_entry_name - translate entry id to long name * @table: pointer to a translation table for entries of a specific type * @msg: message to be returned when translation fails * @id: entry id to be translated * * get_table_entry_name() will go over translation table trying to find * entry that matches given id. If matching entry is found, its long * name is returned to the caller. * * returns: *     long entry name if translation succeeds *     msg otherwise */static char *get_table_entry_name (table_entry_t *table, char *msg, int id){	for (; table->id >= 0; ++table) {		if (table->id == id)			return (table->lname);	}	return (msg);}const char *genimg_get_os_name (uint8_t os){	return (get_table_entry_name (uimage_os, "Unknown OS", os));}const char *genimg_get_arch_name (uint8_t arch){	return (get_table_entry_name (uimage_arch, "Unknown Architecture", arch));}const char *genimg_get_type_name (uint8_t type){	return (get_table_entry_name (uimage_type, "Unknown Image", type));}const char *genimg_get_comp_name (uint8_t comp){	return (get_table_entry_name (uimage_comp, "Unknown Compression", comp));}/** * get_table_entry_id - translate short entry name to id * @table: pointer to a translation table for entries of a specific type * @table_name: to be used in case of error * @name: entry short name to be translated * * get_table_entry_id() will go over translation table trying to find * entry that matches given short name. If matching entry is found, * its id returned to the caller. * * returns: *     entry id if translation succeeds *     -1 otherwise */static int get_table_entry_id (table_entry_t *table,		const char *table_name, const char *name){	table_entry_t *t;#ifdef USE_HOSTCC	int first = 1;	for (t = table; t->id >= 0; ++t) {		if (t->sname && strcasecmp(t->sname, name) == 0)			return (t->id);	}	fprintf (stderr, "\nInvalid %s Type - valid names are", table_name);	for (t = table; t->id >= 0; ++t) {		if (t->sname == NULL)			continue;		fprintf (stderr, "%c %s", (first) ? ':' : ',', t->sname);		first = 0;	}	fprintf (stderr, "\n");#else	for (t = table; t->id >= 0; ++t) {		if (t->sname && strcmp(t->sname, name) == 0)			return (t->id);	}	debug ("Invalid %s Type: %s\n", table_name, name);#endif /* USE_HOSTCC */	return (-1);}int genimg_get_os_id (const char *name){	return (get_table_entry_id (uimage_os, "OS", name));}int genimg_get_arch_id (const char *name){	return (get_table_entry_id (uimage_arch, "CPU", name));}int genimg_get_type_id (const char *name){	return (get_table_entry_id (uimage_type, "Image", name));}int genimg_get_comp_id (const char *name){	return (get_table_entry_id (uimage_comp, "Compression", name));}#ifndef USE_HOSTCC/** * genimg_get_format - get image format type * @img_addr: image start address * * genimg_get_format() checks whether provided address points to a valid * legacy or FIT image. * * New uImage format and FDT blob are based on a libfdt. FDT blob * may be passed directly or embedded in a FIT image. In both situations * genimg_get_format() must be able to dectect libfdt header. * * returns: *     image format type or IMAGE_FORMAT_INVALID if no image is present */int genimg_get_format (void *img_addr){	ulong		format = IMAGE_FORMAT_INVALID;	image_header_t	*hdr;#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)	char		*fit_hdr;#endif	hdr = (image_header_t *)img_addr;	if (image_check_magic(hdr))		format = IMAGE_FORMAT_LEGACY;#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)	else {		fit_hdr = (char *)img_addr;		if (fdt_check_header (fit_hdr) == 0)			format = IMAGE_FORMAT_FIT;	}#endif	return format;}/** * genimg_get_image - get image from special storage (if necessary) * @img_addr: image start address * * genimg_get_image() checks if provided image start adddress is located * in a dataflash storage. If so, image is moved to a system RAM memory. * * returns: *     image start address after possible relocation from special storage */ulong genimg_get_image (ulong img_addr){	ulong ram_addr = img_addr;#ifdef CONFIG_HAS_DATAFLASH	ulong h_size, d_size;	if (addr_dataflash (img_addr)){		/* ger RAM address */		ram_addr = CFG_LOAD_ADDR;		/* get header size */		h_size = image_get_header_size ();#if defined(CONFIG_FIT)		if (sizeof(struct fdt_header) > h_size)			h_size = sizeof(struct fdt_header);#endif		/* read in header */		debug ("   Reading image header from dataflash address "			"%08lx to RAM address %08lx\n", img_addr, ram_addr);		read_dataflash (img_addr, h_size, (char *)ram_addr);		/* get data size */		switch (genimg_get_format ((void *)ram_addr)) {		case IMAGE_FORMAT_LEGACY:			d_size = image_get_data_size ((image_header_t *)ram_addr);			debug ("   Legacy format image found at 0x%08lx, size 0x%08lx\n",					ram_addr, d_size);			break;#if defined(CONFIG_FIT)		case IMAGE_FORMAT_FIT:			d_size = fit_get_size ((const void *)ram_addr) - h_size;			debug ("   FIT/FDT format image found at 0x%08lx, size 0x%08lx\n",					ram_addr, d_size);			break;#endif		default:			printf ("   No valid image found at 0x%08lx\n", img_addr);			return ram_addr;		}		/* read in image data */		debug ("   Reading image remaining data from dataflash address "			"%08lx to RAM address %08lx\n", img_addr + h_size,			ram_addr + h_size);		read_dataflash (img_addr + h_size, d_size,				(char *)(ram_addr + h_size));	}#endif /* CONFIG_HAS_DATAFLASH */	return ram_addr;}/** * fit_has_config - check if there is a valid FIT configuration * @images: pointer to the bootm command headers structure * * fit_has_config() checks if there is a FIT configuration in use * (if FTI support is present). * * returns: *     0, no FIT support or no configuration found *     1, configuration found */int genimg_has_config (bootm_headers_t *images){#if defined(CONFIG_FIT)	if (images->fit_uname_cfg)		return 1;#endif	return 0;}/** * boot_get_ramdisk - main ramdisk handling routine * @argc: command argument count * @argv: command argument list * @images: pointer to the bootm images structure * @arch: expected ramdisk architecture * @rd_start: pointer to a ulong variable, will hold ramdisk start address * @rd_end: pointer to a ulong variable, will hold ramdisk end * * boot_get_ramdisk() is responsible for finding a valid ramdisk image. * Curently supported are the following ramdisk sources: *      - multicomponent kernel/ramdisk image, *      - commandline provided address of decicated ramdisk image. * * returns: *     0, if ramdisk image was found and valid, or skiped *     rd_start and rd_end are set to ramdisk start/end addresses if *     ramdisk image is found and valid * *     1, if ramdisk image is found but corrupted *     rd_start and rd_end are set to 0 if no ramdisk exists */int boot_get_ramdisk (int argc, char *argv[], bootm_headers_t *images,		uint8_t arch, ulong *rd_start, ulong *rd_end){	ulong rd_addr, rd_load;	ulong rd_data, rd_len;	image_header_t *rd_hdr;#if defined(CONFIG_FIT)	void		*fit_hdr;	const char	*fit_uname_config = NULL;	const char	*fit_uname_ramdisk = NULL;	ulong		default_addr;	int		rd_noffset;	int		cfg_noffset;	const void	*data;	size_t		size;#endif	*rd_start = 0;	*rd_end = 0;	/*	 * Look for a '-' which indicates to ignore the	 * ramdisk argument	 */	if ((argc >= 3) && (strcmp(argv[2], "-") ==  0)) {		debug ("## Skipping init Ramdisk\n");		rd_len = rd_data = 0;	} else if (argc >= 3 || genimg_has_config (images)) {#if defined(CONFIG_FIT)		if (argc >= 3) {			/*			 * If the init ramdisk comes from the FIT image and			 * the FIT image address is omitted in the command			 * line argument, try to use os FIT image address or			 * default load address.			 */			if (images->fit_uname_os)				default_addr = (ulong)images->fit_hdr_os;			else				default_addr = load_addr;			if (fit_parse_conf (argv[2], default_addr,						&rd_addr, &fit_uname_config)) {				debug ("*  ramdisk: config '%s' from image at 0x%08lx\n",						fit_uname_config, rd_addr);			} else if (fit_parse_subimage (argv[2], default_addr,						&rd_addr, &fit_uname_ramdisk)) {				debug ("*  ramdisk: subimage '%s' from image at 0x%08lx\n",						fit_uname_ramdisk, rd_addr);			} else#endif			{				rd_addr = simple_strtoul(argv[2], NULL, 16);				debug ("*  ramdisk: cmdline image address = 0x%08lx\n",						rd_addr);			}#if defined(CONFIG_FIT)		} else {			/* use FIT configuration provided in first bootm			 * command argument			 */			rd_addr = (ulong)images->fit_hdr_os;			fit_uname_config = images->fit_uname_cfg;			debug ("*  ramdisk: using config '%s' from image at 0x%08lx\n",					fit_uname_config, rd_addr);			/*			 * Check whether configuration has ramdisk defined,			 * if not, don't try to use it, quit silently.			 */			fit_hdr = (void *)rd_addr;			cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);			if (cfg_noffset < 0) {				debug ("*  ramdisk: no such config\n");				return 1;			}			rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);			if (rd_noffset < 0) {				debug ("*  ramdisk: no ramdisk in config\n");				return 0;			}		}#endif		/* copy from dataflash if needed */		rd_addr = genimg_get_image (rd_addr);		/*		 * Check if there is an initrd image at the		 * address provided in the second bootm argument		 * check image type, for FIT images get FIT node.		 */		switch (genimg_get_format ((void *)rd_addr)) {		case IMAGE_FORMAT_LEGACY:			printf ("## Loading init Ramdisk from Legacy "					"Image at %08lx ...\n", rd_addr);			show_boot_progress (9);			rd_hdr = image_get_ramdisk (rd_addr, arch,							images->verify);			if (rd_hdr == NULL)				return 1;			rd_data = image_get_data (rd_hdr);			rd_len = image_get_data_size (rd_hdr);			rd_load = image_get_load (rd_hdr);			break;#if defined(CONFIG_FIT)		case IMAGE_FORMAT_FIT:			fit_hdr = (void *)rd_addr;			printf ("## Loading init Ramdisk from FIT "					"Image at %08lx ...\n", rd_addr);			show_boot_progress (120);			if (!fit_check_format (fit_hdr)) {				puts ("Bad FIT ramdisk image format!\n");				show_boot_progress (-120);				return 1;			}			show_boot_progress (121);			if (!fit_uname_ramdisk) {				/*				 * no ramdisk image node unit name, try to get config				 * node first. If config unit node name is NULL				 * fit_conf_get_node() will try to find default config node				 */				show_boot_progress (122);				cfg_noffset = fit_conf_get_node (fit_hdr, fit_uname_config);				if (cfg_noffset < 0) {					puts ("Could not find configuration node\n");					show_boot_progress (-122);					return 1;				}				fit_uname_config = fdt_get_name (fit_hdr, cfg_noffset, NULL);				printf ("   Using '%s' configuration\n", fit_uname_config);				rd_noffset = fit_conf_get_ramdisk_node (fit_hdr, cfg_noffset);				fit_uname_ramdisk = fit_get_name (fit_hdr, rd_noffset, NULL);			} else {				/* get ramdisk component image node offset */				show_boot_progress (123);				rd_noffset = fit_image_get_node (fit_hdr, fit_uname_ramdisk);			}			if (rd_noffset < 0) {				puts ("Could not find subimage node\n");				show_boot_progress (-124);				return 1;			}			printf ("   Trying '%s' ramdisk subimage\n", fit_uname_ramdisk);			show_boot_progress (125);			if (!fit_check_ramdisk (fit_hdr, rd_noffset, arch, images->verify))				return 1;			/* get ramdisk image data address and length */			if (fit_image_get_data (fit_hdr, rd_noffset, &data, &size)) {				puts ("Could not find ramdisk subimage data!\n");				show_boot_progress (-127);				return 1;			}			show_boot_progress (128);			rd_data = (ulong)data;			rd_len = size;			if (fit_image_get_load (fit_hdr, rd_noffset, &rd_load)) {				puts ("Can't get ramdisk subimage load address!\n");				show_boot_progress (-129);				return 1;			}			show_boot_progress (129);			images->fit_hdr_rd = fit_hdr;			images->fit_uname_rd = fit_uname_ramdisk;			images->fit_noffset_rd = rd_noffset;			break;#endif		default:			puts ("Wrong Ramdisk Image Format\n");			rd_data = rd_len = rd_load = 0;		}#if defined(CONFIG_B2) || defined(CONFIG_EVB4510) || defined(CONFIG_ARMADILLO)		/*		 * We need to copy the ramdisk to SRAM to let Linux boot		 */		if (rd_data) {			memmove ((void *)rd_load, (uchar *)rd_data, rd_len);

⌨️ 快捷键说明

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