From 1b6689a4de367bcf0b5fd08621748ee9e5abd9d5 Mon Sep 17 00:00:00 2001 From: Furkan Mudanyali Date: Sun, 24 Jul 2022 07:16:00 +0300 Subject: [PATCH] Paging improvements (still borked), grub memory --- README.md | 2 +- kernel/Makefile | 2 +- kernel/arch/i386/boot/boot.S | 3 + kernel/arch/i386/boot/idt.c | 21 ++- kernel/arch/i386/linker.ld | 2 + kernel/arch/i386/vga/tty.c | 47 +++-- kernel/include/rockos/multiboot.h | 276 ++++++++++++++++++++++++++++++ kernel/include/rockos/paging.h | 5 +- kernel/rockos/kernel.c | 62 +++++-- kernel/rockos/keyboard.c | 10 +- kernel/rockos/paging.c | 89 ++++------ kernel/rockos/timer.c | 2 +- libc/Makefile | 2 +- 13 files changed, 426 insertions(+), 97 deletions(-) create mode 100644 kernel/include/rockos/multiboot.h diff --git a/README.md b/README.md index 1a2846a..df922b2 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ Welcome to rockOS project, a hobby OS that aims to run rogue and nethack. - PIC initialization - PIT timer - Keyboard driver -- Bitmap paging +- a thing that is supposed to be paging ## Usage diff --git a/kernel/Makefile b/kernel/Makefile index 0cd6a48..d02baa2 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -13,7 +13,7 @@ EXEC_PREFIX?=$(PREFIX) BOOTDIR?=$(EXEC_PREFIX)/boot INCLUDEDIR?=$(PREFIX)/include -CFLAGS:=$(CFLAGS) -ffreestanding -Wall -Wextra -fstack-protector-strong -mgeneral-regs-only -mno-red-zone +CFLAGS:=$(CFLAGS) -ffreestanding -Wall -Wextra -Wformat -Wpedantic -fstack-protector-strong -mgeneral-regs-only -mno-red-zone CPPFLAGS:=$(CPPFLAGS) -D__is_kernel -Iinclude LDFLAGS:=$(LDFLAGS) LIBS:=$(LIBS) -nostdlib -lk -lgcc diff --git a/kernel/arch/i386/boot/boot.S b/kernel/arch/i386/boot/boot.S index c4fc391..ae013af 100644 --- a/kernel/arch/i386/boot/boot.S +++ b/kernel/arch/i386/boot/boot.S @@ -42,6 +42,9 @@ stack_top: .global _start .type _start, @function _start: + push %eax + push %ebx + call bootloader_init cli call gdt_init # initialize the GDT movl $stack_top, %esp diff --git a/kernel/arch/i386/boot/idt.c b/kernel/arch/i386/boot/idt.c index 71f10c7..e776899 100644 --- a/kernel/arch/i386/boot/idt.c +++ b/kernel/arch/i386/boot/idt.c @@ -21,10 +21,27 @@ #include #include -__attribute__((interrupt)) void int_handler(void* frame, unsigned int number) { +__attribute__((interrupt)) void int_handler(uint32_t* frame, unsigned int number) { if (number <= 21) { printf("%s\n", err_msg[number]); } + switch(number){ + case 14: + if(((uint32_t)frame & 1) == 1) printf("P Present Set.\n"); + if(((uint32_t)frame & 2) == 2) printf("W Write Set.\n"); + if(((uint32_t)frame & 4) == 4) printf("U User Set.\n"); + if(((uint32_t)frame & 8) == 8) printf("R Reserved Write Set.\n"); + if(((uint32_t)frame & 16) == 16) printf("PK Protection Key Set.\n"); + if(((uint32_t)frame & 32) == 32) printf("SS Shadow Stack Set.\n"); + if(((uint32_t)frame & 64) == 64) printf("SGX Software Guard Extensions Set.\n"); + uint32_t address = 0; + asm("mov %%cr2, %%eax" + : "=a"(address) + : + ); + printf("Address: %#08X\n", address); + break; + } asm("cli;hlt"); } @@ -69,7 +86,7 @@ INT_WRAPPER(31) static __attribute__((aligned(0x10))) idt_entry_t idt[IDT_MAX_DESCRIPTORS]; static idtr_t idtptr; -void idt_set_descriptor(uint8_t vector, void* isr, uint8_t flags) { +void idt_set_descriptor(uint8_t vector, void (*isr)(void*), uint8_t flags) { idt_entry_t* descriptor = &idt[vector]; descriptor->isr_low = (uint32_t)isr & 0xFFFF; descriptor->kernel_cs = 0x08; // Whatever offset kernel code selector is in GDT diff --git a/kernel/arch/i386/linker.ld b/kernel/arch/i386/linker.ld index 7569f55..8b4e5bf 100644 --- a/kernel/arch/i386/linker.ld +++ b/kernel/arch/i386/linker.ld @@ -3,6 +3,7 @@ ENTRY(_start) SECTIONS { . = 1M; + _rockos_start = .; .text BLOCK(4K) : ALIGN(4K) { @@ -25,4 +26,5 @@ SECTIONS *(COMMON) *(.bss) } + _rockos_end = .; } diff --git a/kernel/arch/i386/vga/tty.c b/kernel/arch/i386/vga/tty.c index 363a0db..764e7ce 100644 --- a/kernel/arch/i386/vga/tty.c +++ b/kernel/arch/i386/vga/tty.c @@ -10,17 +10,20 @@ static const size_t VGA_WIDTH = 80; static const size_t VGA_HEIGHT = 25; static uint16_t* const VGA_MEMORY = (uint16_t*) 0xB8000; +static uint16_t* const VGA_OLDMEMORY = (uint16_t*) 0xB8000; static size_t terminal_row; static size_t terminal_column; static uint8_t terminal_color; static uint16_t* terminal_buffer; +static uint16_t* terminal_oldbuffer; void terminal_initialize(void) { terminal_row = 0; terminal_column = 0; terminal_color = vga_entry_color(VGA_COLOR_LIGHT_GREY, VGA_COLOR_BLACK); terminal_buffer = VGA_MEMORY; + terminal_oldbuffer = VGA_OLDMEMORY; for (size_t y = 0; y < VGA_HEIGHT; y++) { for (size_t x = 0; x < VGA_WIDTH; x++) { const size_t index = y * VGA_WIDTH + x; @@ -38,22 +41,44 @@ void terminal_putentryat(unsigned char c, uint8_t color, size_t x, size_t y) { terminal_buffer[index] = vga_entry(c, color); } +void scroll_screen_fwd() { + memcpy(terminal_oldbuffer, &terminal_buffer[VGA_WIDTH], (VGA_HEIGHT*2-1) * VGA_WIDTH); + for(size_t x = 0; x < VGA_WIDTH; ++x) { + terminal_oldbuffer[(VGA_HEIGHT-1)*VGA_WIDTH + x] = vga_entry(' ', terminal_color); + } + memcpy(terminal_buffer, terminal_oldbuffer, VGA_HEIGHT*VGA_WIDTH); + --terminal_row; +} + void terminal_putchar(char c) { unsigned char uc = c; - if (uc == '\n') { - terminal_column = 0; - if (++terminal_row == VGA_HEIGHT) { - terminal_row = 0; - } - } else { - terminal_putentryat(uc, terminal_color, terminal_column, terminal_row); - if (++terminal_column == VGA_WIDTH) { + switch(uc) { + case '\n': terminal_column = 0; - if (++terminal_row == VGA_HEIGHT) { - terminal_row = 0; + if (++terminal_row == VGA_HEIGHT) + scroll_screen_fwd(); + break; + case 0x08: + if(!terminal_column & !terminal_row) + return; + if(--terminal_column == 0) { + terminal_column = VGA_WIDTH; + if(--terminal_row == 0) { + terminal_row =VGA_HEIGHT; + } } - } + terminal_putentryat(' ', terminal_color, terminal_column, terminal_row); + break; + default: + terminal_putentryat(uc, terminal_color, terminal_column, terminal_row); + if (++terminal_column == VGA_WIDTH) { + terminal_column = 0; + if (++terminal_row == VGA_HEIGHT) { + scroll_screen_fwd(); + } + } + break; } } diff --git a/kernel/include/rockos/multiboot.h b/kernel/include/rockos/multiboot.h new file mode 100644 index 0000000..7a81531 --- /dev/null +++ b/kernel/include/rockos/multiboot.h @@ -0,0 +1,276 @@ +/* multiboot.h - Multiboot header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_HEADER_ALIGN 4 + +/* The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000004 + +/* Flags set in the ’flags’ member of the multiboot header. */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* Flags to be set in the ’flags’ member of the multiboot info structure. */ + +/* is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 + +/* is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 + +#ifndef ASM_FILE + +typedef unsigned char multiboot_uint8_t; +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* Feature flags. */ + multiboot_uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; + multiboot_uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + multiboot_uint32_t mode_type; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table +{ + multiboot_uint32_t tabsize; + multiboot_uint32_t strsize; + multiboot_uint32_t addr; + multiboot_uint32_t reserved; +}; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; + +/* The section header table for ELF. */ +struct multiboot_elf_section_header_table +{ + multiboot_uint32_t num; + multiboot_uint32_t size; + multiboot_uint32_t addr; + multiboot_uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; + +struct multiboot_info +{ + /* Multiboot info version number */ + multiboot_uint32_t flags; + + /* Available memory from BIOS */ + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; + + /* "root" partition */ + multiboot_uint32_t boot_device; + + /* Kernel command line */ + multiboot_uint32_t cmdline; + + /* Boot-Module list */ + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; + + union + { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; + + /* Memory Mapping buffer */ + multiboot_uint32_t mmap_length; + multiboot_uint32_t mmap_addr; + + /* Drive Info buffer */ + multiboot_uint32_t drives_length; + multiboot_uint32_t drives_addr; + + /* ROM configuration table */ + multiboot_uint32_t config_table; + + /* Boot Loader Name */ + multiboot_uint32_t boot_loader_name; + + /* APM table */ + multiboot_uint32_t apm_table; + + /* Video */ + multiboot_uint32_t vbe_control_info; + multiboot_uint32_t vbe_mode_info; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + union + { + struct + { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; +typedef struct multiboot_info multiboot_info_t; + +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry +{ + multiboot_uint32_t size; + multiboot_uint32_t addr_low; + multiboot_uint32_t addr_high; + multiboot_uint32_t len_low; + multiboot_uint32_t len_high; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_mod_list +{ + /* the memory used goes from bytes ’mod_start’ to ’mod_end-1’ inclusive */ + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + + /* Module command line */ + multiboot_uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + multiboot_uint32_t pad; +}; +typedef struct multiboot_mod_list multiboot_module_t; + +/* APM BIOS info. */ +struct multiboot_apm_info +{ + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ \ No newline at end of file diff --git a/kernel/include/rockos/paging.h b/kernel/include/rockos/paging.h index 775b16b..e381529 100644 --- a/kernel/include/rockos/paging.h +++ b/kernel/include/rockos/paging.h @@ -17,6 +17,7 @@ */ #include +#include #ifndef _ROCKOS_PAGING_H #define _ROCKOS_PAGING_H @@ -24,8 +25,6 @@ #define PAGE_ENTRIES 1024 #define PAGE_SIZE 4096 -uint32_t* get_page(); -void set_page_free(uint32_t*); -uint32_t get_used_memsize(); +void alloc_pages(uint32_t*, size_t); #endif \ No newline at end of file diff --git a/kernel/rockos/kernel.c b/kernel/rockos/kernel.c index 20979f7..62f9720 100644 --- a/kernel/rockos/kernel.c +++ b/kernel/rockos/kernel.c @@ -6,8 +6,32 @@ #include #include #include +#include +#include -void kernel_main(void) { +extern char _rockos_start, _rockos_end; + +static multiboot_info_t* multiboot_info; + +void panic(char* str) { + printf("%s\n", str); + asm("cli;hlt"); +} + +void bootloader_init(multiboot_info_t* mbd, unsigned int magic) { + /* Make sure the magic number matches for memory mapping*/ + if(magic != MULTIBOOT_BOOTLOADER_MAGIC) { + panic("invalid magic number!"); + } + + /* Check bit 6 to see if we have a valid memory map */ + if(!(mbd->flags >> 6 & 0x1)) { + panic("invalid memory map given by GRUB bootloader"); + } + multiboot_info = mbd; +} + +void kernel_main() { printf("Hello, kernel World!\n"); printf("String test: %s\n", "HELLOOOOO"); printf("Float test: %.10f\n", 0.123456789); @@ -27,23 +51,27 @@ void kernel_main(void) { min = (min & 0x0F) + ((min / 16) * 10); hour = ((hour & 0x0F) + (((hour & 0x70) / 16) * 10)) | (hour & 0x80); printf("Time: %02d:%02d:%02d UTC+3\n", (hour + 3) % 24, min, sec); - - uint32_t first = get_used_memsize(); - uint32_t limit = 1024 * 8; - uint32_t* pages[limit]; - - for(uint32_t i = 0; i < limit; i++) { - pages[i] = get_page(); - } - uint32_t middle = get_used_memsize(); - - for(uint32_t i = 0; i < limit; i++) { - set_page_free(pages[i]); - } - uint32_t last = get_used_memsize(); - printf("Before Allocation: %d KiB\nAfter allocation: %d KiB\nAfter Clear: %d KiB\n", first, middle, last); - printf("Finished!\n"); + printf("RockOS Start: %#08X, RockOS End: %#08X\n", &_rockos_start, &_rockos_end); + + for(multiboot_uint32_t i = 0; i < multiboot_info->mmap_length; i += sizeof(multiboot_memory_map_t)) { + multiboot_memory_map_t* mmmt = + (multiboot_memory_map_t*) (multiboot_info->mmap_addr + i); + + printf("Start Addr: %#08X | Length: %#08X | Size: %#08X | Type: %X\n", + mmmt->addr_low, mmmt->len_low, mmmt->size, mmmt->type); + + if(mmmt->type == MULTIBOOT_MEMORY_AVAILABLE) { + // + } + } + uint32_t* pages; + alloc_pages(pages, 1); + printf("Page Start: %#08X\n", *pages); + alloc_pages(*pages, 8192); + for(int i = 0; i < 8192; ++i){ + //printf("Page Start: %#08X\n", (uint32_t)(*pages + i)); + } unsigned char key; for(;;) { diff --git a/kernel/rockos/keyboard.c b/kernel/rockos/keyboard.c index f858be6..9f2089e 100644 --- a/kernel/rockos/keyboard.c +++ b/kernel/rockos/keyboard.c @@ -20,15 +20,15 @@ static uint8_t keyset[89]; static uint64_t keytimes[89]; static unsigned char keymap[89] = { - 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0, - '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0, 0, + 0, 0, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0x08, + '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0, 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 0, '*', 0, ' ', 0 }; static unsigned char keymapshift[89] = { - 0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0, - '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0, 0, + 0, 0, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0x08, + '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0, 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '\"', '`', 0, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 0, '*', 0, ' ', 0 }; @@ -43,7 +43,7 @@ void initialize_keyset() { uint8_t caps_lock = 0; -__attribute__((interrupt)) void keyboard_handler(void* frame) { +__attribute__((interrupt)) void keyboard_handler(__attribute__((unused)) void* frame) { interrupt_key = inb(0x60); pic_eoi(1); if((interrupt_key & 128) == 128) { diff --git a/kernel/rockos/paging.c b/kernel/rockos/paging.c index b0f3f67..a6e1f1e 100644 --- a/kernel/rockos/paging.c +++ b/kernel/rockos/paging.c @@ -1,5 +1,7 @@ #include #include +#include +#include void load_page_dir(uint32_t* page_dir) { asm volatile ( @@ -18,80 +20,57 @@ void enable_paging() { ); } -static uint32_t page_dir[PAGE_ENTRIES] __attribute__((aligned(PAGE_SIZE))); -static uint32_t first_page_table[PAGE_ENTRIES] __attribute__((aligned(PAGE_SIZE))); +extern char _rockos_end; +static uint32_t* page_dir __attribute__((packed)); void paging_init() { + page_dir = (uint32_t*)(((uint32_t)&_rockos_end & ~0xFFF) + 0x1000); for(int i = 0; i < PAGE_ENTRIES; i++) { // Supervisor: only kernel-mode can access // Write Enabled: Can be both read and written to // Not Present: Page table not present - page_dir[i] = 0x00000002; + *(page_dir + i) = 0x00000002; } - + + uint32_t* firstPageTable __attribute__((packed)) = (uint32_t*)(((uint32_t)page_dir & ~0xFFF) + 0x1000); for(unsigned int i = 0; i < PAGE_ENTRIES; i++) { // As the address is page aligned, it will leave 12 bits zeroed, // which are used by the attributes. - first_page_table[i] = (i * 0x1000) | 0x103; // attr: supervisor, r/w, present, 9th bit set + firstPageTable[i] = (i*0x1000) | 0x003; // attr: supervisor, r/w, present, 9th bit set } - page_dir[0] = ((unsigned int)first_page_table) | 3; //attr: supervisor, r/w, present - + page_dir[0] = (uint32_t)firstPageTable | 0x003; //attr: supervisor, r/w, present load_page_dir(page_dir); enable_paging(); } -uint32_t* get_page() { - // Search directories for tables - for (int i = 0; i < PAGE_ENTRIES; ++i) { - // If table is found (if 2nd and 1st bit are set) - if((page_dir[i] & 0x3) == 0x3) { - // Cast table location - uint32_t *mytable = (uint32_t*)((page_dir[i] >> 12) << 12); - // Search table for pages - for(int j = 0; j < PAGE_ENTRIES; ++j) { - // If page is found (9th, 2nd, 1st bit set) - if((mytable[j] & 0x103) == 0x103) { - mytable[j] &= ~0x100; // Unset 9th bit - return &mytable[j]; +void alloc_pages(uint32_t* pages, size_t size) { + for(size_t i = 0; i < size;) { + for(size_t j = 0; j < PAGE_ENTRIES && i < size; ++j) { + printf("oklahoma %#08X\n", page_dir[j]); + if((page_dir[j] & 3) == 3) { + uint32_t* pageTable __attribute__((packed)) = page_dir[j] & ~0xFFF; + for(int k = 0; k < PAGE_ENTRIES && i < size; ++k) { + if((pageTable[k] & 3) == 3 && (pageTable[k] & 0x100) != 0x100) { + pageTable[k] |= 0x100; + pages[i] = ((uint32_t)pageTable & ~0xFFF) | (pageTable[k] >> 12); + printf("connecticut %#08X\n", pages[i]); + ++i; + } } - } // No page found till last entry - // Check if next table is not initialized - if((page_dir[i+1] & 0x3) != 0x3) { - // The last page of previous table points to the next table - uint32_t *newtable = &mytable[2*PAGE_ENTRIES]; - for(int k = 0; k < PAGE_ENTRIES; ++k) { - newtable[k] = (k * 0x1000) | 0x103; // attr: supervisor, r/w, present, 9th bit set + } else { + printf("aa %#08X\n", (page_dir[j-1] & ~0xFFF) + 0x4000); + uint32_t* newPageTable __attribute__((packed)) = (page_dir[j-1] & ~0xFFF) + 0x4000; + printf("alabama %#08X, %#08X\n", newPageTable[0], (page_dir[j-1] & ~0xFFF) + 0x4000); + for(unsigned int l = 0; l < PAGE_ENTRIES; l++) { + // As the address is page aligned, it will leave 12 bits zeroed, + // which are used by the attributes. + newPageTable[l] = (l*0x1000) | 0x003; // attr: supervisor, r/w, present, 9th bit set } - page_dir[i+1] = ((unsigned int)newtable) | 3; //attr: supervisor, r/w, present + page_dir[j] = (uint32_t)newPageTable | 0x003; + printf("NewPageTable: %#08X\n", page_dir[j]); + --j; } } } - return 0; -} - -void set_page_free(uint32_t* addr) { - // Set 9th, 2nd and 1st bits - *(addr) |= 0x103; -} - -uint32_t get_used_memsize() { - uint32_t used = 0; - // Iterate over page_dirs - for(int i = 0; i < PAGE_ENTRIES; ++i) { - // If a table is available - if((page_dir[i] & 3) == 3) { - // Cast the table - uint32_t* table = ((page_dir[i] >> 12) << 12); - // Iterate over table - for(int j = 0; j < PAGE_ENTRIES; ++j) { - // If a page is unavailable - if((table[j] & 0x103) != 0x103) { - // Then it is used - used += 4*4; - } - } - } - } - return used; } \ No newline at end of file diff --git a/kernel/rockos/timer.c b/kernel/rockos/timer.c index 37def03..63f1e98 100644 --- a/kernel/rockos/timer.c +++ b/kernel/rockos/timer.c @@ -6,7 +6,7 @@ uint64_t ticks = 0; uint8_t subticks = 0; -__attribute__((interrupt)) void timer_handler(void* frame) { +__attribute__((interrupt)) void timer_handler(__attribute__((unused)) void* frame) { if(++subticks == SUBTICKS_PER_TICK) { ++ticks; subticks = 0; diff --git a/libc/Makefile b/libc/Makefile index cd77597..9b5b39f 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -13,7 +13,7 @@ EXEC_PREFIX?=$(PREFIX) INCLUDEDIR?=$(PREFIX)/include LIBDIR?=$(EXEC_PREFIX)/lib -CFLAGS:=$(CFLAGS) -ffreestanding -Wall -Wextra -fstack-protector +CFLAGS:=$(CFLAGS) -ffreestanding -Wall -Wextra -Wpedantic -Werror -fstack-protector CPPFLAGS:=$(CPPFLAGS) -D__is_libc -Iinclude LIBK_CFLAGS:=$(CFLAGS) LIBK_CPPFLAGS:=$(CPPFLAGS) -D__is_libk