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

📄 linux.c

📁 Hermit-at-1.1.3,一款bootloader
💻 C
字号:
/* * Copyright (c) 2007 Atmark Techno, Inc.  All Rights Reserved. */#include <hermit.h>#include <target/herrno.h>#include <target/io.h>#include <target/atag.h>#include <target/gunzip.h>#include <target/memzero.h>#include <target/str.h>#include "linux.h"#include "mmu.h"#include "memregions.h"#include "board.h"#include "ide_core.h"#include <target/param.h>#include "ide_a5x0.h"/* for setting the root device */#define MINORBITS       8#define MKDEV(ma,mi)    (((ma) << MINORBITS) | (mi))#define RAMDISK_MAJOR   1	/* major for "RAM disk" */#define RAMDISK0_MINOR	0	/* b 1 0 == /dev/ram0 */typedef struct boot_device {	char	*name;	u8	major;	u8	minor_start;	u8	minor_inc;} boot_device_t;static boot_device_t boot_device_table[] = {	/*			minor	minor	*/	/* name		major	start	inc	*/	{"ram",		1,	0,	1,	},	{"hda",		3,	1,	1,	},	{"mtdblock",	31,	0,	1,	},	{"mmcblk0p",	0,	1,	1,	},};#define DEFAULT_BOOT_DEVICE (1) /* RAMDISK */static int major = RAMDISK_MAJOR;static int minor = RAMDISK0_MINOR;#define COMMAND_LINE_SIZE 1024extern unsigned long bytes_out;#define MACH_ARMADILLO500 1260/**************************************************************************** * linux_cmbfunc ****************************************************************************/static int linux_cmdfunc(int argc, char *argv[]){	u32 machine_no = MACH_ARMADILLO500;	struct tag *tag = (struct tag *) LINUX_PARAM_ADDRESS;	/* zero param block */	memzero (tag, LINUX_PARAM_SIZE);	/* set up core tag */	tag->hdr.tag = ATAG_CORE;	tag->hdr.size = tag_size(tag_core);	tag->u.core.flags = 0;	tag->u.core.pagesize = 0x1000;	tag->u.core.rootdev = MKDEV(major, minor);	/* SDRAM */	tag = tag_next(tag);	tag->hdr.tag = ATAG_MEM;	tag->hdr.size = tag_size(tag_mem32);	tag->u.mem.size = DRAM1_SIZE;	tag->u.mem.start = DRAM1_START;	if (major == RAMDISK_MAJOR) {		/* an initial ramdisk image in flash at 0x00700000 */		tag = tag_next(tag);		tag->hdr.tag = ATAG_INITRD;		tag->hdr.size = tag_size(tag_initrd);		tag->u.initrd.start = INITRD_START_ADDRESS;		tag->u.initrd.size  = bytes_out;	}	/* the command line arguments */	if (argc > 1) {		tag = tag_next(tag);		tag->hdr.tag = ATAG_CMDLINE;		tag->hdr.size = (COMMAND_LINE_SIZE + 1 + 4 +			 sizeof(struct tag_header)) >> 2;		{			const unsigned char *src;			unsigned char *dst;			dst = tag->u.cmdline.cmdline;			memzero (dst, COMMAND_LINE_SIZE);			while (--argc > 0) {				src = *++argv;				hprintf ("Doing %s\n", src);				while (*src)					*dst++ = *src++;				*dst++ = ' ';			}			*--dst = '\0';		}	}	tag = tag_next(tag);	tag->hdr.tag = 0;	tag->hdr.size = 0;	/* branch to kernel image */	__asm__ volatile	  (	   "mov r4, %0;" /* kernel start */	   "mov r0, #0;" /* kernel sanity check */	   "mov r1, %1;" /* machine no */	   "mov r2, #0;"	   "mov r3, %2;" /* param */	   "mov pc, r4;" /* go there! */	   :	   : "r" (LINUX_LOAD_ADDRESS), "r" (machine_no), "r" (tag)	   );	/* never get here */	return 0;}/**************************************************************************** * boot_cmdfunc ****************************************************************************/static int boot_cmdfunc(int argc, char *argv[]){	int bootdevice_ide = 0;	int noinitrd = 0;	int c_argc = 1;	char *c_argv[64];	char *param[64];	int ret;	int i;	led_on();	if (argc > 1) {		c_argc = argc;		for (i=0; i<c_argc; i++)			c_argv[i] = argv[i];	} else {		int param_count;		param_count = get_param_count();		get_param(param, param_count);		for (i=0; i<param_count; i++) {			if (param[i][0] != '@')				c_argv[c_argc++] = param[i];		}	}	for (i=1; i<c_argc; i++) {		int j;		if (!strcmp(c_argv[i], "noinitrd"))			noinitrd = 1;		else if (!strncmp(c_argv[i], "root=", 5)) {			int ptr = 5;			if (!strncmp(&c_argv[i][ptr], "/dev/", 5))				ptr += 5;			for (j=0; j<ARRAY_SIZE(boot_device_table); j++) {				char name_len = 				  strlen(boot_device_table[j].name); 				if (!strncmp(&c_argv[i][ptr],					     boot_device_table[j].name,					     name_len)) {				  u8 dev_minor = 				    (u8)c_argv[i][ptr + name_len] - '0';				  dev_minor = minor > 10 ? 0 : minor;				  major = boot_device_table[j].major;				  minor = (boot_device_table[j].minor_start +					   (boot_device_table[j].minor_inc * 					    dev_minor));				}			}		}	}#if defined(ENABLE_IDE)	{		char param[] = "@bootdevice=hda*";		for (i=0; i<5; i++) {			if (i == 4) {				param[15] = 0x00;				bootdevice_ide = 0;			} else {				param[15] = '1' + i;				bootdevice_ide = i + 1;			}			ret = check_param(param);			if (ret)				break;			bootdevice_ide = -1;		}		if (bootdevice_ide != -1)			ret = ide_load_kernel(bootdevice_ide);		else			ret = -1;	}#else	ret = -1;#endif	boost_on(BOOST_LINUX_MODE);	if (ret)		gunzip_object (" kernel",			       LINUX_SRC_ADDRESS,			       LINUX_LOAD_ADDRESS);    	if (!noinitrd)		gunzip_object ("ramdisk",			       INITRD_SRC_ADDRESS,			       INITRD_LOAD_ADDRESS);    	boost_off ();	/* load boot status */	if (check_param("@clock=532"))		change_clk(CLK_532MHZ, 0);	linux_cmdfunc(c_argc, c_argv);	return 0;}/**************************************************************************** * commands ****************************************************************************/const command_t linux_command =	{ "linux", "<linux options>", "start Linux", &linux_cmdfunc };const command_t boot_command =	{ "boot", "", "boot default Linux kernel and ramdisk", &boot_cmdfunc };COMMAND(linux_command);COMMAND_ABBR(boot_command, 'b');

⌨️ 快捷键说明

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