欢迎来到虫虫下载站 | 资源下载 资源专辑 关于我们
虫虫下载站

image.c

uboot详细解读可用启动引导LINUX2.6内核
C
第 1 页 / 共 5 页
字号:
/* * (C) Copyright 2008 Semihalf * * (C) Copyright 2000-2006 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. * * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA */#ifndef USE_HOSTCC#include <common.h>#include <watchdog.h>#ifdef CONFIG_SHOW_BOOT_PROGRESS#include <status_led.h>#endif#ifdef CONFIG_HAS_DATAFLASH#include <dataflash.h>#endif#ifdef CONFIG_LOGBUFFER#include <logbuff.h>#endif#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE)#include <rtc.h>#endif#include <image.h>#if defined(CONFIG_FIT) || defined (CONFIG_OF_LIBFDT)#include <fdt.h>#include <libfdt.h>#include <fdt_support.h>#endif#if defined(CONFIG_FIT)#include <u-boot/md5.h>#include <sha1.h>static int fit_check_ramdisk (const void *fit, int os_noffset,		uint8_t arch, int verify);#endif#ifdef CONFIG_CMD_BDIextern int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);#endifDECLARE_GLOBAL_DATA_PTR;static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,						int verify);#else#include "mkimage.h"#include <u-boot/md5.h>#include <time.h>#include <image.h>#endif /* !USE_HOSTCC*/typedef struct table_entry {	int	id;		/* as defined in image.h	*/	char	*sname;		/* short (input) name		*/	char	*lname;		/* long (output) name		*/} table_entry_t;static table_entry_t uimage_arch[] = {	{	IH_ARCH_INVALID,	NULL,		"Invalid ARCH",	},	{	IH_ARCH_ALPHA,		"alpha",	"Alpha",	},	{	IH_ARCH_ARM,		"arm",		"ARM",		},	{	IH_ARCH_I386,		"x86",		"Intel x86",	},	{	IH_ARCH_IA64,		"ia64",		"IA64",		},	{	IH_ARCH_M68K,		"m68k",		"M68K",		},	{	IH_ARCH_MICROBLAZE,	"microblaze",	"MicroBlaze",	},	{	IH_ARCH_MIPS,		"mips",		"MIPS",		},	{	IH_ARCH_MIPS64,		"mips64",	"MIPS 64 Bit",	},	{	IH_ARCH_NIOS,		"nios",		"NIOS",		},	{	IH_ARCH_NIOS2,		"nios2",	"NIOS II",	},	{	IH_ARCH_PPC,		"powerpc",	"PowerPC",	},	{	IH_ARCH_PPC,		"ppc",		"PowerPC",	},	{	IH_ARCH_S390,		"s390",		"IBM S390",	},	{	IH_ARCH_SH,		"sh",		"SuperH",	},	{	IH_ARCH_SPARC,		"sparc",	"SPARC",	},	{	IH_ARCH_SPARC64,	"sparc64",	"SPARC 64 Bit",	},	{	IH_ARCH_BLACKFIN,	"blackfin",	"Blackfin",	},	{	IH_ARCH_AVR32,		"avr32",	"AVR32",	},	{	-1,			"",		"",		},};static table_entry_t uimage_os[] = {	{	IH_OS_INVALID,	NULL,		"Invalid OS",		},#if defined(CONFIG_ARTOS) || defined(USE_HOSTCC)	{	IH_OS_ARTOS,	"artos",	"ARTOS",		},#endif	{	IH_OS_LINUX,	"linux",	"Linux",		},#if defined(CONFIG_LYNXKDI) || defined(USE_HOSTCC)	{	IH_OS_LYNXOS,	"lynxos",	"LynxOS",		},#endif	{	IH_OS_NETBSD,	"netbsd",	"NetBSD",		},	{	IH_OS_RTEMS,	"rtems",	"RTEMS",		},	{	IH_OS_U_BOOT,	"u-boot",	"U-Boot",		},#if defined(CONFIG_CMD_ELF) || defined(USE_HOSTCC)	{	IH_OS_QNX,	"qnx",		"QNX",			},	{	IH_OS_VXWORKS,	"vxworks",	"VxWorks",		},#endif#ifdef USE_HOSTCC	{	IH_OS_4_4BSD,	"4_4bsd",	"4_4BSD",		},	{	IH_OS_DELL,	"dell",		"Dell",			},	{	IH_OS_ESIX,	"esix",		"Esix",			},	{	IH_OS_FREEBSD,	"freebsd",	"FreeBSD",		},	{	IH_OS_IRIX,	"irix",		"Irix",			},	{	IH_OS_NCR,	"ncr",		"NCR",			},	{	IH_OS_OPENBSD,	"openbsd",	"OpenBSD",		},	{	IH_OS_PSOS,	"psos",		"pSOS",			},	{	IH_OS_SCO,	"sco",		"SCO",			},	{	IH_OS_SOLARIS,	"solaris",	"Solaris",		},	{	IH_OS_SVR4,	"svr4",		"SVR4",			},#endif	{	-1,		"",		"",			},};static table_entry_t uimage_type[] = {	{	IH_TYPE_INVALID,    NULL,	  "Invalid Image",	},	{	IH_TYPE_FILESYSTEM, "filesystem", "Filesystem Image",	},	{	IH_TYPE_FIRMWARE,   "firmware",	  "Firmware",		},	{	IH_TYPE_KERNEL,	    "kernel",	  "Kernel Image",	},	{	IH_TYPE_MULTI,	    "multi",	  "Multi-File Image",	},	{	IH_TYPE_RAMDISK,    "ramdisk",	  "RAMDisk Image",	},	{	IH_TYPE_SCRIPT,     "script",	  "Script",		},	{	IH_TYPE_STANDALONE, "standalone", "Standalone Program", },	{	IH_TYPE_FLATDT,     "flat_dt",    "Flat Device Tree",	},	{	-1,		    "",		  "",			},};static table_entry_t uimage_comp[] = {	{	IH_COMP_NONE,	"none",		"uncompressed",		},	{	IH_COMP_BZIP2,	"bzip2",	"bzip2 compressed",	},	{	IH_COMP_GZIP,	"gzip",		"gzip compressed",	},	{	-1,		"",		"",			},};uint32_t crc32 (uint32_t, const unsigned char *, uint);uint32_t crc32_wd (uint32_t, const unsigned char *, uint, uint);static void genimg_print_size (uint32_t size);#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)static void genimg_print_time (time_t timestamp);#endif/*****************************************************************************//* Legacy format routines *//*****************************************************************************/int image_check_hcrc (image_header_t *hdr){	ulong hcrc;	ulong len = image_get_header_size ();	image_header_t header;	/* Copy header so we can blank CRC field for re-calculation */	memmove (&header, (char *)hdr, image_get_header_size ());	image_set_hcrc (&header, 0);	hcrc = crc32 (0, (unsigned char *)&header, len);	return (hcrc == image_get_hcrc (hdr));}int image_check_dcrc (image_header_t *hdr){	ulong data = image_get_data (hdr);	ulong len = image_get_data_size (hdr);	ulong dcrc = crc32_wd (0, (unsigned char *)data, len, CHUNKSZ_CRC32);	return (dcrc == image_get_dcrc (hdr));}/** * image_multi_count - get component (sub-image) count * @hdr: pointer to the header of the multi component image * * image_multi_count() returns number of components in a multi * component image. * * Note: no checking of the image type is done, caller must pass * a valid multi component image. * * returns: *     number of components */ulong image_multi_count (image_header_t *hdr){	ulong i, count = 0;	uint32_t *size;	/* get start of the image payload, which in case of multi	 * component images that points to a table of component sizes */	size = (uint32_t *)image_get_data (hdr);	/* count non empty slots */	for (i = 0; size[i]; ++i)		count++;	return count;}/** * image_multi_getimg - get component data address and size * @hdr: pointer to the header of the multi component image * @idx: index of the requested component * @data: pointer to a ulong variable, will hold component data address * @len: pointer to a ulong variable, will hold component size * * image_multi_getimg() returns size and data address for the requested * component in a multi component image. * * Note: no checking of the image type is done, caller must pass * a valid multi component image. * * returns: *     data address and size of the component, if idx is valid *     0 in data and len, if idx is out of range */void image_multi_getimg (image_header_t *hdr, ulong idx,			ulong *data, ulong *len){	int i;	uint32_t *size;	ulong offset, count, img_data;	/* get number of component */	count = image_multi_count (hdr);	/* get start of the image payload, which in case of multi	 * component images that points to a table of component sizes */	size = (uint32_t *)image_get_data (hdr);	/* get address of the proper component data start, which means	 * skipping sizes table (add 1 for last, null entry) */	img_data = image_get_data (hdr) + (count + 1) * sizeof (uint32_t);	if (idx < count) {		*len = uimage_to_cpu (size[idx]);		offset = 0;		/* go over all indices preceding requested component idx */		for (i = 0; i < idx; i++) {			/* add up i-th component size, rounding up to 4 bytes */			offset += (uimage_to_cpu (size[i]) + 3) & ~3 ;		}		/* calculate idx-th component data address */		*data = img_data + offset;	} else {		*len = 0;		*data = 0;	}}static void image_print_type (image_header_t *hdr){	const char *os, *arch, *type, *comp;	os = genimg_get_os_name (image_get_os (hdr));	arch = genimg_get_arch_name (image_get_arch (hdr));	type = genimg_get_type_name (image_get_type (hdr));	comp = genimg_get_comp_name (image_get_comp (hdr));	printf ("%s %s %s (%s)\n", arch, os, type, comp);}/** * image_print_contents - prints out the contents of the legacy format image * @hdr: pointer to the legacy format image header * @p: pointer to prefix string * * image_print_contents() formats a multi line legacy image contents description. * The routine prints out all header fields followed by the size/offset data * for MULTI/SCRIPT images. * * returns: *     no returned results */void image_print_contents (image_header_t *hdr){	const char *p;#ifdef USE_HOSTCC	p = "";#else	p = "   ";#endif	printf ("%sImage Name:   %.*s\n", p, IH_NMLEN, image_get_name (hdr));#if defined(CONFIG_TIMESTAMP) || defined(CONFIG_CMD_DATE) || defined(USE_HOSTCC)	printf ("%sCreated:      ", p);	genimg_print_time ((time_t)image_get_time (hdr));#endif	printf ("%sImage Type:   ", p);	image_print_type (hdr);	printf ("%sData Size:    ", p);	genimg_print_size (image_get_data_size (hdr));	printf ("%sLoad Address: %08x\n", p, image_get_load (hdr));	printf ("%sEntry Point:  %08x\n", p, image_get_ep (hdr));	if (image_check_type (hdr, IH_TYPE_MULTI) ||			image_check_type (hdr, IH_TYPE_SCRIPT)) {		int i;		ulong data, len;		ulong count = image_multi_count (hdr);		printf ("%sContents:\n", p);		for (i = 0; i < count; i++) {			image_multi_getimg (hdr, i, &data, &len);			printf ("%s   Image %d: ", p, i);			genimg_print_size (len);			if (image_check_type (hdr, IH_TYPE_SCRIPT) && i > 0) {				/*				 * the user may need to know offsets				 * if planning to do something with				 * multiple files				 */				printf ("%s    Offset = 0x%08lx\n", p, data);			}		}	}}#ifndef USE_HOSTCC/** * image_get_ramdisk - get and verify ramdisk image * @rd_addr: ramdisk image start address * @arch: expected ramdisk architecture * @verify: checksum verification flag * * image_get_ramdisk() returns a pointer to the verified ramdisk image * header. Routine receives image start address and expected architecture * flag. Verification done covers data and header integrity and os/type/arch * fields checking. * * If dataflash support is enabled routine checks for dataflash addresses * and handles required dataflash reads. * * returns: *     pointer to a ramdisk image header, if image was found and valid *     otherwise, return NULL */static image_header_t* image_get_ramdisk (ulong rd_addr, uint8_t arch,						int verify){	image_header_t *rd_hdr = (image_header_t *)rd_addr;	if (!image_check_magic (rd_hdr)) {		puts ("Bad Magic Number\n");		show_boot_progress (-10);		return NULL;	}	if (!image_check_hcrc (rd_hdr)) {		puts ("Bad Header Checksum\n");		show_boot_progress (-11);		return NULL;	}	show_boot_progress (10);	image_print_contents (rd_hdr);	if (verify) {		puts("   Verifying Checksum ... ");		if (!image_check_dcrc (rd_hdr)) {			puts ("Bad Data CRC\n");			show_boot_progress (-12);			return NULL;		}		puts("OK\n");	}	show_boot_progress (11);	if (!image_check_os (rd_hdr, IH_OS_LINUX) ||	    !image_check_arch (rd_hdr, arch) ||	    !image_check_type (rd_hdr, IH_TYPE_RAMDISK)) {		printf ("No Linux %s Ramdisk Image\n",				genimg_get_arch_name(arch));		show_boot_progress (-13);		return NULL;	}	return rd_hdr;}#endif /* !USE_HOSTCC *//*****************************************************************************//* Shared dual-format routines *//*****************************************************************************/#ifndef USE_HOSTCCint getenv_yesno (char *var){	char *s = getenv (var);	return (s && (*s == 'n')) ? 0 : 1;}ulong getenv_bootm_low(void){	char *s = getenv ("bootm_low");	if (s) {		ulong tmp = simple_strtoul (s, NULL, 16);		return tmp;	}#if defined(CFG_SDRAM_BASE)	return CFG_SDRAM_BASE;#elif defined(CONFIG_ARM)	return gd->bd->bi_dram[0].start;#else	return 0;#endif}phys_size_t getenv_bootm_size(void){	char *s = getenv ("bootm_size");	if (s) {		phys_size_t tmp;#ifdef CFG_64BIT_STRTOUL		tmp = (phys_size_t)simple_strtoull (s, NULL, 16);#else		tmp = (phys_size_t)simple_strtoul (s, NULL, 16);#endif		return tmp;	}#if defined(CONFIG_ARM)	return gd->bd->bi_dram[0].size;#else	return gd->bd->bi_memsize;#endif}void memmove_wd (void *to, void *from, size_t len, ulong chunksz){#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)	while (len > 0) {		size_t tail = (len > chunksz) ? chunksz : len;		WATCHDOG_RESET ();		memmove (to, from, tail);		to += tail;		from += tail;		len -= tail;	}#else	/* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */	memmove (to, from, len);#endif	/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */}#endif /* !USE_HOSTCC */

⌨️ 快捷键说明

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