All pastes #26165 Raw Copy code Copy link Edit

Anonymous

public unlisted text v1 · immutable
#26165 ·published 2005-10-21 14:02 UTC
rendered paste body
struct 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));
}