Looking further you have more bugs related to the GDT. In gdt.h you have:
Code: Select all
//8 bytes long
struct gdt_segment {
uint16_t limit_low;
uint16_t base_low;
uint8_t base_middle;
uint8_t base_high;
uint8_t access;
uint8_t granularity;
} __attribute__((packed));
That is incorrect. It should be:
Code: Select all
struct gdt_segment {
uint16_t limit_low;
uint16_t base_low;
uint8_t base_middle;
uint8_t access;
uint8_t granularity;
uint8_t base_high;
} __attribute__((packed));
In gdt.c you have:
Code: Select all
void initSegment(int num, uint32_t limit, uint32_t base, uint8_t access, uint8_t gran) {
gdt_entries[num].limit_low = limit & 0xFFFF;
gdt_entries[num].base_low = base & 0xFFFF;
gdt_entries[num].base_middle = (base >> 16) & 0xFF;
gdt_entries[num].base_high = (base >> 24) & 0xFF;
gdt_entries[num].access = access;
gdt_entries[num].granularity = (limit >> 16) & 0x0F;
gdt_entries[num].granularity |= gdt_entries[num].granularity;
}
and I think it should be:
Code: Select all
void initSegment(int num, uint32_t limit, uint32_t base, uint8_t access, uint8_t gran) {
gdt_entries[num].limit_low = limit & 0xFFFF;
gdt_entries[num].base_low = base & 0xFFFF;
gdt_entries[num].base_middle = (base >> 16) & 0xFF;
gdt_entries[num].base_high = (base >> 24) & 0xFF;
gdt_entries[num].access = access;
gdt_entries[num].granularity = (limit >> 16) & 0x0F;
gdt_entries[num].granularity |= (gran & 0xF0);
}
Your `initGdt` is this:
Code: Select all
void initGdt() {
gdt_ptr.limit = (sizeof(struct gdt_segment) * 3) - 1;
gdt_ptr.base = (unsigned int)gdt_entries;
initSegment(0, 0, 0, 0, 0);
initSegment(1, 0xFFFFFFFF, 0, 0x92, 0xCF); //kernel code segment
initSegment(2, 0, 0xFFFFFFFF, 0x92, 0xCF); //kernel data segment
//initSegment(3, 0xFFFFFFFF, 0, 0xFA, 0xCF); //user code
//initSegment(4, 0xFFFFFFFF, 0, 0xF2, 0xCF); //user code
gdt_flush();
}
where it should be:
Code: Select all
void initGdt() {
gdt_ptr.limit = (sizeof(struct gdt_segment) * 3) - 1;
gdt_ptr.base = (unsigned int)gdt_entries;
initSegment(0, 0, 0, 0, 0);
initSegment(1, 0xFFFFFFFF, 0, 0x9A, 0xCF); //kernel code segment
initSegment(2, 0xFFFFFFFF, 0, 0x92, 0xCF); //kernel data segment
//initSegment(3, 0xFFFFFFFF, 0, 0xFA, 0xCF); //user code
//initSegment(4, 0xFFFFFFFF, 0, 0xF2, 0xCF); //user code
gdt_flush();
}
---
Your linker.ld is:
Code: Select all
ENTRY(_start)
SECTIONS {
. = 2M;
.text BLOCK(4K) : ALIGN(4K) {
*(.text)
*(.text.*)
}
.rodata BLOCK(4K) : ALIGN(4K) {
*(.rodata)
*(.rodata.)
}
.data BLOCK(4K) : ALIGN(4K) {
*(.data)
*(.data.)
}
.bss BLOCK(4K) : ALIGN(4K) {
*(.bss)
*(.bss.)
}
}
A better one might be:
Code: Select all
ENTRY(_start)
SECTIONS {
. = 2M;
.text BLOCK(4K) : ALIGN(4K) {
*(.multiboot)
*(.text*)
}
.rodata BLOCK(4K) : ALIGN(4K) {
*(.rodata*)
}
.data BLOCK(4K) : ALIGN(4K) {
*(.data)
}
.bss BLOCK(4K) : ALIGN(4K) {
*(.bss)
*(COMMON)
}
}