image.c

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

C
2,365
字号
			rd_data = rd_load;		}#endif /* CONFIG_B2 || CONFIG_EVB4510 || CONFIG_ARMADILLO */	} else if (images->legacy_hdr_valid &&			image_check_type (&images->legacy_hdr_os_copy, IH_TYPE_MULTI)) {		/*		 * Now check if we have a legacy mult-component image,		 * get second entry data start address and len.		 */		show_boot_progress (13);		printf ("## Loading init Ramdisk from multi component "				"Legacy Image at %08lx ...\n",				(ulong)images->legacy_hdr_os);		image_multi_getimg (images->legacy_hdr_os, 1, &rd_data, &rd_len);	} else {		/*		 * no initrd image		 */		show_boot_progress (14);		rd_len = rd_data = 0;	}	if (!rd_data) {		debug ("## No init Ramdisk\n");	} else {		*rd_start = rd_data;		*rd_end = rd_data + rd_len;	}	debug ("   ramdisk start = 0x%08lx, ramdisk end = 0x%08lx\n",			*rd_start, *rd_end);	return 0;}#if defined(CONFIG_PPC) || defined(CONFIG_M68K) || defined(CONFIG_SPARC)/** * boot_ramdisk_high - relocate init ramdisk * @lmb: pointer to lmb handle, will be used for memory mgmt * @rd_data: ramdisk data start address * @rd_len: ramdisk data length * @initrd_start: pointer to a ulong variable, will hold final init ramdisk *      start address (after possible relocation) * @initrd_end: pointer to a ulong variable, will hold final init ramdisk *      end address (after possible relocation) * * boot_ramdisk_high() takes a relocation hint from "initrd_high" environement * variable and if requested ramdisk data is moved to a specified location. * * Initrd_start and initrd_end are set to final (after relocation) ramdisk * start/end addresses if ramdisk image start and len were provided, * otherwise set initrd_start and initrd_end set to zeros. * * returns: *      0 - success *     -1 - failure */int boot_ramdisk_high (struct lmb *lmb, ulong rd_data, ulong rd_len,		  ulong *initrd_start, ulong *initrd_end){	char	*s;	ulong	initrd_high;	int	initrd_copy_to_ram = 1;	if ((s = getenv ("initrd_high")) != NULL) {		/* a value of "no" or a similar string will act like 0,		 * turning the "load high" feature off. This is intentional.		 */		initrd_high = simple_strtoul (s, NULL, 16);		if (initrd_high == ~0)			initrd_copy_to_ram = 0;	} else {		/* not set, no restrictions to load high */		initrd_high = ~0;	}#ifdef CONFIG_LOGBUFFER	/* Prevent initrd from overwriting logbuffer */	lmb_reserve(lmb, logbuffer_base() - LOGBUFF_OVERHEAD, LOGBUFF_RESERVE);#endif	debug ("## initrd_high = 0x%08lx, copy_to_ram = %d\n",			initrd_high, initrd_copy_to_ram);	if (rd_data) {		if (!initrd_copy_to_ram) {	/* zero-copy ramdisk support */			debug ("   in-place initrd\n");			*initrd_start = rd_data;			*initrd_end = rd_data + rd_len;			lmb_reserve(lmb, rd_data, rd_len);		} else {			if (initrd_high)				*initrd_start = (ulong)lmb_alloc_base (lmb, rd_len, 0x1000, initrd_high);			else				*initrd_start = (ulong)lmb_alloc (lmb, rd_len, 0x1000);			if (*initrd_start == 0) {				puts ("ramdisk - allocation error\n");				goto error;			}			show_boot_progress (12);			*initrd_end = *initrd_start + rd_len;			printf ("   Loading Ramdisk to %08lx, end %08lx ... ",					*initrd_start, *initrd_end);			memmove_wd ((void *)*initrd_start,					(void *)rd_data, rd_len, CHUNKSZ);			puts ("OK\n");		}	} else {		*initrd_start = 0;		*initrd_end = 0;	}	debug ("   ramdisk load start = 0x%08lx, ramdisk load end = 0x%08lx\n",			*initrd_start, *initrd_end);	return 0;error:	return -1;}/** * boot_get_cmdline - allocate and initialize kernel cmdline * @lmb: pointer to lmb handle, will be used for memory mgmt * @cmd_start: pointer to a ulong variable, will hold cmdline start * @cmd_end: pointer to a ulong variable, will hold cmdline end * @bootmap_base: ulong variable, holds offset in physical memory to * base of bootmap * * boot_get_cmdline() allocates space for kernel command line below * BOOTMAPSZ + bootmap_base address. If "bootargs" U-boot environemnt * variable is present its contents is copied to allocated kernel * command line. * * returns: *      0 - success *     -1 - failure */int boot_get_cmdline (struct lmb *lmb, ulong *cmd_start, ulong *cmd_end,			ulong bootmap_base){	char *cmdline;	char *s;	cmdline = (char *)(ulong)lmb_alloc_base(lmb, CFG_BARGSIZE, 0xf,					 CFG_BOOTMAPSZ + bootmap_base);	if (cmdline == NULL)		return -1;	if ((s = getenv("bootargs")) == NULL)		s = "";	strcpy(cmdline, s);	*cmd_start = (ulong) & cmdline[0];	*cmd_end = *cmd_start + strlen(cmdline);	debug ("## cmdline at 0x%08lx ... 0x%08lx\n", *cmd_start, *cmd_end);	return 0;}/** * boot_get_kbd - allocate and initialize kernel copy of board info * @lmb: pointer to lmb handle, will be used for memory mgmt * @kbd: double pointer to board info data * @bootmap_base: ulong variable, holds offset in physical memory to * base of bootmap * * boot_get_kbd() allocates space for kernel copy of board info data below * BOOTMAPSZ + bootmap_base address and kernel board info is initialized with * the current u-boot board info data. * * returns: *      0 - success *     -1 - failure */int boot_get_kbd (struct lmb *lmb, bd_t **kbd, ulong bootmap_base){	*kbd = (bd_t *)(ulong)lmb_alloc_base(lmb, sizeof(bd_t), 0xf,				      CFG_BOOTMAPSZ + bootmap_base);	if (*kbd == NULL)		return -1;	**kbd = *(gd->bd);	debug ("## kernel board info at 0x%08lx\n", (ulong)*kbd);#if defined(DEBUG) && defined(CONFIG_CMD_BDI)	do_bdinfo(NULL, 0, 0, NULL);#endif	return 0;}#endif /* CONFIG_PPC || CONFIG_M68K */#endif /* !USE_HOSTCC */#if defined(CONFIG_FIT)/*****************************************************************************//* New uImage format routines *//*****************************************************************************/#ifndef USE_HOSTCCstatic int fit_parse_spec (const char *spec, char sepc, ulong addr_curr,		ulong *addr, const char **name){	const char *sep;	*addr = addr_curr;	*name = NULL;	sep = strchr (spec, sepc);	if (sep) {		if (sep - spec > 0)			*addr = simple_strtoul (spec, NULL, 16);		*name = sep + 1;		return 1;	}	return 0;}/** * fit_parse_conf - parse FIT configuration spec * @spec: input string, containing configuration spec * @add_curr: current image address (to be used as a possible default) * @addr: pointer to a ulong variable, will hold FIT image address of a given * configuration * @conf_name double pointer to a char, will hold pointer to a configuration * unit name * * fit_parse_conf() expects configuration spec in the for of [<addr>]#<conf>, * where <addr> is a FIT image address that contains configuration * with a <conf> unit name. * * Address part is optional, and if omitted default add_curr will * be used instead. * * returns: *     1 if spec is a valid configuration string, *     addr and conf_name are set accordingly *     0 otherwise */inline int fit_parse_conf (const char *spec, ulong addr_curr,		ulong *addr, const char **conf_name){	return fit_parse_spec (spec, '#', addr_curr, addr, conf_name);}/** * fit_parse_subimage - parse FIT subimage spec * @spec: input string, containing subimage spec * @add_curr: current image address (to be used as a possible default) * @addr: pointer to a ulong variable, will hold FIT image address of a given * subimage * @image_name: double pointer to a char, will hold pointer to a subimage name * * fit_parse_subimage() expects subimage spec in the for of * [<addr>]:<subimage>, where <addr> is a FIT image address that contains * subimage with a <subimg> unit name. * * Address part is optional, and if omitted default add_curr will * be used instead. * * returns: *     1 if spec is a valid subimage string, *     addr and image_name are set accordingly *     0 otherwise */inline int fit_parse_subimage (const char *spec, ulong addr_curr,		ulong *addr, const char **image_name){	return fit_parse_spec (spec, ':', addr_curr, addr, image_name);}#endif /* !USE_HOSTCC */static void fit_get_debug (const void *fit, int noffset,		char *prop_name, int err){	debug ("Can't get '%s' property from FIT 0x%08lx, "		"node: offset %d, name %s (%s)\n",		prop_name, (ulong)fit, noffset,		fit_get_name (fit, noffset, NULL),		fdt_strerror (err));}/** * fit_print_contents - prints out the contents of the FIT format image * @fit: pointer to the FIT format image header * @p: pointer to prefix string * * fit_print_contents() formats a multi line FIT image contents description. * The routine prints out FIT image properties (root node level) follwed by * the details of each component image. * * returns: *     no returned results */void fit_print_contents (const void *fit){	char *desc;	char *uname;	int images_noffset;	int confs_noffset;	int noffset;	int ndepth;	int count = 0;	int ret;	const char *p;#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)	time_t timestamp;#endif#ifdef USE_HOSTCC	p = "";#else	p = "   ";#endif	/* Root node properties */	ret = fit_get_desc (fit, 0, &desc);	printf ("%sFIT description: ", p);	if (ret)		printf ("unavailable\n");	else		printf ("%s\n", desc);#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)	ret = fit_get_timestamp (fit, 0, &timestamp);	printf ("%sCreated:         ", p);	if (ret)		printf ("unavailable\n");	else		genimg_print_time (timestamp);#endif	/* Find images parent node offset */	images_noffset = fdt_path_offset (fit, FIT_IMAGES_PATH);	if (images_noffset < 0) {		printf ("Can't find images parent node '%s' (%s)\n",			FIT_IMAGES_PATH, fdt_strerror (images_noffset));		return;	}	/* Process its subnodes, print out component images details */	for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, images_noffset, &ndepth);	     (noffset >= 0) && (ndepth > 0);	     noffset = fdt_next_node (fit, noffset, &ndepth)) {		if (ndepth == 1) {			/*			 * Direct child node of the images parent node,			 * i.e. component image node.			 */			printf ("%s Image %u (%s)\n", p, count++,					fit_get_name(fit, noffset, NULL));			fit_image_print (fit, noffset, p);		}	}	/* Find configurations parent node offset */	confs_noffset = fdt_path_offset (fit, FIT_CONFS_PATH);	if (confs_noffset < 0) {		debug ("Can't get configurations parent node '%s' (%s)\n",			FIT_CONFS_PATH, fdt_strerror (confs_noffset));		return;	}	/* get default configuration unit name from default property */	uname = (char *)fdt_getprop (fit, noffset, FIT_DEFAULT_PROP, NULL);	if (uname)		printf ("%s Default Configuration: '%s'\n", p, uname);	/* Process its subnodes, print out configurations details */	for (ndepth = 0, count = 0, noffset = fdt_next_node (fit, confs_noffset, &ndepth);	     (noffset >= 0) && (ndepth > 0);	     noffset = fdt_next_node (fit, noffset, &ndepth)) {		if (ndepth == 1) {			/*			 * Direct child node of the configurations parent node,			 * i.e. configuration node.			 */			printf ("%s Configuration %u (%s)\n", p, count++,					fit_get_name(fit, noffset, NULL));			fit_conf_print (fit, noffset, p);		}	}}/** * fit_image_print - prints out the FIT component image details * @fit: pointer to the FIT format image header * @image_noffset: offset of the component image node * @p: pointer to prefix string * * fit_image_print() lists all mandatory properies for the processed component * image. If present, hash nodes are printed out as well. * * returns: *     no returned results */void fit_image_print (const void *fit, int image_noffset, const char *p){	char *desc;	uint8_t type, arch, os, comp;	size_t size;	ulong load, entry;	const void *data;	int noffset;	int ndepth;	int ret;	/* Mandatory properties */	ret = fit_get_desc (fit, image_noffset, &desc);	printf ("%s  Description:  ", p);	if (ret)		printf ("unavailable\n");	else		printf ("%s\n", desc);	fit_image_get_type (fit, image_noffset, &type);	printf ("%s  Type:         %s\n", p, genimg_get_type_name (type));	fit_image_get_comp (fit, image_noffset, &comp);	printf ("%s  Compression:  %s\n", p, genimg_get_comp_name (comp));	ret = fit_image_get_data (fit, image_noffset, &data, &size);#ifndef USE_HOSTCC	printf ("%s  Data Start:   ", p);	if (ret)		printf ("unavailable\n");	else		printf ("0x%08lx\n", (ulong)data);#endif	printf ("%s  Data Size:    ", p);	if (ret)		printf ("unavailable\n");	else		genimg_print_size (size);	/* Remaining, type dependent properties */	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE) ||	    (type == IH_TYPE_RAMDISK) || (type == IH_TYPE_FIRMWARE) ||	    (type == IH_TYPE_FLATDT)) {		fit_image_get_arch (fit, image_noffset, &arch);		printf ("%s  Architecture: %s\n", p, genimg_get_arch_name (arch));	}	if (type == IH_TYPE_KERNEL) {		fit_image_get_os (fit, image_noffset, &os);		printf ("%s  OS:           %s\n", p, genimg_get_os_name (os));	}	if ((type == IH_TYPE_KERNEL) || (type == IH_TYPE_STANDALONE)) {		ret = fit_image_get_load (fit, image_noffset, &load);		printf ("%s  Load Address: ", p);		if (ret)			printf ("unavailable\n");		else			printf ("0x%08lx\n", load);		fit_image_get_entry (fit, image_noffset, &entry);		printf ("%s  Entry Point:  ", p);		if (ret)

⌨️ 快捷键说明

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