rulimine/stage23/protos/linux.32.c

63 lines
1.5 KiB
C

#include <stdint.h>
#include <stdnoreturn.h>
#include <sys/gdt.h>
noreturn void linux_spinup(void *entry, void *boot_params) {
struct gdt_desc linux_gdt_descs[4];
linux_gdt_descs[0] = (struct gdt_desc){0};
linux_gdt_descs[1] = (struct gdt_desc){0};
linux_gdt_descs[2] = (struct gdt_desc){
.limit = 0xffff,
.base_low = 0x0000,
.base_mid = 0x00,
.access = 0b10011010,
.granularity = 0b11001111,
.base_hi = 0x00
};
linux_gdt_descs[3] = (struct gdt_desc){
.limit = 0xffff,
.base_low = 0x0000,
.base_mid = 0x00,
.access = 0b10010010,
.granularity = 0b11001111,
.base_hi = 0x00
};
struct gdtr linux_gdt;
linux_gdt.limit = sizeof(linux_gdt_descs) - 1;
linux_gdt.ptr = (uintptr_t)linux_gdt_descs;
asm volatile (
"lgdt %0\n\t"
"pushl $0x10\n\t"
"call 1f\n\t"
"1:\n\t"
"addl $2f-1b, (%%esp)\n\t"
"lret\n\t"
"2:\n\t"
"movl $0x18, %%eax\n\t"
"movl %%eax, %%ds\n\t"
"movl %%eax, %%es\n\t"
"movl %%eax, %%fs\n\t"
"movl %%eax, %%gs\n\t"
"movl %%eax, %%ss\n\t"
"xorl %%ebp, %%ebp\n\t"
"xorl %%edi, %%edi\n\t"
"xorl %%ebx, %%ebx\n\t"
"cld\n\t"
"jmp *%%ecx\n\t"
:
: "m"(linux_gdt), "c"(entry), "S"(boot_params)
: "memory"
);
__builtin_unreachable();
}