This commit is contained in:
Ahmad Khalifa 2024-11-26 18:29:16 +02:00 committed by GitHub
commit 91d38d869a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 121 additions and 146 deletions

View File

@ -239,10 +239,10 @@ struct preloaded_file
size_t f_size; /* file size */
struct kernel_module *f_modules; /* list of modules if any */
struct preloaded_file *f_next; /* next file */
#if defined(__amd64__) || defined(__i386__)
#if defined(__amd64__) || (defined(__i386__) && defined(EFI))
bool f_kernphys_relocatable;
#endif
#if defined(__i386__)
#if defined(__i386__) && !defined(EFI)
bool f_tg_kernel_support;
#endif
};

View File

@ -217,7 +217,7 @@ static int elf_section_header_convert(const Elf_Ehdr *ehdr, Elf_Shdr *shdr)
}
#endif
#if defined(__amd64__) || defined(__i386__)
#if defined(__amd64__) || (defined(__i386__) && defined(EFI))
static bool
is_kernphys_relocatable(elf_file_t ef)
{
@ -491,10 +491,10 @@ __elfN(loadfile_raw)(char *filename, uint64_t dest,
/* Load OK, return module pointer */
*result = (struct preloaded_file *)fp;
err = 0;
#if defined(__amd64__) || defined(__i386__)
#if defined(__amd64__) || (defined(__i386__) && defined(EFI))
fp->f_kernphys_relocatable = multiboot || is_kernphys_relocatable(&ef);
#endif
#ifdef __i386__
#if defined(__i386__) && !defined(EFI)
fp->f_tg_kernel_support = is_tg_kernel_support(fp, &ef);
#endif
goto out;

View File

@ -42,9 +42,6 @@
#include "loader_efi.h"
extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
bool exit_bs);
static int elf64_exec(struct preloaded_file *amp);
static int elf64_obj_exec(struct preloaded_file *amp);
@ -74,8 +71,6 @@ static pdp_entry_t *PT3_l, *PT3_u;
static pd_entry_t *PT2;
static pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1;
extern EFI_PHYSICAL_ADDRESS staging;
static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend,
uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry);
@ -106,8 +101,7 @@ elf64_exec(struct preloaded_file *fp)
ehdr = (Elf_Ehdr *)&(md->md_data);
trampcode = copy_staging == COPY_STAGING_ENABLE ?
(vm_offset_t)0x0000000040000000 /* 1G */ :
(vm_offset_t)0x0000000100000000; /* 4G */;
(vm_offset_t)G(1) : (vm_offset_t)G(4);
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1,
(EFI_PHYSICAL_ADDRESS *)&trampcode);
if (EFI_ERROR(err)) {
@ -122,7 +116,7 @@ elf64_exec(struct preloaded_file *fp)
trampoline = (void *)trampcode;
if (copy_staging == COPY_STAGING_ENABLE) {
PT4 = (pml4_entry_t *)0x0000000040000000; /* 1G */
PT4 = (pml4_entry_t *)G(1);
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3,
(EFI_PHYSICAL_ADDRESS *)&PT4);
if (EFI_ERROR(err)) {
@ -159,11 +153,11 @@ elf64_exec(struct preloaded_file *fp)
/*
* The L2 page slots are mapped with 2MB pages for 1GB.
*/
PT2[i] = (pd_entry_t)i * (2 * 1024 * 1024);
PT2[i] = (pd_entry_t)i * M(2);
PT2[i] |= PG_V | PG_RW | PG_PS;
}
} else {
PT4 = (pml4_entry_t *)0x0000000100000000; /* 4G */
PT4 = (pml4_entry_t *)G(4);
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 9,
(EFI_PHYSICAL_ADDRESS *)&PT4);
if (EFI_ERROR(err)) {

View File

@ -57,8 +57,6 @@ extern int elf32_loadfile_raw(char *filename, uint64_t dest,
extern int elf64_load_modmetadata(struct preloaded_file *fp, uint64_t dest);
extern int elf64_obj_loadfile(char *filename, uint64_t dest,
struct preloaded_file **result);
extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
bool exit_bs);
extern void multiboot2_exec(void *entry, uint64_t multiboot_info,
uint64_t stack);

View File

@ -40,8 +40,6 @@
#include "bootstrap.h"
#include "loader_efi.h"
extern int bi_load(char *, vm_offset_t *, vm_offset_t *, bool);
static int
__elfN(arm_load)(char *filename, uint64_t dest,
struct preloaded_file **result)

View File

@ -42,9 +42,6 @@
static int elf64_exec(struct preloaded_file *amp);
static int elf64_obj_exec(struct preloaded_file *amp);
int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
bool exit_bs);
static struct file_format arm64_elf = {
elf64_loadfile,
elf64_exec

View File

@ -28,7 +28,11 @@
#define __ELF_WORD_SIZE 64
#include <sys/param.h>
#include <sys/linker.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/elf.h>
#include <machine/pmap_pae.h>
#include <machine/segments.h>
#include <efi.h>
#include <efilib.h>
@ -37,9 +41,6 @@
#include "loader_efi.h"
extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
bool exit_bs);
static int elf64_exec(struct preloaded_file *amp);
static int elf64_obj_exec(struct preloaded_file *amp);
@ -59,40 +60,14 @@ struct file_format *file_formats[] = {
NULL
};
struct gdtr {
uint16_t size;
uint64_t ptr;
} __packed;
#define PG_V 0x001
#define PG_RW 0x002
#define PG_PS 0x080
#define GDT_P 0x00800000000000
#define GDT_E 0x00080000000000
#define GDT_S 0x00100000000000
#define GDT_RW 0x00020000000000
#define GDT_L 0x20000000000000
#define M(x) ((x) * 1024 * 1024)
#define G(x) (1ULL * (x) * 1024 * 1024 * 1024)
typedef uint64_t p4_entry_t;
typedef uint64_t p3_entry_t;
typedef uint64_t p2_entry_t;
typedef uint64_t gdt_t;
static p4_entry_t *PT4;
static p3_entry_t *PT3;
static p3_entry_t *PT3_l, *PT3_u;
static p2_entry_t *PT2;
static p2_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1;
static gdt_t *GDT;
extern EFI_PHYSICAL_ADDRESS staging;
/*
* i386's pmap_pae.h doesn't provide this, so
* just typedef our own.
*/
typedef pdpt_entry_t pml4_entry_t;
static void (*trampoline)(uint32_t stack, void *copy_finish, uint32_t kernend,
uint32_t modulep, uint64_t *pagetable, struct gdtr *gdtr, uint64_t entry);
uint32_t modulep, uint64_t *pagetable, void *gdtr, uint64_t entry);
extern void *amd64_tramp;
extern uint32_t amd64_tramp_size;
@ -105,12 +80,23 @@ extern uint32_t amd64_tramp_size;
static int
elf64_exec(struct preloaded_file *fp)
{
/*
* segments.h gives us a 32-bit gdtr, but
* we want a 64-bit one, so define our own.
*/
struct {
uint16_t rd_limit;
uint64_t rd_base;
} __packed *gdtr;
EFI_PHYSICAL_ADDRESS ptr;
EFI_ALLOCATE_TYPE type;
EFI_STATUS err;
struct file_metadata *md;
struct gdtr *gdtr;
Elf_Ehdr *ehdr;
pml4_entry_t *PT4;
pdpt_entry_t *PT3;
pd_entry_t *PT2;
struct user_segment_descriptor *gdt;
vm_offset_t modulep, kernend, trampstack;
int i;
@ -131,36 +117,47 @@ elf64_exec(struct preloaded_file *fp)
return (EFTYPE);
ehdr = (Elf_Ehdr *)&(md->md_data);
/*
* Make our temporary stack 32 bytes big, which is
* a little more than we need.
*/
ptr = G(1);
err = BS->AllocatePages(type, EfiLoaderCode,
EFI_SIZE_TO_PAGES(amd64_tramp_size + 32), &ptr);
EFI_SIZE_TO_PAGES(amd64_tramp_size), &ptr);
if (EFI_ERROR(err)) {
printf("Unable to allocate trampoline\n");
return (ENOMEM);
}
trampoline = (void *)(uintptr_t)ptr;
trampstack = ptr + amd64_tramp_size + 32;
bcopy(&amd64_tramp, trampoline, amd64_tramp_size);
/*
* Allocate enough space for the GDTR + two GDT segments +
* our temporary stack (28 bytes).
*/
#define DATASZ (sizeof(*gdtr) + \
sizeof(struct user_segment_descriptor) * 2 + 28)
ptr = G(1);
err = BS->AllocatePages(type, EfiLoaderData,
EFI_SIZE_TO_PAGES(sizeof(struct gdtr) + sizeof(uint64_t) * 2), &ptr);
EFI_SIZE_TO_PAGES(DATASZ), &ptr);
if (EFI_ERROR(err)) {
printf("Unable to allocate GDT\n");
printf("Unable to allocate GDT and stack\n");
BS->FreePages((uintptr_t)trampoline, 1);
return (ENOMEM);
}
GDT = (gdt_t *)(uintptr_t)ptr;
GDT[1] = GDT_P | GDT_E | GDT_S | GDT_RW | GDT_L; /* CS */
GDT[0] = 0;
gdtr = (struct gdtr *)&GDT[2];
gdtr->size = sizeof(uint64_t) * 2 - 1;
gdtr->ptr = (uintptr_t)GDT;
trampstack = ptr + DATASZ;
#undef DATASZ
gdt = (void *)(uintptr_t)ptr;
gdt[0] = (struct user_segment_descriptor) { 0 };
gdt[1] = (struct user_segment_descriptor) {
.sd_p = 1, .sd_long = 1, .sd_type = SDT_MEMERC
};
gdtr = (void *)(uintptr_t)(ptr +
sizeof(struct user_segment_descriptor) * 2);
gdtr->rd_limit = sizeof(struct user_segment_descriptor) * 2 - 1;
gdtr->rd_base = (uintptr_t)gdt;
if (type == AllocateMaxAddress) {
/* Copy staging enabled */
@ -171,10 +168,10 @@ elf64_exec(struct preloaded_file *fp)
if (EFI_ERROR(err)) {
printf("Unable to allocate trampoline page table\n");
BS->FreePages((uintptr_t)trampoline, 1);
BS->FreePages((uintptr_t)GDT, 1);
BS->FreePages((uintptr_t)gdt, 1);
return (ENOMEM);
}
PT4 = (p4_entry_t *)(uintptr_t)ptr;
PT4 = (pml4_entry_t *)(uintptr_t)ptr;
PT3 = &PT4[512];
PT2 = &PT3[512];
@ -203,15 +200,18 @@ elf64_exec(struct preloaded_file *fp)
PT2[i] = (i * M(2)) | PG_V | PG_RW | PG_PS;
}
} else {
pdpt_entry_t *PT3_l, *PT3_u;
pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1;
err = BS->AllocatePages(AllocateAnyPages, EfiLoaderData,
EFI_SIZE_TO_PAGES(512 * 9 * sizeof(uint64_t)), &ptr);
if (EFI_ERROR(err)) {
printf("Unable to allocate trampoline page table\n");
BS->FreePages((uintptr_t)trampoline, 1);
BS->FreePages((uintptr_t)GDT, 1);
BS->FreePages((uintptr_t)gdt, 1);
return (ENOMEM);
}
PT4 = (p4_entry_t *)(uintptr_t)ptr;
PT4 = (pml4_entry_t *)(uintptr_t)ptr;
PT3_l = &PT4[512];
PT3_u = &PT3_l[512];
@ -229,7 +229,7 @@ elf64_exec(struct preloaded_file *fp)
PT3_l[2] = (uintptr_t)PT2_l2 | PG_V | PG_RW;
PT3_l[3] = (uintptr_t)PT2_l3 | PG_V | PG_RW;
for (i = 0; i < 2048; i++) {
PT2_l0[i] = ((p2_entry_t)i * M(2)) | PG_V | PG_RW | PG_PS;
PT2_l0[i] = ((pd_entry_t)i * M(2)) | PG_V | PG_RW | PG_PS;
}
/* mapping of kernel 2G below top */
@ -248,7 +248,7 @@ elf64_exec(struct preloaded_file *fp)
printf(
"staging %#llx (%scopying) tramp %p PT4 %p GDT %p\n"
"Start @ %#llx ...\n", staging,
type == AllocateMaxAddress ? "" : "not ", trampoline, PT4, GDT,
type == AllocateMaxAddress ? "" : "not ", trampoline, PT4, gdt,
ehdr->e_entry
);

View File

@ -40,8 +40,6 @@
#include "bootstrap.h"
#include "loader_efi.h"
extern int bi_load(char *, vm_offset_t *, vm_offset_t *, bool);
static int
__elfN(exec)(struct preloaded_file *fp)
{

View File

@ -64,9 +64,6 @@
#include "geliboot.h"
#endif
int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
bool exit_bs);
static int
bi_getboothowto(char *kargs)
{

View File

@ -35,9 +35,6 @@
#include "loader_efi.h"
#define M(x) ((x) * 1024 * 1024)
#define G(x) (1ULL * (x) * 1024 * 1024 * 1024)
#if defined(__amd64__)
#include <machine/cpufunc.h>
#include <machine/specialreg.h>
@ -181,12 +178,7 @@ out:
#define EFI_STAGING_SIZE DEFAULT_EFI_STAGING_SIZE
#endif
#if defined(__aarch64__) || defined(__amd64__) || defined(__arm__) || \
defined(__riscv) || defined(__i386__)
#define EFI_STAGING_2M_ALIGN 1
#else
#define EFI_STAGING_2M_ALIGN 0
#endif
#if defined(__amd64__) || defined(__i386__)
#define EFI_STAGING_SLOP M(8)

View File

@ -41,6 +41,10 @@ enum {
extern int copy_staging;
#endif
/* Useful for various calculations */
#define M(x) ((x) * 1024 * 1024)
#define G(x) (1ULL * (x) * 1024 * 1024 * 1024)
extern EFI_LOADED_IMAGE *boot_img;
int efi_autoload(void);
@ -55,4 +59,12 @@ void * efi_translate(vm_offset_t ptr);
void efi_copy_finish(void);
void efi_copy_finish_nop(void);
#if defined(__amd64__) || defined(__i386__)
/* Need this to setup page tables */
extern EFI_PHYSICAL_ADDRESS staging;
#endif
int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
bool exit_bs);
#endif /* _LOADER_EFI_COPY_H_ */

View File

@ -28,8 +28,11 @@
#include <sys/param.h>
#include <sys/exec.h>
#include <sys/linker.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <string.h>
#include <machine/bootinfo.h>
#include <machine/pmap_pae.h>
#include <machine/elf.h>
#include <stand.h>
@ -43,16 +46,15 @@ static int elf64_obj_exec(struct preloaded_file *amp);
struct file_format amd64_elf = { elf64_loadfile, elf64_exec };
struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };
#define PG_V 0x001
#define PG_RW 0x002
#define PG_PS 0x080
/*
* i386's pmap_pae.h doesn't provide this, so
* just typedef our own.
*/
typedef pdpt_entry_t pml4_entry_t;
typedef uint64_t p4_entry_t;
typedef uint64_t p3_entry_t;
typedef uint64_t p2_entry_t;
extern p4_entry_t PT4[];
extern p3_entry_t PT3[];
extern p2_entry_t PT2[];
extern pml4_entry_t PT4[];
extern pdpt_entry_t PT3[];
extern pd_entry_t PT2[];
uint32_t entry_hi;
uint32_t entry_lo;
@ -91,11 +93,11 @@ elf64_exec(struct preloaded_file *fp)
*/
for (i = 0; i < 512; i++) {
/* Each slot of the level 4 pages points to the same level 3 page */
PT4[i] = (p4_entry_t)VTOP((uintptr_t)&PT3[0]);
PT4[i] = (pml4_entry_t)VTOP((uintptr_t)&PT3[0]);
PT4[i] |= PG_V | PG_RW;
/* Each slot of the level 3 pages points to the same level 2 page */
PT3[i] = (p3_entry_t)VTOP((uintptr_t)&PT2[0]);
PT3[i] = (pdpt_entry_t)VTOP((uintptr_t)&PT2[0]);
PT3[i] |= PG_V | PG_RW;
/* The level 2 page slots are mapped with 2MB pages for 1GB. */

View File

@ -42,7 +42,6 @@
#include "bootstrap.h"
#include "kboot.h"
#include "bootstrap.h"
#include "platform/acfreebsd.h"
#include "acconfig.h"
@ -70,8 +69,11 @@ extern uint32_t efi_map_size;
extern vm_paddr_t efi_map_phys_src; /* From DTB */
extern vm_paddr_t efi_map_phys_dst; /* From our memory map metadata module */
/* Usually provided by loader_efi.h */
#ifndef EFI
int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
bool exit_bs);
#endif
static struct file_format arm64_elf = {
elf64_loadfile,

View File

@ -56,6 +56,10 @@
static EFI_GUID acpi_guid = ACPI_TABLE_GUID;
static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
#else
/* Usually provided by loader_efi.h */
extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
bool exit_bs);
#endif
#ifdef EFI
@ -64,9 +68,6 @@ static EFI_GUID acpi20_guid = ACPI_20_TABLE_GUID;
#define LOADER_PAGE_SIZE PAGE_SIZE
#endif
extern int bi_load(char *args, vm_offset_t *modulep, vm_offset_t *kernendp,
bool exit_bs);
static int elf64_exec(struct preloaded_file *amp);
static int elf64_obj_exec(struct preloaded_file *amp);
@ -121,8 +122,6 @@ static pd_entry_t *PT2_l0, *PT2_l1, *PT2_l2, *PT2_l3, *PT2_u0, *PT2_u1;
static pdp_entry_t *PT3;
static pd_entry_t *PT2;
extern EFI_PHYSICAL_ADDRESS staging;
static void (*trampoline)(uint64_t stack, void *copy_finish, uint64_t kernend,
uint64_t modulep, pml4_entry_t *pagetable, uint64_t entry);
#endif
@ -210,8 +209,7 @@ elf64_exec(struct preloaded_file *fp)
#ifdef EFI
trampcode = copy_staging == COPY_STAGING_ENABLE ?
(vm_offset_t)0x0000000040000000 /* 1G */ :
(vm_offset_t)0x0000000100000000; /* 4G */;
(vm_offset_t)G(1) : (vm_offset_t)G(4);
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 1,
(EFI_PHYSICAL_ADDRESS *)&trampcode);
if (EFI_ERROR(err)) {
@ -235,7 +233,7 @@ elf64_exec(struct preloaded_file *fp)
#ifdef EFI
if (copy_staging == COPY_STAGING_ENABLE) {
PT4 = (pml4_entry_t *)0x0000000040000000; /* 1G */
PT4 = (pml4_entry_t *)G(1);
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 3,
(EFI_PHYSICAL_ADDRESS *)&PT4);
if (EFI_ERROR(err)) {
@ -272,11 +270,11 @@ elf64_exec(struct preloaded_file *fp)
/*
* The L2 page slots are mapped with 2MB pages for 1GB.
*/
PT2[i] = (pd_entry_t)i * (2 * 1024 * 1024);
PT2[i] = (pd_entry_t)i * M(2);
PT2[i] |= PG_V | PG_RW | PG_PS;
}
} else {
PT4 = (pml4_entry_t *)0x0000000100000000; /* 4G */
PT4 = (pml4_entry_t *)G(4);
err = BS->AllocatePages(AllocateMaxAddress, EfiLoaderData, 9,
(EFI_PHYSICAL_ADDRESS *)&PT4);
if (EFI_ERROR(err)) {

View File

@ -31,9 +31,10 @@
#ifdef DEBUG
#include <machine/_inttypes.h>
#endif
#include <string.h>
#include <i386/include/bootinfo.h>
#include <vm/vm.h>
#include <vm/pmap.h>
#include <machine/elf.h>
#include <machine/segments.h>
#include <stand.h>
#include "bootstrap.h"
@ -45,35 +46,21 @@ static int elf64_obj_exec(struct preloaded_file *amp);
struct file_format amd64_elf = { elf64_loadfile, elf64_exec };
struct file_format amd64_elf_obj = { elf64_obj_loadfile, elf64_obj_exec };
#define MSR_EFER 0xc0000080
#define EFER_LME 0x00000100
#define EFER_LMA 0x00000400 /* Long mode active (R) */
#define CR4_PAE 0x00000020
#define CR4_VMXE (1UL << 13)
#define CR4_PSE 0x00000010
#define CR0_PG 0x80000000
#define CR0_PE 0x00000001 /* Protected mode Enable */
#define CR0_NE 0x00000020 /* Numeric Error enable (EX16 vs IRQ13) */
#define PG_V 0x001
#define PG_RW 0x002
#define PG_PS 0x080
typedef uint64_t p4_entry_t;
typedef uint64_t p3_entry_t;
typedef uint64_t p2_entry_t;
#define GUEST_NULL_SEL 0
#define GUEST_CODE_SEL 1
#define GUEST_DATA_SEL 2
#define GUEST_GDTR_LIMIT (3 * 8 - 1)
static void
setup_freebsd_gdt(uint64_t *gdtr)
setup_freebsd_gdt(struct user_segment_descriptor *gdt)
{
gdtr[GUEST_NULL_SEL] = 0;
gdtr[GUEST_CODE_SEL] = 0x0020980000000000;
gdtr[GUEST_DATA_SEL] = 0x0000900000000000;
gdt[GUEST_NULL_SEL] = (struct user_segment_descriptor) { 0 };
gdt[GUEST_CODE_SEL] = (struct user_segment_descriptor) {
.sd_p = 1, .sd_long = 1, .sd_type = SDT_MEME
};
gdt[GUEST_DATA_SEL] = (struct user_segment_descriptor) {
.sd_p = 1, .sd_type = SDT_MEMRO
};
}
/*
@ -90,10 +77,10 @@ elf64_exec(struct preloaded_file *fp)
int err;
int i;
uint32_t stack[1024];
p4_entry_t PT4[512];
p3_entry_t PT3[512];
p2_entry_t PT2[512];
uint64_t gdtr[3];
pml4_entry_t PT4[512];
pdp_entry_t PT3[512];
pd_entry_t PT2[512];
struct user_segment_descriptor gdt[3];
if ((md = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL)
return(EFTYPE);
@ -122,11 +109,11 @@ elf64_exec(struct preloaded_file *fp)
*/
for (i = 0; i < 512; i++) {
/* Each slot of the level 4 pages points to the same level 3 page */
PT4[i] = (p4_entry_t) 0x3000;
PT4[i] = (pml4_entry_t) 0x3000;
PT4[i] |= PG_V | PG_RW;
/* Each slot of the level 3 pages points to the same level 2 page */
PT3[i] = (p3_entry_t) 0x4000;
PT3[i] = (pdp_entry_t) 0x4000;
PT3[i] |= PG_V | PG_RW;
/* The level 2 page slots are mapped with 2MB pages for 1GB. */
@ -154,9 +141,9 @@ elf64_exec(struct preloaded_file *fp)
CALLBACK(setcr, 3, 0x2000);
CALLBACK(setcr, 0, CR0_PG | CR0_PE | CR0_NE);
setup_freebsd_gdt(gdtr);
CALLBACK(copyin, gdtr, 0x5000, sizeof(gdtr));
CALLBACK(setgdt, 0x5000, sizeof(gdtr));
setup_freebsd_gdt(gdt);
CALLBACK(copyin, gdt, 0x5000, sizeof(gdt));
CALLBACK(setgdt, 0x5000, sizeof(gdt));
CALLBACK(exec, ehdr->e_entry);