rendered paste bodystruct MOD {
void* mod_start;
void* mod_end;
char* string;
int reserved;
};
struct MULT {
int flags;
int mem_lower;
int mem_upper;
int boot_device;
char* cmdline;
int mods_count;
struct MOD* mods_addr;
union {
struct {
int tabsize;
int strsize;
void* addr;
int reserved;
} symtab;
struct {
int num;
int size;
void* addr;
void* shndx;
} sect_header;
} syms;
int mmap_length;
void* mmap_addr;
int drives_length;
void* drives_addr;
void* config_table;
void* apm_table;
void* vbe_control_info;
void* vbe_mode_info;
int vbe_mode;
int vbe_interface_seg;
int vbe_interface_off;
int vbe_interface_len;
};
struct ELF_HEADER {
unsigned char e_ident[16];
unsigned short e_type;
unsigned short e_machine;
unsigned int e_version;
unsigned int e_entry;
unsigned int e_phoff;
unsigned int e_shoff;
unsigned int e_flags;
unsigned short e_ehsize;
unsigned short e_phentsize;
unsigned short e_phnum;
unsigned short e_shentsize;
unsigned short e_shnum;
unsigned short e_shstrndx;
};
struct PHEADER {
unsigned int p_type;
unsigned int p_offset;
unsigned int p_vaddr;
unsigned int p_paddr;
unsigned int p_filesz;
unsigned int p_memsz;
unsigned int p_flags;
unsigned int p_align;
};
struct SEGMENT {
unsigned short sizeLow;
unsigned int baseLow : 24;
unsigned int type : 4;
unsigned int system : 1;
unsigned int dpl : 2;
unsigned int present : 1;
unsigned int sizeHigh : 4;
unsigned int avail : 1;
unsigned int reserved : 1;
unsigned int dbBit : 1;
unsigned int granularity : 1;
unsigned char baseHigh;
};
struct SEGMENT ldt[2] = {
{ 0x0400, 0x200000, 0x0A, 1, 0, 1, 0, 1, 0, 1, 1, 0 },
{ 0x0400, 0x200000, 0x02, 1, 0, 1, 0, 1, 0, 1, 1, 0 }
};
struct SEGMENT gdt[3] = {
{ 0xFFFF, 0x100000, 0x0A, 1, 0, 1, 0, 1, 0, 1, 1, 0 },
{ 0xFFFF, 0x100000, 0x02, 1, 0, 1, 0, 1, 0, 1, 1, 0 },
{ sizeof(struct SEGMENT) * 2, 0, 0x02, 1, 0, 1, 0, 1, 0, 1, 0, 0 }
};
void kmain() {
short gdtr[3] = { sizeof(struct SEGMENT) * 3, (int) gdt & 0xffff, (int) gdt >> 16 };
gdt[2].baseLow = ldt;
int i;
struct MULT* x;
asm("movl %%ebx,%0" : "a=" (x) : );
struct MOD* mods = x->mods_addr;
char* exe = mods->mod_start;
struct PHEADER* phead = exe + sizeof(struct ELF_HEADER);
for (i = 0; i < 2; i++) {
int j;
for (j = 0; j < phead[i].p_filesz; j++) {
*(char*)(0x200000 + phead[i].p_vaddr + j) = *(exe + phead[i].p_offset + j);
}
}
asm("lgdt (%0)" : : "a" (gdtr));
asm("lldt %0" : : "a" ((short)((0 & 0x3) | (1 << 2) | ((2 & 0x1FFF) << 3))));
asm("movl %0,%%cs" : : "a" ((0 & 0x3) | (0 << 2) | ((0 & 0x1FFF) << 3)));
asm("movl %0,%%ds" : : "a" ((0 & 0x3) | (0 << 2) | ((1 & 0x1FFF) << 3)));
asm("jmp %0" : : "a" (phead[0].p_vaddr + 0x200000));
}