From e2bb3ff6340b148725d5680239ac70af4e2501b8 Mon Sep 17 00:00:00 2001 From: Xnoe Date: Tue, 12 Oct 2021 00:53:02 +0100 Subject: [PATCH] The kernel is now actually useable with paging enabled. --- Makefile | 3 +- src/boot_stage2/main.c | 6 +++- src/kernel/allocate.c | 72 ++++++++++++++++++++++++++++++++++++++++ src/kernel/allocate.h | 15 +++++++++ src/kernel/atapio.c | 8 +++-- src/kernel/atapio.h | 1 + src/kernel/kernel.c | 8 +++-- src/kernel/paging.c | 2 +- src/kernel/screenstuff.c | 2 +- 9 files changed, 108 insertions(+), 9 deletions(-) create mode 100644 src/kernel/allocate.c create mode 100644 src/kernel/allocate.h diff --git a/Makefile b/Makefile index a30d12e..14d2fd5 100644 --- a/Makefile +++ b/Makefile @@ -2,7 +2,7 @@ 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 +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 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 @@ -23,6 +23,7 @@ prepare: mkdir -p build/boot mkdir -p build/boot_stage2 mkdir -p build/kernel + mountpoint img.d | grep not || umount img.d clean: rm -rf build diff --git a/src/boot_stage2/main.c b/src/boot_stage2/main.c index 7011b08..b358dd1 100644 --- a/src/boot_stage2/main.c +++ b/src/boot_stage2/main.c @@ -119,9 +119,13 @@ void main() { map_4k_phys_to_virt((uint32_t)kernel_page_directory, 0xc0100000, kernel_page_directory, kernel_page_tables); // Map the page directory to 0xc0100000 map_many_4k_phys_to_virt(0x121000, 0xc0101000, kernel_page_directory, kernel_page_tables, 1024); // Map 1024 pages from 0x121000 to 0xc0101000 map_4k_phys_to_virt(0xb8000, 0xc0501000, kernel_page_directory, kernel_page_tables); // Map 0xb8000 (video) to 0xc0501000 + map_4k_phys_to_virt(0x521000, 0xc0502000, kernel_page_directory, kernel_page_tables); // Map the PTE** data, we'll need to convert the pointers to point at kernel space at some point. + + // 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(0x8f000, 0x8f000, 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 new file mode 100644 index 0000000..248acb4 --- /dev/null +++ b/src/kernel/allocate.c @@ -0,0 +1,72 @@ +#include "allocate.h" + +uint8_t* bitmap = 0xc0600000; +PDE* kernel_page_directory = 0xc0100000; +PTE** kernel_page_tables = 0xc0502000; + +uint32_t kernel_allocate_area = 0xf0000000; + +uint32_t last_free_page = 0; + +/*void init_allocator() { + for (int i=0; i<1024; i++) { + kernel_page_tables[i] = 0xc0101000 + 0x1000*i; + } +}*/ // Don't do this. + +void set_bit(uint32_t offset, uint8_t* buffer) { + uint32_t index = offset / 8; + uint32_t bit = offset % 8; + + buffer[index] |= (1<<(7 - bit)); +} + +uint8_t get_bit(uint32_t offset, uint8_t* buffer) { + uint32_t index = offset / 8; + uint32_t bit = offset % 8; + + return buffer[index] & (1<<(7 - bit)); +} + +void unset_bit(uint32_t offset, uint8_t* buffer) { + uint32_t index = offset / 8; + uint32_t bit = offset % 8; + + buffer[index] &= (255 - (1<<(7 - bit))); +} + +void mark_unavailble(uint32_t address, uint32_t size) { + // This function takes a physical address and length and marks the corresponding pages as unavailable. + address -= address % 4096; + if (size % 4096) + size += 4096 - (size % 4096); + + address /= 4096; + size /= 4096; + + for (int i=0; i 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; + + mark_unavailble(phys_addr, 4096); + map_4k_phys_to_virt(phys_addr, kernel_allocate_area, kernel_page_directory, kernel_page_tables); + + kernel_allocate_area += 4096; + size -= 4096; + } + + return (void*)ptr; +} \ No newline at end of file diff --git a/src/kernel/allocate.h b/src/kernel/allocate.h new file mode 100644 index 0000000..945d215 --- /dev/null +++ b/src/kernel/allocate.h @@ -0,0 +1,15 @@ +#ifndef ALLOCATE_H +#define ALLOCATE_H + +#include "paging.h" +//void init_allocator(); + +void set_bit(uint32_t offset, uint8_t* buffer); +void unset_bit(uint32_t offset, uint8_t* buffer); +uint8_t get_bit(uint32_t offset, uint8_t* buffer); + +void mark_unavailble(uint32_t address, uint32_t size); + +void* dumb_alloc(uint32_t size); + +#endif \ No newline at end of file diff --git a/src/kernel/atapio.c b/src/kernel/atapio.c index c6e7745..cfecf28 100644 --- a/src/kernel/atapio.c +++ b/src/kernel/atapio.c @@ -11,8 +11,8 @@ uint16_t identify_result[256]; uint32_t total_28_lbas = 0; -uint8_t* rootDirEntries = 0x1000000; -uint16_t* FAT1 = 0x1002000; +uint8_t* rootDirEntries; +uint16_t* FAT1; uint16_t countReserved; uint8_t countFATs; @@ -21,6 +21,10 @@ 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; diff --git a/src/kernel/atapio.h b/src/kernel/atapio.h index 48de720..0a1e982 100644 --- a/src/kernel/atapio.h +++ b/src/kernel/atapio.h @@ -6,6 +6,7 @@ #include "io.h" #include "types.h" #include "strings.h" +#include "allocate.h" void init_atapio(); void read_sector(uint32_t address, uint8_t* buffer); diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index 46dbc51..f89078e 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -7,19 +7,21 @@ #include "atapio.h" int main() { - while (1); 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"); + printf("KERNEL OK!\n"); - printf("Hello, World!\n\nWe are running XnoeOS Code in C now, Protected Mode has been achieved and everything is working super nicely!\n\nHow wonderful!\n\nNow I just need to hope my print function works properly too~~\n"); - init_keyboard(); enable_idt(); init_atapio(); + //while (1); + uint8_t sector[512]; read_sector(0, sector); diff --git a/src/kernel/paging.c b/src/kernel/paging.c index 63978d3..016fc8b 100644 --- a/src/kernel/paging.c +++ b/src/kernel/paging.c @@ -24,7 +24,7 @@ void map_4k_phys_to_virt(uint32_t physical, uint32_t virtual, PDE* page_director .ignored2 = 0 }; - page_tables[split->pd_index][split->pt_index] = (PTE){ + ((PTE*)((uint32_t)page_tables[split->pd_index] + 0xbffe0000))[split->pt_index] = (PTE){ .address = physical >> 12, .available = 0, .global = 0, diff --git a/src/kernel/screenstuff.c b/src/kernel/screenstuff.c index 7700d2a..6d0a0c9 100644 --- a/src/kernel/screenstuff.c +++ b/src/kernel/screenstuff.c @@ -1,6 +1,6 @@ #include "screenstuff.h" -uint16_t* VMEM_ADDR = (uint16_t*)0xb8000; +uint16_t* VMEM_ADDR = (uint16_t*)0xc0501000; const int TERM_WIDTH = 80; const int TERM_HEIGHT = 25;