From f44d4ad7689d468739f56ac1b424cacf62835610 Mon Sep 17 00:00:00 2001 From: Xnoe Date: Tue, 12 Oct 2021 21:41:31 +0100 Subject: [PATCH] Fixed bug in GDT length calculation in bootloader. Kernel now loads its own GDT so it doesn't clobber itself while touching memory. ATAPIO now loads its own copy of the boot sector so it isn't reliant on 0x7000 being mapped. Removed debug printf statements from a lot of places. --- Makefile | 14 ++++++-- src/boot/boot.asm | 2 +- src/boot_stage2/main.c | 4 +-- src/kernel/allocate.c | 1 - src/kernel/atapio.c | 12 ++++--- src/kernel/entry.asm | 6 ++++ src/kernel/gdt.c | 76 ++++++++++++++++++++++++++++++++++++++++++ src/kernel/gdt.h | 32 ++++++++++++++++++ src/kernel/kernel.c | 19 +++-------- src/kernel/kernel.ld | 3 +- 10 files changed, 141 insertions(+), 28 deletions(-) create mode 100644 src/kernel/entry.asm create mode 100644 src/kernel/gdt.c create mode 100644 src/kernel/gdt.h diff --git a/Makefile b/Makefile index 14d2fd5..9e1c8dc 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,9 @@ CFLAGS = -m32 -mgeneral-regs-only -nostdlib -fno-builtin -fno-exceptions -fno-le LDFLAGS = DISK_IMG_FILES = build/kernel/kernel.bin -KERNEL_OBJS = build/c_code_entry.o build/kernel/screenstuff.o build/kernel/io.o build/kernel/idt.o build/kernel/keyboard.o build/kernel/strings.o build/kernel/atapio.o build/kernel/kernel.o build/kernel/paging.o build/kernel/allocate.o +KERNEL_OBJS = build/kernel/entry.o build/kernel/screenstuff.o build/kernel/io.o build/kernel/idt.o build/kernel/keyboard.o \ + build/kernel/strings.o build/kernel/atapio.o build/kernel/kernel.o build/kernel/paging.o build/kernel/allocate.o \ + build/kernel/gdt.o STAGE2_OBS = build/c_code_entry.o build/boot_stage2/io.o build/boot_stage2/atapio.o build/boot_stage2/strings.o build/boot_stage2/screenstuff.o build/boot_stage2/stage2.o build/boot_stage2/paging.o run: disk.img @@ -31,9 +33,14 @@ clean: build/boot/boot.bin: src/boot/boot.asm nasm $< -o $@ +# Boot Stage 2 build/boot_stage2/boot.bin: src/boot_stage2/boot_stage2.ld $(STAGE2_OBS) ld $(LDFLAGS) -T $< $(STAGE2_OBS) +build/boot_stage2/%.o: src/boot_stage2/%.c + gcc $(CFLAGS) -o $@ -c $< + +# Kernel build/kernel/kernel.bin: src/kernel/kernel.ld $(KERNEL_OBJS) ld $(LDFLAGS) -T $< $(KERNEL_OBJS) @@ -43,8 +50,9 @@ build/boot_stage2/stage2.o: src/boot_stage2/main.c build/kernel/%.o: src/kernel/%.c gcc $(CFLAGS) -o $@ -c $< -build/boot_stage2/%.o: src/boot_stage2/%.c - gcc $(CFLAGS) -o $@ -c $< +build/kernel/%.o: src/kernel/%.asm + nasm -felf32 $< -o $@ +# Generic build/%.o: src/%.asm nasm -felf32 $< -o $@ \ No newline at end of file diff --git a/src/boot/boot.asm b/src/boot/boot.asm index 0dbc1a1..fd9a94a 100644 --- a/src/boot/boot.asm +++ b/src/boot/boot.asm @@ -134,7 +134,7 @@ data: db 0 gdt_end: gdt_desc: - dw gdt_desc - gdt_end - 1 + dw gdt_end - gdt - 1 dd gdt TIMES 510 - ($ - $$) db 0 diff --git a/src/boot_stage2/main.c b/src/boot_stage2/main.c index b358dd1..1d6cb02 100644 --- a/src/boot_stage2/main.c +++ b/src/boot_stage2/main.c @@ -107,7 +107,7 @@ void main() { PTE** kernel_page_tables = 0x521000; // Mark unavailable bitmap to 0x522000 - mark_unavailble(bitmap, 0x522000 - (uint32_t)bitmap); + mark_unavailble(bitmap, 0x4000000); // Now we want to map some stuff. // But first, we should load the kernel somewhere @@ -124,7 +124,7 @@ void main() { // Map the bitmap map_many_4k_phys_to_virt(0x100000, 0xc0600000, kernel_page_directory, kernel_page_tables, 32); - map_many_4k_phys_to_virt(0x7000, 0x7000, kernel_page_directory, kernel_page_tables, 2); + map_4k_phys_to_virt(0x8000, 0x8000, kernel_page_directory, kernel_page_tables); map_many_4k_phys_to_virt(0x8a000, 0x8a000, kernel_page_directory, kernel_page_tables, 6); load_file("KERNEL BIN", kernel_location); diff --git a/src/kernel/allocate.c b/src/kernel/allocate.c index 248acb4..37eda1c 100644 --- a/src/kernel/allocate.c +++ b/src/kernel/allocate.c @@ -57,7 +57,6 @@ void* dumb_alloc(uint32_t size) { while (size > 0) { for (; get_bit(last_free_page, bitmap) == 0; last_free_page++); - printf("Free page: %d\n", last_free_page); uint32_t phys_addr = last_free_page * 4096; diff --git a/src/kernel/atapio.c b/src/kernel/atapio.c index cfecf28..6991018 100644 --- a/src/kernel/atapio.c +++ b/src/kernel/atapio.c @@ -23,12 +23,14 @@ uint16_t sectorsPerFAT; void init_atapio() { rootDirEntries = (uint8_t*)dumb_alloc(8192); FAT1 = (uint16_t*)dumb_alloc(512 * 34); - printf("RDE: %x\nFAT1: %x\n", rootDirEntries, FAT1); - countReserved = *(uint16_t*)0x7c0e; - countFATs = *(uint8_t*)0x7c10; - countRDEs = *(uint16_t*)0x7c11; - sectorsPerFAT = *(uint16_t*)0x7c16; + uint32_t boot_sector = (uint32_t)dumb_alloc(4096); + read_sectors(0, 1, (uint8_t*)boot_sector); + + countReserved = *((uint16_t*)(boot_sector + 0x0e)); + countFATs = *((uint8_t*)(boot_sector + 0x10)); + countRDEs = *((uint16_t*)(boot_sector + 0x11)); + sectorsPerFAT = *((uint16_t*)(boot_sector + 0x16)); // Select Drive 0 on the Primary Bus outb(0x1f6, 0xa0); diff --git a/src/kernel/entry.asm b/src/kernel/entry.asm new file mode 100644 index 0000000..7b8e693 --- /dev/null +++ b/src/kernel/entry.asm @@ -0,0 +1,6 @@ +[BITS 32] + +_start: + call main + +extern main \ No newline at end of file diff --git a/src/kernel/gdt.c b/src/kernel/gdt.c new file mode 100644 index 0000000..05de68c --- /dev/null +++ b/src/kernel/gdt.c @@ -0,0 +1,76 @@ +#include "gdt.h" + +gdt_entry gdt[] = { + (gdt_entry){ // Null Segment + .limit_lo = 0, + .limit_hi = 0, + .base_lo = 0, + .base_mid = 0, + .base_hi = 0, + .accessed = 0, + .read_write = 0, + .direction = 0, + .executable = 0, + .system_segment = 0, + .privilege = 0, + .present = 0, + .size = 0, + .granularity = 0, + + .__ignored__ = 0, + }, + (gdt_entry){ // Code Segment + .limit_lo = 0xffff, + .limit_hi = 0xf, + .base_lo = 0, + .base_mid = 0, + .base_hi = 0, + .accessed = 0, + .read_write = 1, + .direction = 0, + .executable = 1, + .system_segment = 1, + .privilege = 0, + .present = 1, + .size = 1, + .granularity = 1, + + .__ignored__ = 0, + }, + (gdt_entry){ // Data Segment + .limit_lo = 0xffff, + .limit_hi = 0xf, + .base_lo = 0, + .base_mid = 0, + .base_hi = 0, + .accessed = 0, + .read_write = 1, + .direction = 0, + .executable = 0, + .system_segment = 1, + .privilege = 0, + .present = 1, + + .size = 1, + .granularity = 1, + + .__ignored__ = 0, + } +}; + +gdt_descr descr = (gdt_descr){ + .size = sizeof(gdt) - 1, + .offset = gdt, +}; + +__attribute__((far)) void far_call() {} + +void init_gdt() { + asm volatile("lgdt %0;" + "mov $0x10, %%eax;" + "mov %%eax, %%ss;" + "mov $0x10, %%eax;" + "mov %%eax, %%ds" : : "m" (descr)); + + far_call(); +} \ No newline at end of file diff --git a/src/kernel/gdt.h b/src/kernel/gdt.h new file mode 100644 index 0000000..225ab1c --- /dev/null +++ b/src/kernel/gdt.h @@ -0,0 +1,32 @@ +#ifndef GDT_H +#define GDT_H + +#include "types.h" + +typedef struct { + uint32_t limit_lo : 16; + uint32_t base_lo : 16; + + uint32_t base_mid : 8; + uint32_t accessed : 1; + uint32_t read_write : 1; + uint32_t direction : 1; + uint32_t executable : 1; + uint32_t system_segment : 1; + uint32_t privilege : 2; + uint32_t present : 1; + + uint32_t limit_hi : 4; + uint32_t __ignored__ : 2; + uint32_t size : 1; + uint32_t granularity : 1; + + uint32_t base_hi : 8; +}__attribute__((packed)) gdt_entry; + +typedef struct { + uint16_t size; + uint32_t offset; +}__attribute__((packed)) gdt_descr; + +#endif \ No newline at end of file diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index f89078e..d64fdab 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -5,11 +5,12 @@ #include "keyboard.h" #include "strings.h" #include "atapio.h" +#include "gdt.h" int main() { + init_gdt(); init_idt(); init_term(); -// init_allocator(); printf("Hello, World!\n\nWe are running XnoeOS Code in C now, Protected Mode has been achieved (as well as Virtual Memory / Paging!!!) and everything is working super nicely!\n\nHow wonderful!\n\nNow I just need to hope my print function works properly too~~\n"); @@ -20,19 +21,11 @@ int main() { enable_idt(); init_atapio(); - //while (1); - uint8_t sector[512]; read_sector(0, sector); - printf("OEM ID: %s\n", (char*)(sector+0x3)); - - char hellotxt[1024]; - - load_file("HELLO TXT", hellotxt); - printf("%s", hellotxt); - + uint8_t* filebuffer = (uint8_t*)dumb_alloc(0x3000); while (1) { printf(">>> "); @@ -43,7 +36,6 @@ int main() { char* rest = split_on_first(' ', buffer); - if (strcmp(buffer, "help", 4)) { printf( "XnoeOS 32 Bit Mode Help.\n" @@ -64,7 +56,6 @@ int main() { printf("%s\n", rest); } else if (strcmp(buffer, "type", 4)) { char filenamebuffer[12]; - uint8_t* filebuffer = 0x1006400; decode_filename(rest, filenamebuffer); if (!file_exists(filenamebuffer)) { @@ -72,8 +63,8 @@ int main() { continue; } - for (int i=0; i<1024; i++) - hellotxt[i] = 0; + for (int i=0; i<4096; i++) + filebuffer[i] = 0; load_file(filenamebuffer, filebuffer); printf(filebuffer); diff --git a/src/kernel/kernel.ld b/src/kernel/kernel.ld index e1ee885..2a37cd5 100644 --- a/src/kernel/kernel.ld +++ b/src/kernel/kernel.ld @@ -7,9 +7,8 @@ SECTIONS { . = 0xc0000000; .text : { - build/c_code_entry.o(.text) + build/kernel/entry.o(.text) build/kernel/kernel.o(.text) build/kernel/*(.text) - heap_section = .; } } \ No newline at end of file