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

📄 bootm.c

📁 uboot详细解读可用启动引导LINUX2.6内核
💻 C
字号:
/* SPARC code for booting linux 2.6 * * (C) Copyright 2007 * Daniel Hellstrom, Gaisler Research, daniel@gaisler.com. * * 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 */#include <common.h>#include <command.h>#include <asm/byteorder.h>#include <asm/prom.h>#include <asm/cache.h>#define PRINT_KERNEL_HEADERextern image_header_t header;extern void srmmu_init_cpu(unsigned int entry);extern void prepare_bootargs(char *bootargs);extern int do_reset(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]);#ifdef CONFIG_USB_UHCIextern int usb_lowlevel_stop(void);#endif/* sparc kernel argument (the ROM vector) */struct linux_romvec *kernel_arg_promvec;/* page szie is 4k */#define PAGE_SIZE 0x1000#define RAMDISK_IMAGE_START_MASK	0x07FF#define RAMDISK_PROMPT_FLAG		0x8000#define RAMDISK_LOAD_FLAG		0x4000struct __attribute__ ((packed)) {	char traptable[PAGE_SIZE];	char swapper_pg_dir[PAGE_SIZE];	char pg0[PAGE_SIZE];	char pg1[PAGE_SIZE];	char pg2[PAGE_SIZE];	char pg3[PAGE_SIZE];	char empty_bad_page[PAGE_SIZE];	char empty_bad_page_table[PAGE_SIZE];	char empty_zero_page[PAGE_SIZE];	unsigned char hdr[4];	/* ascii "HdrS" */	/* 00.02.06.0b is for Linux kernel 2.6.11 */	unsigned char linuxver_mega_major;	unsigned char linuxver_major;	unsigned char linuxver_minor;	unsigned char linuxver_revision;	/* header version 0x0203 */	unsigned short hdr_ver;	union __attribute__ ((packed)) {		struct __attribute__ ((packed)) {			unsigned short root_flags;			unsigned short root_dev;			unsigned short ram_flags;			unsigned int sparc_ramdisk_image;			unsigned int sparc_ramdisk_size;			unsigned int reboot_command;			unsigned int resv[3];			unsigned int end;		} ver_0203;	} hdr_input;} *linux_hdr;/* temporary initrd image holder */image_header_t ihdr;/* boot the linux kernel */void do_bootm_linux(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[],		    bootm_headers_t * images){	char *bootargs;	ulong ep, load;	ulong initrd_start, initrd_end;	ulong rd_data_start, rd_data_end, rd_len;	unsigned int data, len, checksum;	unsigned int initrd_addr, kernend;	void (*kernel) (struct linux_romvec *, void *);	struct lmb *lmb = images->lmb;	int ret;	if (images->legacy_hdr_valid) {		ep = image_get_ep(images->legacy_hdr_os);		load = image_get_load(images->legacy_hdr_os);#if defined(CONFIG_FIT)	} else if (images->fit_uname_os) {		int ret = fit_image_get_entry(images->fit_hdr_os,					      images->fit_noffset_os, &ep);		if (ret) {			puts("Can't get entry point property!\n");			goto error;		}		ret = fit_image_get_load(images->fit_hdr_os,					 images->fit_noffset_os, &load);		if (ret) {			puts("Can't get load address property!\n");			goto error;		}#endif	} else {		puts("Could not find kernel entry point!\n");		goto error;	}	/* Get virtual address of kernel start */	linux_hdr = (void *)load;	/* */	kernel = (void (*)(struct linux_romvec *, void *))ep;	/* check for a SPARC kernel */	if ((linux_hdr->hdr[0] != 'H') ||	    (linux_hdr->hdr[1] != 'd') ||	    (linux_hdr->hdr[2] != 'r') || (linux_hdr->hdr[3] != 'S')) {		puts("Error reading header of SPARC Linux kernel, aborting\n");		goto error;	}#ifdef PRINT_KERNEL_HEADER	printf("## Found SPARC Linux kernel %d.%d.%d ...\n",	       linux_hdr->linuxver_major,	       linux_hdr->linuxver_minor, linux_hdr->linuxver_revision);#endif#ifdef CONFIG_USB_UHCI	usb_lowlevel_stop();#endif	/* set basic boot params in kernel header now that it has been	 * extracted and is writeable.	 */	/*	 * Are we going to use an initrd image?	 */	ret = boot_get_ramdisk(argc, argv, images, IH_ARCH_SPARC,			       &rd_data_start, &rd_data_end);	if (ret) {		/* RAM disk found but was corrupt */		puts("RAM Disk corrupt\n");		goto error;	}	/* Calc length of RAM disk, if zero no ramdisk available */	rd_len = rd_data_end - rd_data_start;	if (rd_len) {		/* Reserve the space used by PROM and stack. This is done		 * to avoid that the RAM image is copied over stack or		 * PROM.		 */		lmb_reserve(lmb, CFG_RELOC_MONITOR_BASE, CFG_RAM_END);		ret = boot_ramdisk_high(lmb, rd_data_start, rd_len,					&initrd_start, &initrd_end);		if (ret) {			puts("### Failed to relocate RAM disk\n");			goto error;		}		/* Update SPARC kernel header so that Linux knows		 * what is going on and where to find RAM disk.		 *		 * Set INITRD Image address relative to RAM Start		 */		linux_hdr->hdr_input.ver_0203.sparc_ramdisk_image =		    initrd_start - CFG_RAM_BASE;		linux_hdr->hdr_input.ver_0203.sparc_ramdisk_size = rd_len;		/* Clear READ ONLY flag if set to non-zero */		linux_hdr->hdr_input.ver_0203.root_flags = 1;		/* Set root device to: Root_RAM0 */		linux_hdr->hdr_input.ver_0203.root_dev = 0x100;		linux_hdr->hdr_input.ver_0203.ram_flags = 0;	} else {		/* NOT using RAMDISK image, overwriting kernel defaults */		linux_hdr->hdr_input.ver_0203.sparc_ramdisk_image = 0;		linux_hdr->hdr_input.ver_0203.sparc_ramdisk_size = 0;		/* Leave to kernel defaults		   linux_hdr->hdr_input.ver_0203.root_flags = 1;		   linux_hdr->hdr_input.ver_0203.root_dev = 0;		   linux_hdr->hdr_input.ver_0203.ram_flags = 0;		 */	}	/* Copy bootargs from bootargs variable to kernel readable area */	bootargs = getenv("bootargs");	prepare_bootargs(bootargs);	/* turn on mmu & setup context table & page table for process 0 (kernel) */	srmmu_init_cpu((unsigned int)kernel);	/* Enter SPARC Linux kernel	 * From now on the only code in u-boot that will be	 * executed is the PROM code.	 */	kernel(kernel_arg_promvec, (void *)ep);	/* It will never come to this... */	while (1) ;      error:	do_reset(cmdtp, flag, argc, argv);	return;}

⌨️ 快捷键说明

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