-
- // XXX - this is supposed to jump without changing any memory -
- // but the stack has been altered by the time the code gets here.
- eoi_pic2();
- struct bregs br;
- memset(&br, 0, sizeof(br));
- br.cs = GET_BDA(jump_cs_ip) >> 16;
- br.ip = GET_BDA(jump_cs_ip);
- call16(&br);
+ // Symbols populated by the build.
+ extern u8 code32flat_start[];
+ extern u8 _reloc_min_align[];
+ extern u32 _reloc_abs_start[], _reloc_abs_end[];
+ extern u32 _reloc_rel_start[], _reloc_rel_end[];
+ extern u32 _reloc_init_start[], _reloc_init_end[];
+ extern u8 code32init_start[], code32init_end[];
+
+ // Allocate space for init code.
+ u32 initsize = code32init_end - code32init_start;
+ u32 align = (u32)&_reloc_min_align;
+ void *dest = memalign_tmp(align, initsize);
+ if (!dest)
+ panic("No space for init relocation.\n");
+
+ // Copy code and update relocs (init absolute, init relative, and runtime)
+ dprintf(1, "Relocating init from %p to %p (size %d)\n"
+ , code32init_start, dest, initsize);
+ s32 delta = dest - (void*)code32init_start;
+ memcpy(dest, code32init_start, initsize);
+ updateRelocs(dest, _reloc_abs_start, _reloc_abs_end, delta);
+ updateRelocs(dest, _reloc_rel_start, _reloc_rel_end, -delta);
+ updateRelocs(code32flat_start, _reloc_init_start, _reloc_init_end, delta);
+
+ // Call maininit() in relocated code.
+ void (*func)(void) = (void*)maininit + delta;
+ barrier();
+ func();