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

📄 first32.c

📁 linux下从网卡远程启动
💻 C
📖 第 1 页 / 共 2 页
字号:
#include	"stddef.h"#include	"string.h"#include	"linux-asm-io.h"#include	"etherboot.h"#include	"start32.h"#include	"elf_boot.h"#ifndef	FIRST32DOS#define	FIRST32LINUX	1#endif#ifdef	FIRST32LINUX#define SERIAL_CONSOLE 0/* * 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. *//*Memory layout assumed by mknbi and this program0x07C00-0x07FFF   0.5 kB	floppy boot sector if loaded from floppy0x0F???-0x0FFFF     ? kB	large Etherboot data buffers (deprecated)0x10000-0x8FFFF 512.0 kB	kernel (from tagged image)0x90000-0x901FF	  0.5 kB	Linux floppy boot sector (from Linux image)0x90200-0x921FF	  8.0 kB	kernel setup (from Linux image)0x92200-0x923FF	  0.5 kB	tagged image header ("directory")0x92400-0x927FF	  1.0 kB	kernel parameters (generated by mknbi)0x92800-0x93FFF	  6.0 kB	this program (generated by mknbi)0x94000-0x9FFFF	 48.0 kB	Etherboot (top few kB may be used by BIOS)				Normally Etherboot starts at 0x940000x100000-			kernel (if bzImage) (from tagged image)after bzImage kernel		ramdisk (optional) (from tagged image)				moved to below top of memory by this program				but not higher than 896kB or what the				limit in setup.S says*/#define		PARAMSIZE	512extern void printf(const char *, ...);extern int sprintf(char *, const char *, ...);extern void xstart(unsigned long);extern void exit(int);#ifdef	FIRST32ELFstatic Elf32_Phdr	*seg[S_END] = { 0 };#elsestatic struct segment	*seg[S_END] = { 0 };#endifstatic unsigned char 	*ip, *op;static short		*vgamode;static struct bootp_t	*bp;static unsigned char	*vendortags;unsigned long		top_of_initrd = 0;static enum { RD_TOP, RD_ASIS, RD_HEXADDR } rdmode = RD_TOP;static unsigned long	rdaddr;#if SERIAL_CONSOLE/* Base Address */#define TTYS0 0x3f8/* Data */#define TTYS0_RBR (TTYS0+0x00)#define TTYS0_TBR (TTYS0+0x00)/* Control */#define TTYS0_IER (TTYS0+0x01)#define TTYS0_IIR (TTYS0+0x02)#define TTYS0_FCR (TTYS0+0x02)#define TTYS0_LCR (TTYS0+0x03)#define TTYS0_MCR (TTYS0+0x04)#define TTYS0_DLL (TTYS0+0x00)#define TTYS0_DLM (TTYS0+0x01)/* Status */#define TTYS0_LSR (TTYS0+0x05)#define TTYS0_MSR (TTYS0+0x06)#define TTYS0_SCR (TTYS0+0x07)static void ttys0_tx_byte(unsigned byte){	while((inb(TTYS0_LSR) & 0x20) == 0)		;	outb(byte, TTYS0_TBR);}#endifvoid putchar(int c){	if (c == '\n')		putchar('\r');#if SERIAL_CONSOLE	ttys0_tx_byte(c);#endif	console_putc(c);}static inline void quit(void){	printf("Bad argument\n");	exit(0);}static void nomem(void){	printf("Out of parameter space\n");	exit(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;}#ifdef	FIRST32ELFstatic inline void locate_segs(union infoblock *header){	int		i;	Elf32_Phdr	*s;	s = (Elf32_Phdr *)((char *)header + header->ehdr.e_phoff);	for (i = 0; i < S_END && i < header->ehdr.e_phnum; i++, s++) {		seg[i] = s;#if	DEBUG > 1		printf("%d %#X\n", i, s->p_paddr);#endif	}}#elsestatic inline void locate_segs(union infoblock *header){	int		i;	struct segment	*s;	s = (struct segment *)((char *)header + sizeof(struct imgheader)		+ ((header->img.length & 0xF0) >> 2));	for (i = 0; i < S_END; i++, s++) {		seg[i] = s;#if	DEBUG > 1		printf("%d %#X\n", i, s->p_paddr);#endif		if (s->flags & F_FINAL)			break;		s = (struct segment *)((char *)s + ((s->lengths & 0xF0) >> 2));	}}#endif	/* !FIRST32ELF *//* *	Find DHCP vendor tag, return pointer to tag length */static unsigned char *gettag(unsigned int tag){	unsigned char		*p;	unsigned char		c;	static unsigned char	emptytag[] = { 0, 0 };	if (vendortags == 0)		return (emptytag);	for (p = vendortags; (c = *p) != RFC1533_END; ) {		if (c == RFC1533_PAD)			p++;		else if (c == tag)			return (p + 1);		else			p += p[1] + 2;	}	return (emptytag);}static void outtag(unsigned char *value){	int			len;	len = *value++;	if (op + len > ip)		nomem();	while (len-- > 0)		*op++ = *value++;}/* Return 1 if s2 is a prefix of s1 */static int strprefix(const unsigned char *s1, const unsigned char *s2){	while (*s1 != '\0' && *s2 != '\0' && *s1++ == *s2++)		;	/* Have we reached the end of s2? */	return (*s2 == '\0');}enum keyword { K_VGA, K_NFSROOT, K_IP, K_RDBASE, K_MEM };static inline int match_keyword(const unsigned char *start){	if (strprefix(start, "vga"))		return (K_VGA);	if (strprefix(start, "nfsroot"))		return (K_NFSROOT);	if (strprefix(start, "ip"))		return (K_IP);	if (strprefix(start, "rdbase"))		return (K_RDBASE);	if (strprefix(start, "mem"))		return (K_MEM);	return (-1);}#define	isws(c)	((c) == ' ' || (c) == '\t')static inline int copy_and_match(void){	int			c;	unsigned char		*start;	start = ip;	/* Stop copying at = if it exists */	while ((c = *ip) != '\0' && !isws(c) && c != '=') {		*op++ = *ip++;	}	if (c == '=') {		ip++;		*op++ = '=';		return (match_keyword(start));	}	return (-1);}static unsigned long gethex(const unsigned char *p){	unsigned long		value = 0;	for (;;) {		int c = *p++;		if (c >= '0' && c <= '9')			c -= '0';		else if (c >= 'a' && c <= 'f')			c -= 'a' - 10;		else if (c >= 'A' && c <= 'F')			c -= 'A' - 10;		else			break;		value <<= 4;		value |= c;	}	return (value);}static int getdec(const unsigned char *p){	int			value = 0, sign = 0;	if (*p == '-') {		sign = 1;		p++;	}	for (;;) {		int c = *p++;		if (c >= '0' && c <= '9')			c -= '0';		else			break;		value *= 10;		value += c;	}	return (sign ? -value : value);}static void copy_nonws(void){	int			c;	/* Copy up to next whitespace */	while ((c = *ip) != '\0' && !isws(c))		*op++ = *ip++;}static void discard_arg(void){	int			c;	/* Discard up to next whitespace */	while ((c = *ip) != '\0' && !isws(c))		ip++;}static int outip(const unsigned char *p){	long		ip;	if (*p == 0)		return (0);	memcpy(&ip, p + 1, sizeof(ip));	return sprintf(op, "%@", ip);}static inline void subst_value(int kwindex){	int			c;	unsigned char		*p;	if (kwindex == K_VGA) {		/* backup over "vga=" */		op -= sizeof("vga=") - 1;		if (strprefix(ip, "ask"))			c = -3;		else if (strprefix(ip, "extended"))			c = -2;		else if (strprefix(ip, "normal"))			c = -1;		else if (strprefix(ip, "0x"))			c = gethex(ip+2);		else	/* assume decimal mode number */			c = getdec(ip);		*vgamode = c;		discard_arg();	} else if (kwindex == K_NFSROOT && strprefix(ip, "rom") &&		(ip[3] == '\0' || isws(ip[3]))) {		outtag(gettag(RFC1533_ROOTPATH));		discard_arg();	} else if (kwindex == K_IP && strprefix(ip, "rom") &&		(ip[3] == '\0' || isws(ip[3]))) {		long		ip;		op += sprintf(op, "%@:%@:", bp->bp_yiaddr, bp->bp_siaddr);		p = gettag(RFC1533_GATEWAY);		op += outip(p);		*op++ = ':';		p = gettag(RFC1533_NETMASK);		op += outip(p);		*op++ = ':';		outtag(gettag(RFC1533_HOSTNAME));		p = gettag(RFC1533_VENDOR_ETHDEV);		if (*p)			*op++ = ':';		outtag(p);		discard_arg();	} else if (kwindex == K_RDBASE) {		if (strprefix(ip, "top"))			rdmode = RD_TOP;		else if (strprefix(ip, "asis"))			rdmode = RD_ASIS;		else if (strprefix(ip, "0x")) {			rdmode = RD_HEXADDR;			rdaddr = gethex(ip+2);		}		discard_arg();	} else if (kwindex == K_MEM) {		unsigned char 	*p;		unsigned long	memsize;

⌨️ 快捷键说明

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