diff options
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/relocate.c | 104 |
1 files changed, 0 insertions, 104 deletions
diff --git a/src/core/relocate.c b/src/core/relocate.c deleted file mode 100644 index 436432e5c..000000000 --- a/src/core/relocate.c +++ /dev/null @@ -1,104 +0,0 @@ -#ifndef NORELOCATE - -#include "etherboot.h" -#include "memsizes.h" - -/* 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; - unsigned 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; - } - if (r_end < size) { - /* Avoid overflow weirdness when r_end - size < 0 */ - continue; - } - /* 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)) { - unsigned long old_addr = virt_to_phys(_text); - printf("Relocating _text from: [%lx,%lx) to [%lx,%lx)\n", - old_addr, virt_to_phys(_end), - addr, eaddr); - /* arch_relocate_to ( addr ) */ - cleanup(); - relocate_to(addr); - /* arch_relocated_from ( addr ) */ - } -} - -#endif /* NORELOCATE */ |
