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

📄 boot_kernel.c

📁 SMDK2440 boot code, base on vivi
💻 C
字号:
/* *  vivi/kernel/boot-kernel.c:  *    copy the kernel image to ram, then execute it  * *  Author:	Janghoon Lyu *  Created:	December 23, 2001 *  Copyright:  MIZI Resarch, Inc. All rights reserved. * *  Last modified: $Date: 2004/04/19 04:00:29 $ *                 $Revision: 1.20 $ */#include <config.h>#include <machine.h>#include <memory.h>#include <boot_kernel.h>#include <param.h>#include <mtd/mtd.h>#include <mtd/partitions.h>#include <command.h>#include <vstring.h>#include <mmu.h>#include <types.h>#include <setup.h>#include <string.h>#include <serial.h>#include <irq.h>#include <processor.h>#define LINUX_KERNEL_OFFSET	(0x8000)#define LINUX_PARAM_OFFSET	(0x100)#define LINUX_PAGE_SIZE		(SZ_4K)#define LINUX_PAGE_SHIFT	(12)#define LINUX_ZIMAGE_MAGIC	(0x016f2818)/* * Function:	call_linux() *  * Purpose:	Execute the kernel * * Arguments:	r0 - must contain a zero or else the kernel loops * 		r1 - architecture type * 		r2 - address to be executed * * Return:	None * * Notes:	This fucntion depends on the processor. */#ifdef CONFIG_ARCH_S3C2400void call_linux(long a0, long a1, long a2){	cache_clean_invalidate();	tlb_invalidate();__asm__(	"mov	r0, %0\n"	"mov	r1, %1\n"	"mov	r2, %2\n"	"mov	ip, #0\n"	"mcr	p15, 0, ip, c13, c0, 0\n"	/* zero PID */	"mcr	p15, 0, ip, c7, c7, 0\n"	/* invalidate I,D caches */	"mcr	p15, 0, ip, c7, c10, 4\n"	/* drain write buffer */	"mcr	p15, 0, ip, c8, c7, 0\n"	/* invalidate I,D TLBs */	"mrc	p15, 0, ip, c1, c0, 0\n"	/* get control register */	"bic	ip, ip, #0x0001\n"		/* disable MMU */	"mcr	p15, 0, ip, c1, c0, 0\n"	/* write control register */	"mov	pc, r2\n"	"nop\n"	"nop\n"	: /* no outputs */	: "r" (a0), "r" (a1), "r" (a2)	);}#elif defined(CONFIG_ARCH_S3C2410) || defined(CONFIG_ARCH_S3C2440) || defined(CONFIG_ARCH_MMSP2)void  call_linux(long a0, long a1, long a2){	cache_clean_invalidate();	tlb_invalidate();__asm__(	"mov	r0, %0\n"	"mov	r1, %1\n"	"mov	r2, %2\n"	"mov	ip, #0\n"	"mcr	p15, 0, ip, c13, c0, 0\n"	/* zero PID */	"mcr	p15, 0, ip, c7, c7, 0\n"	/* invalidate I,D caches */	"mcr	p15, 0, ip, c7, c10, 4\n"	/* drain write buffer */	"mcr	p15, 0, ip, c8, c7, 0\n"	/* invalidate I,D TLBs */	"mrc	p15, 0, ip, c1, c0, 0\n"	/* get control register */	"bic	ip, ip, #0x0001\n"		/* disable MMU */	"mcr	p15, 0, ip, c1, c0, 0\n"	/* write control register */	"mov	pc, r2\n"	"nop\n"	"nop\n"	: /* no outputs */	: "r" (a0), "r" (a1), "r" (a2)	);}#elif defined(CONFIG_ARCH_SA1100)void  call_linux(long r0, long r1, long r2){	__asm__(" mov r10, r1\n" 		" mov r11, r2\n" 		" mcr p15, 0, r0, c8, c7, 0\n" /* flush I and D TlB */		" mcr p15, 0, r0, c7, c10, 4\n" /* drain the write buffer */		" mov r3, #0x130\n"		" mcr p15, 0, r3, c1, c0, 0\n"   /* disable the MMU */		/* make sure the pipeline is emptied */		" mov r0, #0\n"  		" mov r0, r0\n"  		" mov r0, r0\n"  		" mov r0, r0\n"  		" mov r0, r0\n"  		/* zero PID in Fast Context Switch Extension PID register */		" mov r0, #0\n"  		" mcr p15, 0, r0, c13, c0, 0\n"		" mov r0, #0\n"  		" mov r1, r10\n" 		" mov pc, r11\n"         /* jump to addr. bootloader is done */ 		: : "r" (r0), "r" (r1), "r" (r2) );}#elif defined(CONFIG_ARCH_PXA250)void  call_linux(long r0, long r1, long r2){	__asm__(" mov r10, r1\n" 		" mov r11, r2\n" 		" mcr p15, 0, r0, c8, c7, 0\n" /* flush I and D TlB */		" mcr p15, 0, r0, c7, c10, 4\n" /* drain the write buffer */		" mov r3, #0x130\n"		" mcr p15, 0, r3, c1, c0, 0\n"   /* disable the MMU */		/* make sure the pipeline is emptied */		" mov r0, #0\n"  		" mov r0, r0\n"  		" mov r0, r0\n"  		" mov r0, r0\n"  		" mov r0, r0\n"  		/* zero PID in Fast Context Switch Extension PID register */		" mov r0, #0\n"  		" mcr p15, 0, r0, c13, c0, 0\n"		" mov r0, #0\n"  		" mov r1, r10\n" 		" mov pc, r11\n"         /* jump to addr. bootloader is done */ 		: : "r" (r0), "r" (r1), "r" (r2) );}#elif defined(CONFIG_ARCH_S3C24A0)void  call_linux(long a0, long a1, long a2){	cache_clean_invalidate();	tlb_invalidate();__asm__(	"mov	r0, %0\n"	"mov	r1, %1\n"	"mov	r2, %2\n"	"mov	ip, #0\n"	"mcr	p15, 0, ip, c13, c0, 0\n"	/* zero PID */	"mrc	p15, 0, ip, c1, c0, 0\n"	/* get control register */	"bic	ip, ip, #0x0001\n"		/* disable MMU */	"mcr	p15, 0, ip, c1, c0, 0\n"	/* write control register */	"mov	pc, r2\n"	"nop\n"	"nop\n"	: /* no outputs */	: "r" (a0), "r" (a1), "r" (a2)	);}#elif defined(CONFIG_ARCH_PXA27X)void  call_linux(long r0, long r1, long r2){	__asm__(" mov r10, r1\n" 		" mov r11, r2\n" 		" mcr p15, 0, r0, c8, c7, 0\n" /* flush I and D TlB */		" mcr p15, 0, r0, c7, c10, 4\n" /* drain the write buffer */		" mov r3, #0x130\n"		" mcr p15, 0, r3, c1, c0, 0\n"   /* disable the MMU */		/* make sure the pipeline is emptied */		" mov r0, #0\n"  		" mov r0, r0\n"  		" mov r0, r0\n"  		" mov r0, r0\n"  		" mov r0, r0\n"  		/* zero PID in Fast Context Switch Extension PID register */		" mov r0, #0\n"  		" mcr p15, 0, r0, c13, c0, 0\n"		" mov r0, #0\n"  		" mov r1, r10\n" 		" mov pc, r11\n"         /* jump to addr. bootloader is done */ 		: : "r" (r0), "r" (r1), "r" (r2) );}#else#error not defined call_linux() for this architecture	#endif/* * Function:	setup_linux_param() *  * Purpose:	setup parameters for linux kernel. * * Arguments:	param_base - base address of linux parameters *                           Normally, this address is RAM base address + 0x100. * * Return:	None * * Notes:	None */static void setup_linux_param(ulong param_base){	char *linux_cmd;#if 0 //phoenix20090212:blocked_compile error#ifdef CONFIG_KERNEL_VERSION_2_6	struct tag *tags = (struct tag *)param_base;	linux_cmd = get_linux_cmd_line();	if (linux_cmd == NULL) {		printk("There's no valid command line\n");	}	tags->hdr.size = tag_size(tag_core);	tags->hdr.tag = ATAG_CORE;	tags->u.core.flags = 1;	tags->u.core.pagesize = LINUX_PAGE_SIZE;	tags->u.core.rootdev = 0xff;	tags = tag_next(tags);	tags->hdr.size = tag_size(tag_mem32);	tags->hdr.tag = ATAG_MEM;	tags->u.mem.size = DRAM_SIZE;	tags->u.mem.start = DRAM_BASE;	tags = tag_next(tags);	tags->hdr.size = ((sizeof(struct tag_header) + 1024) >> 2);	tags->hdr.tag = ATAG_CMDLINE;	memcpy(tags->u.cmdline.cmdline, linux_cmd, 1024);	printk("linux command line is: \"%s\"\n", tags->u.cmdline.cmdline);	tags = tag_next(tags);		tags->hdr.size = 0;	tags->hdr.tag = ATAG_NONE;#else	struct param_struct *params = (struct param_struct *)param_base; 	printk("Setup linux parameters at 0x%08lx\n", param_base);	memset(params, 0, sizeof(struct param_struct));	/* 部坷苛 秦拎具 瞪 巴甸.. 抄叼啊 版氰利栏肺 措面 嘛篮 巴.. */	params->u1.s.page_size = LINUX_PAGE_SIZE;	params->u1.s.nr_pages = (DRAM_SIZE >> LINUX_PAGE_SHIFT);	/* set linux command line */	linux_cmd = get_linux_cmd_line();	if (linux_cmd == NULL) {		printk("There's no valid command line\n");	} else {		memcpy(params->commandline, linux_cmd, strlen(linux_cmd));		printk("linux command line is: \"%s\"\n", params->commandline);	}#endif#endif}static int media_type_is(const char *mt){	if (strncmp("ram", mt, 3) == 0) {		return MT_RAM;	} else if (strncmp("nor", mt, 3) == 0) {		return MT_NOR_FLASH;	} else if (strncmp("smc", mt, 3) == 0) {		return MT_NAND_S3C24XX;	} else if (strncmp("mdocp", mt, 4) == 0) {		return MT_NAND_MDOCP;	} else {		return MT_UNKNOWN;	}}static intcopy_kernel(u_char *buf, int mt){	int ret = 0;	ulong zimage_magic;	printk("copying kernel... ");	switch (mt) {	case MT_RAM:		/* Noting to do */		ret = 0;		break;	case MT_NOR_FLASH:	case MT_NAND_S3C24XX:	case MT_NAND_MDOCP:#ifdef CONFIG_MTD				if ((ret = mtd_read_part("kernel", buf, 0)))			return ret;		//nandll_read_blocks(0x30008000, 0x30000, 0xc0000);#endif		break;	case MT_UNKNOWN:	default:		ret = -2;	}	if (ret) {		printk("fail\n");		if (ret == -2) printk("Undefined media type.\n");	} else {		printk("ok\n");	}	/* 府椽胶 目澄 捞固瘤啊 嘎绰瘤 埃窜洒 眉农. 酒聪搁 富备... */	memcpy((void *)&zimage_magic, buf + 36, sizeof(ulong));	if (zimage_magic != LINUX_ZIMAGE_MAGIC)		printk("** WARNING: this binary is not compressed linux kernel image\n");	printk("zImage magic = 0x%08lx\n", zimage_magic);	return ret;}/* * copy_initrd: copy ram disk to ram * * Arguments: *    media_type: a typeof storage device * Return value: *         0: OK *    others: Fail */static int copy_initrd(char *str){	int no;	ulong addr[2];	/* 0 = offset to be write, 1 = length */	char *next;	printk("copying initrd... ");	no = 0;	next = str;	while((str = next) != NULL) {		next = strchr(str, ',');		if (next != NULL) {			*next++ = '\0';		}		addr[no] = simple_strtoul(str, NULL, 0);		no++;	}	if (no != 2) {		printk("wrong 'initrd' command\n");		return 1;	}#ifdef CONFIG_MTD	if (mtd_read_part("root",  (u_char *)addr[0], addr[1]))		printk("fail\n");	else		printk("ok\n");#endif	return 0;}/* * boot_kernel: booting the linux kernel * * from: address of stored kernel image * size: size of kernel image * media_type: a type of stoage device */int boot_kernel(int media_type){	char str[32];	ulong boot_mem_base = DRAM_BASE;	ulong kernel_mem_base = boot_mem_base + LINUX_KERNEL_OFFSET;	ulong mach_type;	term_blank_on();	/* tern off terminal if you want */	/* copy kerne image */	copy_kernel((u_char *)(kernel_mem_base), media_type);	/* copy initrd */	if (get_param_str("initrd", &str[0]) != NULL) {		copy_initrd((char *)&str[0]);	}	/* Setup linux parameters and linux command line */	setup_linux_param(boot_mem_base + LINUX_PARAM_OFFSET);	/* Get machine type */	get_param_ulong("mach_type", &mach_type);	printk("MACH_TYPE = %d\n", mach_type);	/* reset prcessor's resource */	reset_proc_res();	/* Go Go Go */	printk("NOW, Booting Linux......\n\n");	call_linux(0, mach_type, kernel_mem_base);	return 0;	/* never return */}	/* * User Commands */static void display_help(void){	printk("Usage:\n");	printk("  boot       -- booting kernel \n");	printk("  boot ram   -- booting kernel using image on the ram\n");	printk("  boot help  -- help about 'boot' command\n");}/* * default values: *   kernel mtd partition = "kernel" *   base adress of bootable memory = DRAM_BASE *   media type =  */void command_boot(int argc, const char **argv){	int media_type = 0;	char m[16];	switch (argc) {	case 1:		if (get_param_str("media_type", m) == NULL) {			printk("Unable to get media_type parameter\n");			return;		}		media_type = media_type_is(m);		break;	case 2:		if (strncmp("help", argv[1], 4) == 0) {			display_help();			return;		}					media_type = media_type_is(argv[1]);		break;	default:		display_help();		break;	}	disable_irq_and_clear();	boot_kernel(media_type);}user_command_t boot_cmd = {	"boot",	command_boot,	NULL};

⌨️ 快捷键说明

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