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

📄 cmd_bootm.c.svn-base

📁 u-boot loader common files, like cpu, clock, environment...etc...
💻 SVN-BASE
📖 第 1 页 / 共 3 页
字号:
/* * (C) Copyright 2000-2002 * 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 *//* * Boot support */#include <common.h>#include <watchdog.h>#include <command.h>#include <image.h>#include <malloc.h>#include <zlib.h>#include <bzlib.h>#include <environment.h>#include <asm/byteorder.h> /*cmd_boot.c*/ extern int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);#if (CONFIG_COMMANDS & CFG_CMD_DATE) || defined(CONFIG_TIMESTAMP)#include <rtc.h>#endif#ifdef CFG_HUSH_PARSER#include <hush.h>#endif#ifdef CONFIG_SHOW_BOOT_PROGRESS# include <status_led.h># define SHOW_BOOT_PROGRESS(arg)	show_boot_progress(arg)#else# define SHOW_BOOT_PROGRESS(arg)#endif#ifdef CFG_INIT_RAM_LOCK#include <asm/cache.h>#endif#ifdef CONFIG_LOGBUFFER#include <logbuff.h>#endif#ifdef CONFIG_HAS_DATAFLASH#include <dataflash.h>#endif/* * Some systems (for example LWMON) have very short watchdog periods; * we must make sure to split long operations like memmove() or * crc32() into reasonable chunks. */#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)# define CHUNKSZ (64 * 1024)#endifint  gunzip (void *, int, unsigned char *, int *);static void *zalloc(void *, unsigned, unsigned);static void zfree(void *, void *, unsigned);#if (CONFIG_COMMANDS & CFG_CMD_IMI)static int image_info (unsigned long addr);#endif#if (CONFIG_COMMANDS & CFG_CMD_IMLS)#include <flash.h>extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips */static int do_imls (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);#endifstatic void print_type (image_header_t *hdr);#ifdef __I386__image_header_t *fake_header(image_header_t *hdr, void *ptr, int size);#endif/* *  Continue booting an OS image; caller already has: *  - copied image header to global variable `header' *  - checked header magic number, checksums (both header & image), *  - verified image architecture (PPC) and type (KERNEL or MULTI), *  - loaded (first part of) image to header load address, *  - disabled interrupts. */typedef void boot_os_Fcn (cmd_tbl_t *cmdtp, int flag,			  int	argc, char *argv[],			  ulong	addr,		/* of image to boot */			  ulong	*len_ptr,	/* multi-file image length table */			  int	verify);	/* getenv("verify")[0] != 'n' */#ifdef	DEBUGextern int do_bdinfo ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);#endif#ifdef CONFIG_PPCstatic boot_os_Fcn do_bootm_linux;#elseextern boot_os_Fcn do_bootm_linux;#endif#ifdef CONFIG_SILENT_CONSOLEstatic void fixup_silent_linux (void);#endifstatic boot_os_Fcn do_bootm_netbsd;static boot_os_Fcn do_bootm_rtems;#if (CONFIG_COMMANDS & CFG_CMD_ELF)static boot_os_Fcn do_bootm_vxworks;static boot_os_Fcn do_bootm_qnxelf;int do_bootvx ( cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] );int do_bootelf (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[] );#endif /* CFG_CMD_ELF */#if defined(CONFIG_ARTOS) && defined(CONFIG_PPC)static boot_os_Fcn do_bootm_artos;#endif#ifdef CONFIG_LYNXKDIstatic boot_os_Fcn do_bootm_lynxkdi;extern void lynxkdi_boot( image_header_t * );#endifimage_header_t header;ulong load_addr = CFG_LOAD_ADDR;		/* Default Load Address */int do_bootm (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]){	ulong	iflag;	ulong	addr;	ulong	data, len, checksum;	ulong  *len_ptr;	uint	unc_len = 0x400000;	int	i, verify;	char	*name, *s;	int	(*appl)(int, char *[]);	image_header_t *hdr = &header;	s = getenv ("verify");	verify = (s && (*s == 'n')) ? 0 : 1;	if (argc < 2) {		addr = load_addr;	} else {		addr = simple_strtoul(argv[1], NULL, 16);	}	SHOW_BOOT_PROGRESS (1);	printf ("## Booting image at %08lx ...\n", addr);	/* Copy header so we can blank CRC field for re-calculation */#ifdef CONFIG_HAS_DATAFLASH	if (addr_dataflash(addr)){		read_dataflash(addr, sizeof(image_header_t), (char *)&header);	} else#endif	memmove (&header, (char *)addr, sizeof(image_header_t));	if (ntohl(hdr->ih_magic) != IH_MAGIC) {#ifdef __I386__	/* correct image format not implemented yet - fake it */		if (fake_header(hdr, (void*)addr, -1) != NULL) {			/* to compensate for the addition below */			addr -= sizeof(image_header_t);			/* turnof verify,			 * fake_header() does not fake the data crc			 */			verify = 0;		} else#endif	/* __I386__ */	    {		puts ("Bad Magic Number\n");		SHOW_BOOT_PROGRESS (-1);		return 1;	    }	}	SHOW_BOOT_PROGRESS (2);	data = (ulong)&header;	len  = sizeof(image_header_t);	checksum = ntohl(hdr->ih_hcrc);	hdr->ih_hcrc = 0;	if (crc32 (0, (char *)data, len) != checksum) {		puts ("Bad Header Checksum\n");		SHOW_BOOT_PROGRESS (-2);		return 1;	}	SHOW_BOOT_PROGRESS (3);	/* for multi-file images we need the data part, too */	print_image_hdr ((image_header_t *)addr);	data = addr + sizeof(image_header_t);	len  = ntohl(hdr->ih_size);#ifdef CONFIG_HAS_DATAFLASH	if (addr_dataflash(addr)){		read_dataflash(data, len, (char *)CFG_LOAD_ADDR);		data = CFG_LOAD_ADDR;	}#endif	if (verify) {		puts ("   Verifying Checksum ... ");		if (crc32 (0, (char *)data, len) != ntohl(hdr->ih_dcrc)) {			printf ("Bad Data CRC\n");			SHOW_BOOT_PROGRESS (-3);			return 1;		}		puts ("OK\n");	}	SHOW_BOOT_PROGRESS (4);	len_ptr = (ulong *)data;#if defined(__PPC__)	if (hdr->ih_arch != IH_CPU_PPC)#elif defined(__ARM__)	if (hdr->ih_arch != IH_CPU_ARM)#elif defined(__I386__)	if (hdr->ih_arch != IH_CPU_I386)#elif defined(__mips__)	if (hdr->ih_arch != IH_CPU_MIPS)#elif defined(__nios__)	if (hdr->ih_arch != IH_CPU_NIOS)#elif defined(__M68K__)	if (hdr->ih_arch != IH_CPU_M68K)#elif defined(__microblaze__)	if (hdr->ih_arch != IH_CPU_MICROBLAZE)#else# error Unknown CPU type#endif	{		printf ("Unsupported Architecture 0x%x\n", hdr->ih_arch);		SHOW_BOOT_PROGRESS (-4);		return 1;	}	SHOW_BOOT_PROGRESS (5);	switch (hdr->ih_type) {	case IH_TYPE_STANDALONE:		name = "Standalone Application";		/* A second argument overwrites the load address */		if (argc > 2) {			hdr->ih_load = simple_strtoul(argv[2], NULL, 16);		}		break;	case IH_TYPE_KERNEL:		name = "Kernel Image";		break;	case IH_TYPE_MULTI:		name = "Multi-File Image";		len  = ntohl(len_ptr[0]);		/* OS kernel is always the first image */		data += 8; /* kernel_len + terminator */		for (i=1; len_ptr[i]; ++i)			data += 4;		break;	default: printf ("Wrong Image Type for %s command\n", cmdtp->name);		SHOW_BOOT_PROGRESS (-5);		return 1;	}	SHOW_BOOT_PROGRESS (6);	/*	 * We have reached the point of no return: we are going to	 * overwrite all exception vector code, so we cannot easily	 * recover from any failures any more...	 */	iflag = disable_interrupts();#ifdef CONFIG_AMIGAONEG3SE	/*	 * We've possible left the caches enabled during	 * bios emulation, so turn them off again	 */	icache_disable();	invalidate_l1_instruction_cache();	flush_data_cache();	dcache_disable();#endif	switch (hdr->ih_comp) {	case IH_COMP_NONE:		if(ntohl(hdr->ih_load) == addr) {			printf ("   XIP %s ... ", name);		} else {#if defined(CONFIG_HW_WATCHDOG) || defined(CONFIG_WATCHDOG)			size_t l = len;			void *to = (void *)ntohl(hdr->ih_load);			void *from = (void *)data;			printf ("   Loading %s ... ", name);			while (l > 0) {				size_t tail = (l > CHUNKSZ) ? CHUNKSZ : l;				WATCHDOG_RESET();				memmove (to, from, tail);				to += tail;				from += tail;				l -= tail;			}#else	/* !(CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG) */			memmove ((void *) ntohl(hdr->ih_load), (uchar *)data, len);#endif	/* CONFIG_HW_WATCHDOG || CONFIG_WATCHDOG */		}		break;	case IH_COMP_GZIP:		printf ("   Uncompressing %s ... ", name);		if (gunzip ((void *)ntohl(hdr->ih_load), unc_len,			    (uchar *)data, (int *)&len) != 0) {			puts ("GUNZIP ERROR - must RESET board to recover\n");			SHOW_BOOT_PROGRESS (-6);			do_reset (cmdtp, flag, argc, argv);		}		break;#ifdef CONFIG_BZIP2	case IH_COMP_BZIP2:		printf ("   Uncompressing %s ... ", name);		/*		 * If we've got less than 4 MB of malloc() space,		 * use slower decompression algorithm which requires		 * at most 2300 KB of memory.		 */		i = BZ2_bzBuffToBuffDecompress ((char*)ntohl(hdr->ih_load),						&unc_len, (char *)data, len,						CFG_MALLOC_LEN < (4096 * 1024), 0);		if (i != BZ_OK) {			printf ("BUNZIP2 ERROR %d - must RESET board to recover\n", i);			SHOW_BOOT_PROGRESS (-6);			udelay(100000);			do_reset (cmdtp, flag, argc, argv);		}		break;#endif /* CONFIG_BZIP2 */	default:		if (iflag)			enable_interrupts();		printf ("Unimplemented compression type %d\n", hdr->ih_comp);		SHOW_BOOT_PROGRESS (-7);		return 1;	}	puts ("OK\n");	SHOW_BOOT_PROGRESS (7);	switch (hdr->ih_type) {	case IH_TYPE_STANDALONE:		if (iflag)			enable_interrupts();		/* load (and uncompress), but don't start if "autostart"		 * is set to "no"		 */		if (((s = getenv("autostart")) != NULL) && (strcmp(s,"no") == 0)) {			char buf[32];			sprintf(buf, "%lX", len);			setenv("filesize", buf);			return 0;		}		appl = (int (*)(int, char *[]))ntohl(hdr->ih_ep);		(*appl)(argc-1, &argv[1]);		return 0;	case IH_TYPE_KERNEL:	case IH_TYPE_MULTI:		/* handled below */		break;	default:		if (iflag)			enable_interrupts();		printf ("Can't boot image type %d\n", hdr->ih_type);		SHOW_BOOT_PROGRESS (-8);		return 1;	}	SHOW_BOOT_PROGRESS (8);	switch (hdr->ih_os) {	default:			/* handled by (original) Linux case */	case IH_OS_LINUX:#ifdef CONFIG_SILENT_CONSOLE	    fixup_silent_linux();#endif	    do_bootm_linux  (cmdtp, flag, argc, argv,			     addr, len_ptr, verify);	    break;	case IH_OS_NETBSD:	    do_bootm_netbsd (cmdtp, flag, argc, argv,			     addr, len_ptr, verify);	    break;#ifdef CONFIG_LYNXKDI	case IH_OS_LYNXOS:	    do_bootm_lynxkdi (cmdtp, flag, argc, argv,			     addr, len_ptr, verify);	    break;#endif	case IH_OS_RTEMS:	    do_bootm_rtems (cmdtp, flag, argc, argv,			     addr, len_ptr, verify);	    break;#if (CONFIG_COMMANDS & CFG_CMD_ELF)	case IH_OS_VXWORKS:	    do_bootm_vxworks (cmdtp, flag, argc, argv,			      addr, len_ptr, verify);	    break;	case IH_OS_QNX:	    do_bootm_qnxelf (cmdtp, flag, argc, argv,			      addr, len_ptr, verify);	    break;#endif /* CFG_CMD_ELF */#ifdef CONFIG_ARTOS	case IH_OS_ARTOS:	    do_bootm_artos  (cmdtp, flag, argc, argv,			     addr, len_ptr, verify);	    break;#endif	}	SHOW_BOOT_PROGRESS (-9);#ifdef DEBUG	puts ("\n## Control returned to monitor - resetting...\n");	do_reset (cmdtp, flag, argc, argv);#endif	return 1;}U_BOOT_CMD( 	bootm,	CFG_MAXARGS,	1,	do_bootm, 	"bootm   - boot application image from memory\n", 	"[addr [arg ...]]\n    - boot application image stored in memory\n" 	"        passing arguments 'arg ...'; when booting a Linux kernel,\n" 	"        'arg' can be the address of an initrd image\n");#ifdef CONFIG_SILENT_CONSOLEstatic voidfixup_silent_linux ()

⌨️ 快捷键说明

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