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

📄 relocate.c

📁 linux下从网卡远程启动
💻 C
字号:
#include "etherboot.h"#if defined(RELOCATE)/* by Eric Biederman *//* On some platforms etherboot is compiled as a shared library, and we use * the ELF pic support to make it relocateable.  This works very nicely * for code, but since no one has implemented PIC data yet pointer * values in variables are a a problem.  Global variables are a * pain but the return addresses on the stack are the worst.  On these * platforms relocate_to will restart etherboot, to ensure the stack * is reinitialize and hopefully get the global variables * appropriately reinitialized as well. *  */void relocate(void){	unsigned long addr, eaddr, size;	int i;	/* Walk through the memory map and find the highest address	 * below 4GB that etherboot will fit into.  Ensure etherboot	 * lies entirely within a range with A20=0.  This means that	 * even if something screws up the state of the A20 line, the	 * etherboot code is still visible and we have a chance to	 * diagnose the problem.	 */	/* First find the size of etherboot */	addr = virt_to_phys(_text);	eaddr = virt_to_phys(_end);	size = (eaddr - addr + 0xf) & ~0xf;	/* If the current etherboot is beyond MAX_ADDR pretend it is	 * at the lowest possible address.	 */	if (eaddr > MAX_ADDR) {		eaddr = 0;	}	for(i = 0; i < meminfo.map_count; i++) {		unsigned long r_start, r_end;		if (meminfo.map[i].type != E820_RAM) {			continue;		}		if (meminfo.map[i].addr > MAX_ADDR) {			continue;		}		if (meminfo.map[i].size > MAX_ADDR) {			continue;		}		r_start = meminfo.map[i].addr;		r_end = r_start + meminfo.map[i].size;		/* Make the addresses 16 byte (128 bit) aligned */		r_start = (r_start + 15) & ~15;		r_end = r_end & ~15;		if (r_end < r_start) {			r_end = MAX_ADDR;		}		/* Shrink the range down to use only even megabytes		 * (i.e. A20=0).		 */		if ( r_end & 0x100000 ) {			/* If r_end is in an odd megabyte, round down			 * r_end to the top of the next even megabyte.			 */			r_end = r_end & ~0xfffff;		} else if ( ( r_end - size ) & 0x100000 ) {			/* If r_end is in an even megabyte, but the			 * start of Etherboot would be in an odd			 * megabyte, round down to the top of the next			 * even megabyte.			*/			r_end = ( r_end - 0x100000 ) & ~0xfffff;		}		/* If we have rounded down r_end below r_ start, skip		 * this block.		 */		if ( r_end < r_start ) {			continue;		}		if (eaddr < r_end - size) {			addr = r_end - size;			eaddr = r_end;		}	}	if (addr != virt_to_phys(_text)) {		printf("Relocating _text from: [%lx,%lx) to [%lx,%lx)\n",			virt_to_phys(_text), virt_to_phys(_end),			addr, eaddr);		arch_relocate_to(addr);		cleanup();		relocate_to(addr);	}}#endif /* RELOCATE */

⌨️ 快捷键说明

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