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

📄 menu.c

📁 linux下从网卡远程启动
💻 C
字号:
#include	"stddef.h"#include	"string.h"#include	"printf.h"#include	"ansiesc.h"#include	"misc.h"#include	"linux-asm-io.h"#include	"etherboot.h"#include	"startmenu.h"#include	"elf_boot.h"#include	"bootmenu.h"/* * 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, or (at * your option) any later version. *//*This is an example program which shows how the extension routinefeature in Etherboot 5.0 works.This program is linked to run at 0x60000, and expects to find configdata if any at 0x70000. This means the code can be up to 64kB long.When the program starts it receives 3 parameters from Etherboot:Pointer to ebinfo structurePointer to image header structure (either a tagged or ELF image header)Pointer to bootp/DHCP reply obtained by Etherboot from bootpd or DHCPDEtherboot expects this program to return an int. The values have thesemeanings:<0	Do not use0	Same as 1, for implementation reasons1	Redo tftp with possibly modified bootp record2	Redo bootp and tftp255	Exit EtherbootObserve that this program causes Etherboot to load a different programnext by modifying the contents of the filename field in the bootp recordand then returning 1. It can also send parameters to the next program bymodifying tag 129 in the bootp record.*//*Memory layout assumed by mknbi and this program0x60000-0x6FFFF    64 kB	Menu program0x70000-0x7FFFF    64 kB	Menu data (initial)*/static unsigned char	*vendortags;static unsigned char	*end_of_rfc1533;#ifdef IMAGE_FREEBSD	/* yes this is a pain FreeBSD uses this for swap, however,	   there are cases when you don't want swap and then	   you want this set to get the extra features so lets	   just set if dealing with FreeBSD.  I haven't run into	   any troubles with this but I have without it	*/static int vendorext_is_valid = 1;#elsestatic int vendorext_is_valid = 0;#endifstatic unsigned char	*motd[RFC1533_VENDOR_NUMOFMOTD] = { 0 };static unsigned char	*imagelist[RFC1533_VENDOR_NUMOFIMG] = { 0 };static inline void checkvendor(void){	union {		unsigned long	l;		unsigned char	c[4];	} u;        memcpy(u.c, vendortags, sizeof(u));        if (u.l == RFC_1048 || u.l == VEND_CMU || u.l == VEND_STAN)                vendortags += 4;        else                vendortags = 0;}static void parsebootp(){	unsigned char		*p;	unsigned int		c;	static unsigned char	vendorext_magic[] = {0xE4,0x45,0x74,0x68}; /* 銭th */	memset(motd, 0, sizeof(motd));	memset(imagelist, 0, sizeof(imagelist));	if (vendortags == 0)		return;	for (p = vendortags; (c = *p) != RFC1533_END; ) {		if (c == RFC1533_PAD) {			p++;			continue;		}#if	DEBUG > 1		printf("Tag %d\n", c);#endif		switch (c) {		case RFC1533_VENDOR_MAGIC:			if (TAG_LEN(p) >= 6				&& !memcmp(p+2, vendorext_magic, 4)				&& p[6] == RFC1533_VENDOR_MAJOR)				vendorext_is_valid = 1;			break;		case RFC1533_VENDOR_MENUOPTS:			parse_menuopts(p+2, TAG_LEN(p));			break;		default:			if (c >= RFC1533_VENDOR_MOTD && c < RFC1533_VENDOR_MOTD + RFC1533_VENDOR_NUMOFMOTD)				motd[c-RFC1533_VENDOR_MOTD] = p;			else if (c >= RFC1533_VENDOR_IMG && c < RFC1533_VENDOR_IMG + RFC1533_VENDOR_NUMOFIMG) 				imagelist[c-RFC1533_VENDOR_IMG] = p;			break;		}		p += p[1] + 2;	}	end_of_rfc1533 = p;}static void parse_elf_boot_notes(	void *notes, union infoblock **rheader, struct bootpd_t **rbootp){	unsigned char *note, *end;	Elf_Bhdr *bhdr;	Elf_Nhdr *hdr;	bhdr = notes;	if (bhdr->b_signature != ELF_BHDR_MAGIC) {		return;	}	note = ((char *)bhdr) + sizeof(*bhdr);	end  = ((char *)bhdr) + bhdr->b_size;	while (note < end) {		unsigned char *n_name, *n_desc, *next;		hdr = (Elf_Nhdr *)note;		n_name = note + sizeof(*hdr);		n_desc = n_name + ((hdr->n_namesz + 3) & ~3);		next = n_desc + ((hdr->n_descsz + 3) & ~3);		if (next > end) 			break;#if 0		printf("n_type: %x n_name(%d): n_desc(%d): \n", 			hdr->n_type, hdr->n_namesz, hdr->n_descsz);#endif		if ((hdr->n_namesz == 10) &&			(memcmp(n_name, "Etherboot", 10) == 0)) {			switch(hdr->n_type) {			case EB_BOOTP_DATA:				*rbootp = *((void **)n_desc);				break;			case EB_HEADER:				*rheader = *((void **)n_desc);				break;			default:				break;			}		}		note = next;	}}int menu(struct ebinfo *eb, union infoblock *header, struct bootpd_t *bootp){	int		i;	extern int	serial_init(void);	extern void	serial_fini(void);#ifdef	DEBUG	printf(MKNBI_VERSION "\n");#endif	parse_elf_boot_notes(eb, &header, &bootp);	/* Sanity check */	if (header->img.magic != ELF_MAGIC && header->img.magic != TAG_MAGIC) {		printf("Bad argument passed from Etherboot\n");		return (255);	}	vendortags = (unsigned char *)bootp->bootp_reply.bp_vend;	checkvendor();	parsebootp();	if (!vendorext_is_valid) {		printf("No menu vendor tags found, returning to Etherboot\n");		sleep(10);		return(2);	}#ifdef CONSOLE_SERIAL	serial_init();#endif#ifdef	ANSIESC	ansi_reset();#endif	show_motd(motd);	i = selectImage(bootp, imagelist, end_of_rfc1533);	if (i == 2) {		printf("No selection, returning to Etherboot\n");		sleep(10);	}#ifdef CONSOLE_SERIAL	serial_fini();#endif	return (i);}

⌨️ 快捷键说明

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