My kernel, after setting up the stack, sets up the GDT via (AT&T syntax)
Code: Select all
pushl %eax
pushl %ebx
call load_default_gdt
popl %ebx
popl %eax
Code: Select all
#include <stddef.h>
#include <stdint.h>
typedef struct {
uint16_t lim1;
uint16_t base1;
uint8_t base2;
uint8_t access;
uint8_t lim2_flags;
uint8_t base3;
} gdt_entry_t;
typedef struct {
uint16_t size;
uint32_t addr;
} __attribute__ ((packed)) gdtr_t; /* Also used for the IDTR */
gdt_entry_t fill_gdt_entry (uint32_t limit, uint32_t base, uint8_t access) {
gdt_entry_t entry;
uint8_t granularity = 0;
if (limit > 0x100000) {
granularity = 1;
limit >>= 12;
}
entry.lim1 = limit & 0xFFFF;
entry.lim2_flags = (limit >> 16) | (granularity << 7) | 0x40;
entry.base1 = base & 0xFFFF;
entry.base2 = (base >> 16) & 0xFF;
entry.base3 = base >> 24;
entry.access = access;
return entry;
}
void lgdt (gdt_entry_t *entries, size_t count) {
gdtr_t gdtr;
if (count*sizeof(gdt_entry_t) > 0x10000) {
return;
}
gdtr.size = count*sizeof(gdt_entry_t)-1;
gdtr.addr = (uint32_t) entries;
__asm__ __volatile__ ( "lgdt %0" : : "m" (gdtr) : );
}
void load_default_gdt () {
gdt_entry_t entries[3];
entries[0] = fill_gdt_entry(0, 0, 0);
entries[1] = fill_gdt_entry(0xFFFFFFFF, 0, 0x99);
entries[2] = fill_gdt_entry(0xFFFFFFFF, 0, 0x93);
lgdt((gdt_entry_t*) entries, 3);
}
Code: Select all
extern uint32_t _isr222;
typedef struct {
uint16_t offset1;
uint16_t segment;
uint8_t resv;
uint8_t flags;
uint16_t offset2;
} idt_entry_t;
idt_entry_t fill_idt_entry (uint32_t offset, uint8_t flags, uint16_t segment) {
idt_entry_t entry;
entry.offset1 = offset & 0xFFFF;
entry.segment = 8*segment;
entry.resv = 0;
entry.flags = flags;
entry.offset2 = offset >> 16;
return entry;
}
void load_default_idt (uint32_t isr1) {
idt_entry_t entries[256];
size_t idx;
for (idx = 0; idx < 256; idx++) {
entries[idx] = fill_idt_entry(0,0,0);
}
entries[0xDE] = fill_idt_entry((uint32_t) isr1, 0xCE, 1);
lidt((idt_entry_t*) entries);
}
load_default_idt(_isr222);
Code: Select all
.section .text
.global _isr222
.type _isr222, @function
_isr222:
pushal
cld
call isr_222
popal
iret