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

📄 main.c

📁 linux下从网卡远程启动
💻 C
字号:
/**************************************************************************Etherboot -  Network Bootstrap ProgramLiterature dealing with the network protocols:	ARP - RFC826	RARP - RFC903	UDP - RFC768	BOOTP - RFC951, RFC2132 (vendor extensions)	DHCP - RFC2131, RFC2132 (options)	TFTP - RFC1350, RFC2347 (options), RFC2348 (blocksize), RFC2349 (tsize)	RPC - RFC1831, RFC1832 (XDR), RFC1833 (rpcbind/portmapper)	NFS - RFC1094, RFC1813 (v3, useful for clarifications, not implemented)	IGMP - RFC1112**************************************************************************//* #define MDEBUG */#include "etherboot.h"#include "dev.h"#include "nic.h"#include "disk.h"#include "timer.h"#include "cpu.h"jmp_buf	restart_etherboot;int	url_port;		#ifdef	IMAGE_FREEBSDint freebsd_howto = 0;char freebsd_kernel_env[FREEBSD_KERNEL_ENV_SIZE];#endif#ifdef FREEBSD_PXEEMUextern char		pxeemu_nbp_active;#endif	/* FREEBSD_PXEBOOT */static inline unsigned long ask_boot(unsigned *index){	unsigned long order = DEFAULT_BOOT_ORDER;	*index = DEFAULT_BOOT_INDEX;#ifdef LINUXBIOS	order = get_boot_order(order, index);#endif#if defined(ASK_BOOT) && ASK_BOOT >= 0	while(1) {		int c;		unsigned long time;		printf(ASK_PROMPT);#if ASK_BOOT > 0		for (time = currticks() + ASK_BOOT*TICKS_PER_SEC; !iskey(); ) {			if (currticks() > time) {				c = ANS_DEFAULT;				goto done;			}		}#endif /* ASK_BOOT > 0 */		c = getchar();		if ((c >= 'a') && (c <= 'z')) c &= 0x5F;		if ((c >= ' ') && (c <= '~')) putchar(c);		putchar('\n');done:		switch(c) {		default:			/* Nothing useful try again */			continue;		case ANS_QUIT:			order = BOOT_NOTHING;			*index = 0;			break;		case ANS_DEFAULT:			/* Preserve the default boot order */			break;		case ANS_NETWORK:			order = (BOOT_NIC     << (0*BOOT_BITS)) | 				(BOOT_NOTHING << (1*BOOT_BITS));			*index = 0;			break;		case ANS_DISK:			order = (BOOT_DISK    << (0*BOOT_BITS)) | 				(BOOT_NOTHING << (1*BOOT_BITS));			*index = 0;			break;		case ANS_FLOPPY:			order = (BOOT_FLOPPY  << (0*BOOT_BITS)) | 				(BOOT_NOTHING << (1*BOOT_BITS));			*index = 0;			break;		}		break;	}	putchar('\n');#endif /* ASK_BOOT */	return order;}static inline void try_floppy_first(void){#if (TRY_FLOPPY_FIRST > 0) && defined(CAN_BOOT_DISK)	int i;	printf("Trying floppy");	disk_init();	for (i = TRY_FLOPPY_FIRST; i-- > 0; ) {		putchar('.');		if (pcbios_disk_read(0, 0, 0, 0, ((char *)FLOPPY_BOOT_LOCATION)) != 0x8000) {			printf("using floppy\n");			exit(0);		}	}	printf("no floppy\n");#endif /* TRY_FLOPPY_FIRST */	}static void console_init(void){#ifdef	CONSOLE_SERIAL	(void)serial_init();#endif#ifdef 	CONSOLE_DIRECT_VGA       	video_init();#endif}static void console_fini(void){#ifdef	CONSOLE_SERIAL	(void)serial_fini();#endif}static struct class_operations {	struct dev *dev;	int (*probe)(struct dev *dev);	int (*load_configuration)(struct dev *dev);	int (*load)(struct dev *dev);}operations[] = {	{ &nic.dev,  eth_probe,  eth_load_configuration,  eth_load  },	{ &disk.dev, disk_probe, disk_load_configuration, disk_load },	{ &disk.dev, disk_probe, disk_load_configuration, disk_load },};static int main_loop(int state);static int exit_ok;static int exit_status;static int initialized;/**************************************************************************MAIN - Kick off routine**************************************************************************/int main(struct Elf_Bhdr *ptr){	char *p;	int state;	for (p = _bss; p < _ebss; p++)		*p = 0;	/* Zero BSS */	console_init();	arch_main(ptr);	rom = *(struct rom_info *)phys_to_virt(ROM_INFO_LOCATION);	printf("ROM segment %#hx length %#hx reloc %#x\n", rom.rom_segment,		rom.rom_length << 1, (unsigned long)_text);	cpu_setup();	setup_timers();	gateA20_set();	print_config();	get_memsizes();	cleanup();#ifdef CONFIG_PCMCIA	pcmcia_init_all();#endif	/* -1:	timeout or ESC	   -2:	error return from loader	   -3:  finish the current run.	   0:	retry booting bootp and tftp	   1:   retry tftp with possibly modified bootp reply	   2:   retry bootp and tftp	   3:   retry probe bootp and tftp	   4:   start with the next device and retry from there...	   255: exit Etherboot	   256: retry after relocation	*/	state = setjmp(restart_etherboot);	exit_ok = 1;	for(;state != 255;) {		state = main_loop(state);	}	arch_on_exit(exit_status);#ifdef CONFIG_PCMCIA	pcmcia_shutdown_all();#endif	return exit_status;}void exit(int status){	while(!exit_ok)		;	exit_status = status;	longjmp(restart_etherboot, 255);}static int main_loop(int state){	/* Splitting main into 2 pieces makes the semantics of 	 * which variables are preserved across a longjmp clean	 * and predictable.	 */	static unsigned long order;	static unsigned boot_index;	static struct dev * dev = 0;	static struct class_operations *ops;	static void *heap_base;	static int type;	static int i;	if (!initialized) {		initialized = 1;		console_init();		if (dev && (state >= 1) && (state <= 2)) {			dev->how_probe = PROBE_AWAKE;			dev->how_probe = ops->probe(dev);			if (dev->how_probe == PROBE_FAILED) {				state = -1;			}		}	}	switch(state) {	case 0:	{		static int firsttime = 1;		/* First time through */		if (firsttime) {			relocate();			cleanup();			console_init();			init_heap();			firsttime = 0;		} #ifdef EMERGENCYDISKBOOT		else {			cleanup();			exit(0);		}#endif		heap_base = allot(0);		i = -1;		state = 4;		dev = 0;		/* We just called setjmp ... */		order = ask_boot(&boot_index);		try_floppy_first();		break;	}	case 4:		cleanup();		console_init();		forget(heap_base);		/* Find a dev entry to probe with */		if (!dev) {			int boot;			int failsafe;			/* Advance to the next device type */			i++;			boot = (order >> (i * BOOT_BITS)) & BOOT_MASK;			type = boot & BOOT_TYPE_MASK;			failsafe = (boot & BOOT_FAILSAFE) != 0;			if (i >= MAX_BOOT_ENTRIES) {				type = BOOT_NOTHING;			}			if ((i == 0) && (type == BOOT_NOTHING)) {				/* Return to caller */				exit(0);			}			if (type >= BOOT_NOTHING) {				interruptible_sleep(2);				state = 0;				break;			}			ops = &operations[type];			dev = ops->dev;			dev->how_probe = PROBE_FIRST;			dev->type = type;			dev->failsafe = failsafe;			dev->type_index = 0;		} else {			/* Advance to the next device of the same type */			dev->how_probe = PROBE_NEXT;		}		state = 3;		break;	case 3:		state = -1;		heap_base = allot(0);		dev->how_probe = ops->probe(dev);		if (dev->how_probe == PROBE_FAILED) {			dev = 0;			state = 4;		} else if (boot_index && (i == 0) && (boot_index != dev->type_index)) {			printf("Wrong index\n");			state = 4;		}		else {			state = 2;		}		break;	case 2:		state = -1;		if (ops->load_configuration(dev) >= 0) {			state = 1;		}		break;	case 1:		/* Any return from load is a failure */		ops->load(dev);		state = -1;		break;	case 256:		state = 0;		break;	case -3:		i = MAX_BOOT_ENTRIES;		type = BOOT_NOTHING;		/* fall through */	default:		printf("<abort>\n");		state = 4;		/* At the end goto state 0 */		if ((type >= BOOT_NOTHING) || (i >= MAX_BOOT_ENTRIES)) {			state = 0;		}		break;	}	return state;}/**************************************************************************LOADKERNEL - Try to load kernel image**************************************************************************/struct proto {	char *name;	int (*load)(const char *name,		int (*fnc)(unsigned char *, unsigned int, unsigned int, int));};static const struct proto protos[] = {#ifdef DOWNLOAD_PROTO_TFTM	{ "x-tftm", url_tftm },#endif#ifdef DOWNLOAD_PROTO_SLAM	{ "x-slam", url_slam },#endif#ifdef DOWNLOAD_PROTO_NFS	{ "nfs", nfs },#endif#ifdef DOWNLOAD_PROTO_DISK	{ "file", url_file },#endif#ifdef DOWNLOAD_PROTO_TFTP	{ "tftp", tftp },#endif};int loadkernel(const char *fname){	static const struct proto * const last_proto = 		&protos[sizeof(protos)/sizeof(protos[0])];	const struct proto *proto;	in_addr ip;	int len;	const char *name;#if 0 && defined(CAN_BOOT_DISK)	if (!memcmp(fname,"/dev/",5) && fname[6] == 'd') {		int dev, part = 0;		if (fname[5] == 'f') {			if ((dev = fname[7] - '0') < 0 || dev > 3)				goto nodisk; }		else if (fname[5] == 'h' || fname[5] == 's') {			if ((dev = 0x80 + fname[7] - 'a') < 0x80 || dev > 0x83)				goto nodisk;			if (fname[8]) {				part = fname[8] - '0';				if (fname[9])					part = 10*part + fname[9] - '0'; }			/* bootdisk cannot cope with more than eight partitions */			if (part < 0 || part > 8)				goto nodisk; }		else			goto nodisk;		return(bootdisk(dev, part, load_block));	}#endif	ip.s_addr = arptable[ARP_SERVER].ipaddr.s_addr;	name = fname;	url_port = -1;	len = 0;	while(fname[len] && fname[len] != ':') {		len++;	}	for(proto = &protos[0]; proto < last_proto; proto++) {		if (memcmp(name, proto->name, len) == 0) {			break;		}	}	if ((proto < last_proto) && (memcmp(fname + len, "://", 3) == 0)) {		name += len + 3;		if (name[0] != '/') {			name += inet_aton(name, &ip);			if (name[0] == ':') {				name++;				url_port = strtoul(name, &name, 10);			}		}		if (name[0] == '/') {			arptable[ARP_SERVER].ipaddr.s_addr = ip.s_addr;			printf( "Loading %s ", fname );			return proto->load(name + 1, load_block);		}	}	printf("Loading %@:%s ", arptable[ARP_SERVER].ipaddr, fname);#ifdef	DEFAULT_PROTO_NFS	return nfs(fname, load_block);#else	return tftp(fname, load_block);#endif}/**************************************************************************CLEANUP - shut down networking and console so that the OS may be called **************************************************************************/void cleanup(void){#ifdef	DOWNLOAD_PROTO_NFS	nfs_umountall(ARP_SERVER);#endif	/* Stop receiving packets */	eth_disable();	disk_disable();	console_fini();	initialized = 0;}/* * Local variables: *  c-basic-offset: 8 * End: */

⌨️ 快捷键说明

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