From 624ffbe738532e9394ac61ce22748818cc57825d Mon Sep 17 00:00:00 2001 From: Tunacan Date: Tue, 17 Aug 2021 12:45:35 +0300 Subject: [PATCH] fix idt and begin paging --- Makefile | 8 +- arch/i386/boot/asm.asm | 41 --- arch/i386/drivers/idt/idt.c | 25 -- arch/i386/drivers/idt/isr.c | 149 --------- arch/{i386 => x86_64}/drivers/device/device.c | 0 arch/{i386 => x86_64}/drivers/framebuffer.c | 16 +- arch/{i386 => x86_64}/drivers/ide/ide.c | 17 +- arch/x86_64/drivers/idt/idt.c | 48 +++ arch/x86_64/drivers/idt/isr.c | 124 +++++++ .../drivers/keyboard/keyboard.c | 12 +- arch/{i386 => x86_64}/drivers/pic/pic.c | 10 +- arch/{i386 => x86_64}/drivers/psf.c | 8 +- arch/{i386 => x86_64}/drivers/tar/tar.c | 0 .../drivers/terminal/terminal.c | 74 ++--- arch/{i386/boot => x86_64}/kernel.c | 159 ++++----- arch/x86_64/paging.c | 18 ++ arch/{i386 => x86_64}/std/stdio.c | 8 +- arch/{i386 => x86_64}/std/string.c | 22 +- arch/{i386 => x86_64}/std/util.c | 13 +- include/drivers/ahci/ahci.h | 302 +++++++++--------- include/drivers/device/device.h | 8 - include/drivers/ide/ide.h | 12 +- include/drivers/idt/idt.h | 39 ++- include/drivers/idt/isr.h | 8 - include/drivers/keyboard/keyboard.h | 10 +- include/drivers/pic/pic.h | 14 +- include/drivers/tar/tar.h | 8 - include/drivers/terminal/terminal.h | 41 +-- include/framebuffer.h | 26 +- include/paging.h | 36 +++ include/psf.h | 29 +- include/std/ctype.h | 8 - include/std/inline.h | 28 +- include/std/stdio.h | 8 - include/std/string.h | 20 +- include/std/util.h | 25 +- include/stivale2.h | 126 ++++---- include/types.h | 21 ++ linker.ld | 6 +- 39 files changed, 704 insertions(+), 823 deletions(-) delete mode 100644 arch/i386/boot/asm.asm delete mode 100644 arch/i386/drivers/idt/idt.c delete mode 100644 arch/i386/drivers/idt/isr.c rename arch/{i386 => x86_64}/drivers/device/device.c (100%) rename arch/{i386 => x86_64}/drivers/framebuffer.c (50%) rename arch/{i386 => x86_64}/drivers/ide/ide.c (97%) create mode 100644 arch/x86_64/drivers/idt/idt.c create mode 100644 arch/x86_64/drivers/idt/isr.c rename arch/{i386 => x86_64}/drivers/keyboard/keyboard.c (90%) rename arch/{i386 => x86_64}/drivers/pic/pic.c (85%) rename arch/{i386 => x86_64}/drivers/psf.c (78%) rename arch/{i386 => x86_64}/drivers/tar/tar.c (100%) rename arch/{i386 => x86_64}/drivers/terminal/terminal.c (53%) rename arch/{i386/boot => x86_64}/kernel.c (64%) create mode 100644 arch/x86_64/paging.c rename arch/{i386 => x86_64}/std/stdio.c (98%) rename arch/{i386 => x86_64}/std/string.c (69%) rename arch/{i386 => x86_64}/std/util.c (79%) create mode 100644 include/paging.h create mode 100644 include/types.h diff --git a/Makefile b/Makefile index 5386bb6..27d3961 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CC = x86_64-elf-gcc NASM = nasm # User controllable CFLAGS. -CFLAGS = -Wall -Wextra -O3 -pipe +CFLAGS = -Wall -Wextra -O2 -pipe NASMFLAGS = -felf64 # Internal link flags that should not be changed by the user. @@ -20,7 +20,7 @@ INTERNALLDFLAGS := \ # Internal C flags that should not be changed by the user. INTERNALCFLAGS := \ -Iinclude \ - -std=gnu11 \ + -std=gnu17 \ -ffreestanding \ -fno-stack-protector \ -fno-pic -fpie \ @@ -40,7 +40,9 @@ OBJ += font.o .PHONY: all clean run run: $(ISO) - qemu-system-x86_64 -cdrom $(ISO) -serial file:serial.log -drive id=disk,file=build/disk.img,if=none,format=raw -device ide-hd,drive=disk,bus=ide.0 + qemu-system-x86_64 -cdrom $(ISO) -m 128M -serial file:serial.log \ + -drive id=disk,file=disk.img,if=none,format=raw \ + -device ide-hd,drive=disk,bus=ide.0 $(ISO): $(KERNEL) mkdir -p sysroot diff --git a/arch/i386/boot/asm.asm b/arch/i386/boot/asm.asm deleted file mode 100644 index ac7f89c..0000000 --- a/arch/i386/boot/asm.asm +++ /dev/null @@ -1,41 +0,0 @@ -.intel_syntax noprefix - -.rodata -gdt: -.null: - dq 0x0 -.code: - dw 0xffff - dw 0x0000 - db 0x00 - db 10011010b - db 11001111b - db 0x00 -.data: - dw 0xffff - dw 0x0000 - db 0x00 - db 10010010b - db 11001111b - db 0x00 -.end: -.descriptor: - dw .end - gdt - 1 - dd gdt - -.text - .global gdt_load - -gdt_load: - push eax - lgdt [gdt.descriptor] - jmp 0x08:.loaded_cs -.loaded_cs: - mov ax, 0x10 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - pop eax - ret diff --git a/arch/i386/drivers/idt/idt.c b/arch/i386/drivers/idt/idt.c deleted file mode 100644 index 151a37a..0000000 --- a/arch/i386/drivers/idt/idt.c +++ /dev/null @@ -1,25 +0,0 @@ -#include -#include - -struct idt_entry idt[256]; -static unsigned long idt_address; -static unsigned long idt_ptr[2]; - -void idt_init() { - idt_address = (unsigned long)idt; - idt_ptr[0] = (sizeof (struct idt_entry) * 256) + ((idt_address & 0xffff) << 16); - idt_ptr[1] = idt_address >> 16; - - __asm__ __volatile__( - "lidt %0\n\t" - "sti\n\t" : : "m"(idt_ptr) - ); -} - -void idt_register_handler(uint8_t interrupt, unsigned long address) { - idt[interrupt].offset_lowerbits = address & 0xffff; - idt[interrupt].selector = KERNEL_CODE_SEGMENT_OFFSET; - idt[interrupt].zero = 0; - idt[interrupt].type_attr = INTERRUPT_GATE; - idt[interrupt].offset_higherbits = (address & 0xffff0000) >> 16; -} \ No newline at end of file diff --git a/arch/i386/drivers/idt/isr.c b/arch/i386/drivers/idt/isr.c deleted file mode 100644 index c906be9..0000000 --- a/arch/i386/drivers/idt/isr.c +++ /dev/null @@ -1,149 +0,0 @@ -#include -#include - -__attribute__((interrupt)) static void isr0(struct interrupt_frame* frame) { - terminal_writeline("Division By Zero"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr1(struct interrupt_frame* frame) { - terminal_writeline("Debug"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr2(struct interrupt_frame* frame) { - terminal_writeline("Non Maskable Interrupt"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr3(struct interrupt_frame* frame) { - terminal_writeline("Breakpoint"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr4(struct interrupt_frame* frame) { - terminal_writeline("Into Detected Overflow"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr5(struct interrupt_frame* frame) { - terminal_writeline("Out of Bounds"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr6(struct interrupt_frame* frame) { - terminal_writeline("Invalid Opcode"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr7(struct interrupt_frame* frame) { - terminal_writeline("No Coprocessor"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr8(struct interrupt_frame* frame) { - terminal_writeline("Double Fault"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr9(struct interrupt_frame* frame) { - terminal_writeline("Coprocessor Segment Overrun"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr10(struct interrupt_frame* frame) { - terminal_writeline("Bad TSS"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr11(struct interrupt_frame* frame) { - terminal_writeline("Segment Not Present"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr12(struct interrupt_frame* frame) { - terminal_writeline("Stack Fault"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr13(struct interrupt_frame* frame) { - terminal_writeline("General Protection Fault"); - - terminal_writeline("heres some info:"); - - terminal_writestring("ip: "); - terminal_writeline(itoa(frame->ip)); - terminal_writestring("sp: "); - terminal_writeline(itoa(frame->sp)); - terminal_writestring("cs: "); - terminal_writeline(itoa(frame->cs)); - - asm("hlt"); -} - -__attribute__((interrupt)) static void isr14(struct interrupt_frame* frame) { - terminal_writeline("Page Fault"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr15(struct interrupt_frame* frame) { - terminal_writeline("Unknown Interrupt"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr16(struct interrupt_frame* frame) { - terminal_writeline("Coprocessor Fault"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr17(struct interrupt_frame* frame) { - terminal_writeline("Alignment Check"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr18(struct interrupt_frame* frame) { - terminal_writeline("Machine Check"); - asm("hlt"); -} - -__attribute__((interrupt)) static void isr_reserved(struct interrupt_frame* frame) { - terminal_writeline("Reserved"); - asm("hlt"); -} - -void isr_install(void) { - idt_register_handler(0, (unsigned long)isr0); - idt_register_handler(1, (unsigned long)isr1); - idt_register_handler(2, (unsigned long)isr2); - idt_register_handler(3, (unsigned long)isr3); - idt_register_handler(4, (unsigned long)isr4); - idt_register_handler(5, (unsigned long)isr5); - idt_register_handler(6, (unsigned long)isr6); - idt_register_handler(7, (unsigned long)isr7); - idt_register_handler(8, (unsigned long)isr8); - idt_register_handler(9, (unsigned long)isr9); - idt_register_handler(10, (unsigned long)isr10); - idt_register_handler(11, (unsigned long)isr11); - idt_register_handler(12, (unsigned long)isr12); - idt_register_handler(13, (unsigned long)isr13); - idt_register_handler(14, (unsigned long)isr14); - idt_register_handler(15, (unsigned long)isr15); - idt_register_handler(16, (unsigned long)isr16); - idt_register_handler(17, (unsigned long)isr17); - idt_register_handler(18, (unsigned long)isr18); - idt_register_handler(19, (unsigned long)isr_reserved); - idt_register_handler(20, (unsigned long)isr_reserved); - idt_register_handler(21, (unsigned long)isr_reserved); - idt_register_handler(22, (unsigned long)isr_reserved); - idt_register_handler(23, (unsigned long)isr_reserved); - idt_register_handler(24, (unsigned long)isr_reserved); - idt_register_handler(25, (unsigned long)isr_reserved); - idt_register_handler(26, (unsigned long)isr_reserved); - idt_register_handler(27, (unsigned long)isr_reserved); - idt_register_handler(28, (unsigned long)isr_reserved); - idt_register_handler(29, (unsigned long)isr_reserved); - idt_register_handler(30, (unsigned long)isr_reserved); - idt_register_handler(31, (unsigned long)isr_reserved); - - idt_init(); -} \ No newline at end of file diff --git a/arch/i386/drivers/device/device.c b/arch/x86_64/drivers/device/device.c similarity index 100% rename from arch/i386/drivers/device/device.c rename to arch/x86_64/drivers/device/device.c diff --git a/arch/i386/drivers/framebuffer.c b/arch/x86_64/drivers/framebuffer.c similarity index 50% rename from arch/i386/drivers/framebuffer.c rename to arch/x86_64/drivers/framebuffer.c index abba19f..e06ccb5 100644 --- a/arch/i386/drivers/framebuffer.c +++ b/arch/x86_64/drivers/framebuffer.c @@ -1,21 +1,21 @@ #include #include -void putpixel(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint32_t color) { +void putpixel(framebuffer_t *framebuffer, u16 x, u16 y, u32 color) { if (color & 255 == 0) return; - uint64_t where = x * framebuffer->pixelwidth + y * framebuffer->pitch; + u64 where = x * framebuffer->pixelwidth + y * framebuffer->pitch; framebuffer->address[where] = (color >> 8) & 255; // BLUE framebuffer->address[where + 1] = (color >> 16) & 255; // GREEN framebuffer->address[where + 2] = (color >> 24) & 255; // RED } -void fillrect(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color) { +void fillrect(framebuffer_t *framebuffer, u16 x, u16 y, u16 w, u16 h, u32 color) { if (color & 255 == 0) return; - uint8_t* where; - uint32_t pw = framebuffer->pixelwidth; - for (uint16_t i = y; i < h + y; i++) { - where = (uint8_t*)((uint64_t)framebuffer->address + framebuffer->pitch * i); - for (uint16_t j = x; j < w + x; j++) { + u8 *where; + u32 pw = framebuffer->pixelwidth; + for (u16 i = y; i < h + y; i++) { + where = (u8*)((u64)framebuffer->address + framebuffer->pitch * i); + for (u16 j = x; j < w + x; j++) { where[j * pw] = (color >> 8) & 255; // BLUE where[j * pw + 1] = (color >> 16) & 255; // GREEN where[j * pw + 2] = (color >> 24) & 255; // RED diff --git a/arch/i386/drivers/ide/ide.c b/arch/x86_64/drivers/ide/ide.c similarity index 97% rename from arch/i386/drivers/ide/ide.c rename to arch/x86_64/drivers/ide/ide.c index 37f701c..fcb0aed 100644 --- a/arch/i386/drivers/ide/ide.c +++ b/arch/x86_64/drivers/ide/ide.c @@ -7,7 +7,7 @@ // NOTE(hippoz): The function below is actually a joke. It's temporary. I'll // implement the timer soon. -uint8_t sleep(int h) { +u8 sleep(int h) { if (h != 1) return 1; for (unsigned long long i = 0; i < 99999999999; i++) @@ -79,8 +79,7 @@ unsigned char ide_read(unsigned char channel, unsigned char reg) { return result; } -void ide_read_buffer(unsigned char channel, unsigned char reg, - unsigned int *buffer, unsigned int quads) { +void ide_read_buffer(u8 channel, u8 reg, u32 *buffer, u32 quads) { /* WARNING: This code contains a serious bug. The inline assembly trashes ES * and ESP for all of the code the compiler generates between the inline * assembly blocks. @@ -308,7 +307,7 @@ void ide_wait_irq() { } unsigned char ide_ata_access(unsigned char direction, unsigned char drive, - unsigned int lba, uint8_t *buf) { + unsigned int lba, u8 *buf) { unsigned char lba_mode /* 0: CHS, 1:LBA28, 2: LBA48 */, dma /* 0: No DMA, 1: DMA */, cmd; unsigned char lba_io[6]; @@ -450,7 +449,7 @@ unsigned char ide_ata_access(unsigned char direction, unsigned char drive, return 0; // Easy, isn't it? no } -uint8_t ide_read_sectors(unsigned char drive, unsigned int lba, uint8_t *buf) { +u8 ide_read_sectors(unsigned char drive, unsigned int lba, u8 *buf) { // Check if the drive is present: if (drive > 3 || ide_devices[drive].Reserved == 0) return 0x01; // Drive not present @@ -470,7 +469,7 @@ uint8_t ide_read_sectors(unsigned char drive, unsigned int lba, uint8_t *buf) { return ide_print_error(drive, err); } -uint8_t ide_write_sectors(unsigned char drive, unsigned int lba, uint8_t *buf) { +u8 ide_write_sectors(unsigned char drive, unsigned int lba, u8 *buf) { if (drive > 3 || ide_devices[drive].Reserved == 0) return 0x01; // Drive not present if (((lba + 1) > ide_devices[drive].Size) && @@ -494,7 +493,7 @@ void ide_init() { sleep(1); printf("Testing IDE drive...\n"); - uint8_t buf[512] = {0}; + u8 buf[512] = {0}; memcpy(buf, "Hello world", sizeof("Hello world")); ide_write_sectors(0, 1, buf); @@ -502,14 +501,14 @@ void ide_init() { sleep(1); sleep(1); - uint8_t outbuf[512] = {0}; + u8 outbuf[512] = {0}; ide_read_sectors(0, 1, outbuf); sleep(1); sleep(1); sleep(1); - for (uint8_t i = 0; i < 11; i++) { + for (u8 i = 0; i < 11; i++) { printf("%d: %c | ", i, outbuf[i]); } printf("\n"); diff --git a/arch/x86_64/drivers/idt/idt.c b/arch/x86_64/drivers/idt/idt.c new file mode 100644 index 0000000..1d5cabf --- /dev/null +++ b/arch/x86_64/drivers/idt/idt.c @@ -0,0 +1,48 @@ +#include +#include + +__attribute__((aligned(0x10))) +static idt_entry_t idt[256]; + +static idtr_t idtr; + +void idt_init() { + idtr.base = (uintptr_t)&idt[0]; + idtr.limit = (u16)sizeof(idt_entry_t) * 256 - 1; + + asm volatile ("lidt %0" : : "memory"(idtr)); // load the new IDT + asm volatile ("sti"); // set the interrupt flag +} + +void idt_set_entry(u8 vector, void* isr, u8 flags) { + idt_entry_t* entry = &idt[vector]; + + entry->isr_low = (u64)isr & 0xFFFF; + entry->kernel_cs = KERNEL_CODE_SEGMENT_OFFSET; + entry->ist = 0; + entry->attributes = flags; + entry->isr_mid = ((u64)isr >> 16) & 0xFFFF; + entry->isr_high = ((u64)isr >> 32) & 0xFFFFFFFF; + entry->reserved = 0; +} + +/* +void idt_init() { + idt_address = (unsigned long)idt; + idt_ptr[0] = (sizeof (struct idt_entry) * 256) + ((idt_address & 0xffff) << 16); + idt_ptr[1] = idt_address >> 16; + + __asm__ __volatile__( + "lidt %0\n\t" + "sti\n\t" : : "m"(idt_ptr) + ); +} + +void idt_register_handler(u8 interrupt, unsigned long address) { + idt[interrupt].offset_lowerbits = address & 0xffff; + idt[interrupt].selector = KERNEL_CODE_SEGMENT_OFFSET; + idt[interrupt].zero = 0; + idt[interrupt].type_attr = INTERRUPT_GATE; + idt[interrupt].offset_higherbits = (address & 0xffff0000) >> 16; +} +*/ \ No newline at end of file diff --git a/arch/x86_64/drivers/idt/isr.c b/arch/x86_64/drivers/idt/isr.c new file mode 100644 index 0000000..4792cd4 --- /dev/null +++ b/arch/x86_64/drivers/idt/isr.c @@ -0,0 +1,124 @@ +#include +#include + +inline isr_exception(interrupt_frame_t *frame, const char *error) { + printf(error); + asm volatile("cli; hlt"); +} + +__attribute__((interrupt)) static void isr0(interrupt_frame_t *frame) { + isr_exception(frame, "Division By Zero"); +} + +__attribute__((interrupt)) static void isr1(interrupt_frame_t *frame) { + isr_exception(frame, "Debug"); +} + +__attribute__((interrupt)) static void isr2(interrupt_frame_t *frame) { + isr_exception(frame, "Non Maskable Interrupt"); +} + +__attribute__((interrupt)) static void isr3(interrupt_frame_t *frame) { + isr_exception(frame, "Breakpoint"); +} + +__attribute__((interrupt)) static void isr4(interrupt_frame_t *frame) { + isr_exception(frame, "Into Detected Overflow"); +} + +__attribute__((interrupt)) static void isr5(interrupt_frame_t *frame) { + isr_exception(frame, "Out of Bounds"); +} + +__attribute__((interrupt)) static void isr6(interrupt_frame_t *frame) { + isr_exception(frame, "Invalid Opcode"); +} + +__attribute__((interrupt)) static void isr7(interrupt_frame_t *frame) { + isr_exception(frame, "No Coprocessor"); +} + +__attribute__((interrupt)) static void isr8(interrupt_frame_t *frame) { + isr_exception(frame, "Double Fault"); +} + +__attribute__((interrupt)) static void isr9(interrupt_frame_t *frame) { + isr_exception(frame, "Coprocessor Segment Overrun"); +} + +__attribute__((interrupt)) static void isr10(interrupt_frame_t *frame) { + isr_exception(frame, "Bad TSS"); +} + +__attribute__((interrupt)) static void isr11(interrupt_frame_t *frame) { + isr_exception(frame, "Segment Not Present"); +} + +__attribute__((interrupt)) static void isr12(interrupt_frame_t *frame) { + isr_exception(frame, "Stack Fault"); +} + +__attribute__((interrupt)) static void isr13(interrupt_frame_t *frame) { + isr_exception(frame, "General Protection Fault"); +} + +__attribute__((interrupt)) static void isr14(interrupt_frame_t *frame) { + isr_exception(frame, "Page Fault"); +} + +__attribute__((interrupt)) static void isr15(interrupt_frame_t *frame) { + isr_exception(frame, "Unknown Interrupt"); +} + +__attribute__((interrupt)) static void isr16(interrupt_frame_t *frame) { + isr_exception(frame, "Coprocessor Fault"); +} + +__attribute__((interrupt)) static void isr17(interrupt_frame_t *frame) { + isr_exception(frame, "Alignment Check"); +} + +__attribute__((interrupt)) static void isr18(interrupt_frame_t *frame) { + isr_exception(frame, "Machine Check"); +} + +__attribute__((interrupt)) static void isr_reserved(interrupt_frame_t *frame) { + isr_exception(frame, "Reserved"); +} + +void isr_install(void) { + idt_set_entry(0, (void*)isr0, INTERRUPT_GATE); + idt_set_entry(1, (void*)isr1, INTERRUPT_GATE); + idt_set_entry(2, (void*)isr2, INTERRUPT_GATE); + idt_set_entry(3, (void*)isr3, INTERRUPT_GATE); + idt_set_entry(4, (void*)isr4, INTERRUPT_GATE); + idt_set_entry(5, (void*)isr5, INTERRUPT_GATE); + idt_set_entry(6, (void*)isr6, INTERRUPT_GATE); + idt_set_entry(7, (void*)isr7, INTERRUPT_GATE); + idt_set_entry(8, (void*)isr8, INTERRUPT_GATE); + idt_set_entry(9, (void*)isr9, INTERRUPT_GATE); + idt_set_entry(10, (void*)isr10, INTERRUPT_GATE); + idt_set_entry(11, (void*)isr11, INTERRUPT_GATE); + idt_set_entry(12, (void*)isr12, INTERRUPT_GATE); + idt_set_entry(13, (void*)isr13, INTERRUPT_GATE); + idt_set_entry(14, (void*)isr14, INTERRUPT_GATE); + idt_set_entry(15, (void*)isr15, INTERRUPT_GATE); + idt_set_entry(16, (void*)isr16, INTERRUPT_GATE); + idt_set_entry(17, (void*)isr17, INTERRUPT_GATE); + idt_set_entry(18, (void*)isr18, INTERRUPT_GATE); + idt_set_entry(19, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(20, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(21, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(22, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(23, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(24, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(25, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(26, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(27, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(28, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(29, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(30, (void*)isr_reserved, INTERRUPT_GATE); + idt_set_entry(31, (void*)isr_reserved, INTERRUPT_GATE); + + idt_init(); +} \ No newline at end of file diff --git a/arch/i386/drivers/keyboard/keyboard.c b/arch/x86_64/drivers/keyboard/keyboard.c similarity index 90% rename from arch/i386/drivers/keyboard/keyboard.c rename to arch/x86_64/drivers/keyboard/keyboard.c index 2ca4f0f..1c1a1ad 100644 --- a/arch/i386/drivers/keyboard/keyboard.c +++ b/arch/x86_64/drivers/keyboard/keyboard.c @@ -44,15 +44,15 @@ unsigned char kbdus[128] = { 0, /* All other keys are undefined */ }; -uint8_t lastkey = 0; -uint8_t __kbd_enabled = 0; +u8 lastkey = 0; +u8 __kbd_enabled = 0; void keyboard_buffer_push_key(unsigned char scancode) { kbdbuf[lastkey++] = scancode; } unsigned char keyboard_buffer_pop_key() { - uint8_t index = lastkey--; + u8 index = lastkey--; unsigned char scancode = kbdbuf[index]; kbdbuf[index] = 0; return scancode; @@ -62,7 +62,7 @@ unsigned char keyboard_get_key_from_scancode(unsigned char scancode) { return kbdus[scancode]; } -__attribute__((interrupt)) static void keyboard_irq(struct interrupt_frame* frame) { +__attribute__((interrupt)) static void keyboard_irq(interrupt_frame_t *frame) { unsigned char scancode = inportb(0x60); if (scancode & 128) { @@ -75,7 +75,7 @@ __attribute__((interrupt)) static void keyboard_irq(struct interrupt_frame* fram pic_send_eoi(1); } -uint8_t keyboard_enabled(void) { +u8 keyboard_enabled(void) { return __kbd_enabled; } @@ -89,7 +89,7 @@ void* keyboard_write() { int keyboard_init(void) { pic_irq_enable(1); - idt_register_handler(33, (uint32_t)keyboard_irq); + idt_set_entry(33, (void*)keyboard_irq, INTERRUPT_GATE); __kbd_enabled = 1; diff --git a/arch/i386/drivers/pic/pic.c b/arch/x86_64/drivers/pic/pic.c similarity index 85% rename from arch/i386/drivers/pic/pic.c rename to arch/x86_64/drivers/pic/pic.c index 0e286ea..122cbfe 100644 --- a/arch/i386/drivers/pic/pic.c +++ b/arch/x86_64/drivers/pic/pic.c @@ -1,7 +1,7 @@ #include -static uint8_t pic1_mask = 0xff; -static uint8_t pic2_mask = 0xff; +static u8 pic1_mask = 0xff; +static u8 pic2_mask = 0xff; void pic_init() { outportb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); @@ -25,14 +25,14 @@ void pic_init() { pic_irq_enable(2); } -void pic_send_eoi(uint8_t no) { +void pic_send_eoi(u8 no) { if (no >= 8) { outportb(PIC2_COMMAND, PIC_EOI); } outportb(PIC1_COMMAND, PIC_EOI); } -void pic_irq_enable(uint8_t no) { +void pic_irq_enable(u8 no) { if (no >= 8) { no -= 8; pic2_mask &= ~(1 << no); @@ -43,7 +43,7 @@ void pic_irq_enable(uint8_t no) { } } -void pic_irq_disable(uint8_t no) { +void pic_irq_disable(u8 no) { if (no >= 8) { no -= 8; pic2_mask |= (1 << no); diff --git a/arch/i386/drivers/psf.c b/arch/x86_64/drivers/psf.c similarity index 78% rename from arch/i386/drivers/psf.c rename to arch/x86_64/drivers/psf.c index 41a3bb2..1c34b38 100644 --- a/arch/i386/drivers/psf.c +++ b/arch/x86_64/drivers/psf.c @@ -1,13 +1,13 @@ #include // c is a unicode character, cx and cy are cursor position in characters -void draw_psf_char(framebuffer_t *framebuffer, uint32_t c, uint16_t cx, uint16_t cy, uint32_t fg, uint32_t bg) { +void draw_psf_char(framebuffer_t *framebuffer, u32 c, u16 cx, u16 cy, u32 fg, u32 bg) { PSF_font *font = (PSF_font*)&_binary_font_psfu_start; // we need to know how many bytes encode one row int bytesperline = (font->width + 7) / 8; // get the glyph for the character. If there's no // glyph for a given character, we'll display the first glyph. - uint8_t *glyph = (uint8_t*)&_binary_font_psfu_start + font->headersize + + u8 *glyph = (u8*)&_binary_font_psfu_start + font->headersize + (c > 0 && c < font->numglyph ? c : 0) * font->bytesperglyph; // calculate the upper left corner on screen where we want to display. // we only do this once, and adjust the whereet later. This is faster. @@ -20,10 +20,10 @@ void draw_psf_char(framebuffer_t *framebuffer, uint32_t c, uint16_t cx, uint16_t mask = 1 << (font->width - 1); // display a row for (x = 0; x < font->width; x++) { - *((uint32_t*)(framebuffer->address + line)) = *((uint32_t*)glyph) & mask ? fg : bg; + *((u32*)(framebuffer->address + line)) = *((u32*)glyph) & mask ? fg : bg; // adjust to the next pixel mask >>= 1; - line += 4; + line += framebuffer->pixelwidth; } // adjust to the next line glyph += bytesperline; diff --git a/arch/i386/drivers/tar/tar.c b/arch/x86_64/drivers/tar/tar.c similarity index 100% rename from arch/i386/drivers/tar/tar.c rename to arch/x86_64/drivers/tar/tar.c diff --git a/arch/i386/drivers/terminal/terminal.c b/arch/x86_64/drivers/terminal/terminal.c similarity index 53% rename from arch/i386/drivers/terminal/terminal.c rename to arch/x86_64/drivers/terminal/terminal.c index e17a516..cd14d6d 100644 --- a/arch/i386/drivers/terminal/terminal.c +++ b/arch/x86_64/drivers/terminal/terminal.c @@ -1,17 +1,16 @@ #include #include -size_t terminal_row; -size_t terminal_column; -uint8_t terminal_color; -uint16_t *terminal_buffer; +usize terminal_row; +usize terminal_column; +u8 terminal_color; framebuffer_t *terminal_framebuffer; void terminal_clear() { - 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; - terminal_buffer[index] = vga_entry(' ', terminal_color); + for (usize y = 0; y < terminal_height; y++) { + for (usize x = 0; x < terminal_width; x++) { + const usize index = y * terminal_width + x; + //terminal_buffer[index] = vga_entry(' ', terminal_color); } } } @@ -38,10 +37,10 @@ void* terminal_devwrite(void* data) { int terminal_initialize(framebuffer_t *terminal_fb) { terminal_framebuffer = terminal_fb; + terminal_width = terminal_framebuffer->width / 8; + terminal_height = terminal_framebuffer->height / 16; terminal_row = 0; terminal_column = 0; - terminal_color = vga_entry_color(VGA_COLOR_BLACK, VGA_COLOR_WHITE); - terminal_buffer = (uint16_t*) 0xB8000; terminal_clear(); struct device terminal_device = { @@ -52,56 +51,45 @@ int terminal_initialize(framebuffer_t *terminal_fb) { return push_device(terminal_device); } -void terminal_setcolor(uint8_t color) { +void terminal_setcolor(u8 color) { terminal_color = color; } -void terminal_clearline(size_t line) { - for (size_t x = 0; x < VGA_WIDTH; x++) { - const size_t index = line * VGA_WIDTH + x; - terminal_buffer[index] = vga_entry(' ', terminal_color); +void terminal_clearline(usize line) { + for (usize x = 0; x < terminal_width; x++) { + const usize index = line * terminal_width + x; + //terminal_buffer[index] = vga_entry(' ', terminal_color); } } -void terminal_clearlines(size_t from, size_t to) { - for (size_t y = from; y <= to; y++) { - for (size_t x = 0; x < VGA_WIDTH; x++) { - const size_t index = y * VGA_WIDTH + x; - terminal_buffer[index] = vga_entry(' ', terminal_color); +void terminal_clearlines(usize from, usize to) { + for (usize y = from; y <= to; y++) { + for (usize x = 0; x < terminal_width; x++) { + const usize index = y * terminal_width + x; + //terminal_buffer[index] = vga_entry(' ', terminal_color); } } } void terminal_updatecursor() { - size_t temp = terminal_row * VGA_WIDTH + terminal_column; + /* + usize temp = terminal_row * terminal_width + terminal_column; outportb(0x3D4, 14); outportb(0x3D5, temp >> 8); outportb(0x3D4, 15); outportb(0x3D5, temp); -} - -void terminal_scrollup() { - for (size_t index = 0; index < VGA_WIDTH * (VGA_HEIGHT - 1); index++) { - terminal_buffer[index] = terminal_buffer[index + VGA_WIDTH]; - } - terminal_clearline(VGA_HEIGHT); - if ((terminal_row - 1) < 0) { - terminal_row = 0; - terminal_column = 0; - } else { - terminal_row -= 1; - } - terminal_updatecursor(); + */ + } void terminal_checknewline() { - if (terminal_row >= VGA_HEIGHT - 1) { - terminal_scrollup(); + if (terminal_row >= terminal_height - 1) { + //terminal_scrollup(); } } -void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) { - //terminal_buffer[y * VGA_WIDTH + x] = vga_entry(c, color); +void terminal_putentryat(char c, u8 color, usize x, usize y) { + //terminal_buffer[y * terminal_width + x] = vga_entry(c, color); draw_psf_char(terminal_framebuffer, c, x, y, 0xFFFFFFFF, 0); } @@ -111,7 +99,7 @@ void terminal_putchar(char c) { case '\b': if (--terminal_column < 0) { if (terminal_row-- > 0) { - terminal_column = VGA_WIDTH - 1; + terminal_column = terminal_width - 1; terminal_putentryat(' ', terminal_color, terminal_column, terminal_row); } } else { @@ -131,7 +119,7 @@ void terminal_putchar(char c) { terminal_column++; } - if (terminal_column >= VGA_WIDTH) { + if (terminal_column >= terminal_width) { terminal_column = 0; terminal_row++; } @@ -140,7 +128,7 @@ void terminal_putchar(char c) { terminal_checknewline(); } -void terminal_write(const char* data, size_t size) { - for (size_t i = 0; i < size; i++) +void terminal_write(const char* data, usize size) { + for (usize i = 0; i < size; i++) terminal_putchar(data[i]); } diff --git a/arch/i386/boot/kernel.c b/arch/x86_64/kernel.c similarity index 64% rename from arch/i386/boot/kernel.c rename to arch/x86_64/kernel.c index ba561ee..47a44ca 100644 --- a/arch/i386/boot/kernel.c +++ b/arch/x86_64/kernel.c @@ -1,5 +1,5 @@ -#include -#include +#include + #include #include #include @@ -12,11 +12,9 @@ #include #include #include +#include -// We need to tell the stivale bootloader where we want our stack to be. -// We are going to allocate our stack as an uninitialised array in .bss. -static uint8_t stack[4096]; -void kmain(); +static u8 stack[16384]; bool is_running = true; int keyboard_descriptor = 0; @@ -42,7 +40,7 @@ static struct stivale2_header_tag_framebuffer framebuffer_hdr_tag = { .framebuffer_height = 600, .framebuffer_bpp = 32 }; - + // The stivale2 specification says we need to define a "header structure". // This structure needs to reside in the .stivale2hdr ELF section in order // for the bootloader to find it. We use this __attribute__ directive to @@ -64,10 +62,8 @@ static struct stivale2_header stivale_hdr = { // points to the first one in the linked list. .tags = (uintptr_t)&framebuffer_hdr_tag }; - -// We will now write a helper function which will allow us to scan for tags -// that we want FROM the bootloader (structure tags). -void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, uint64_t id) { + +void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, u64 id) { struct stivale2_tag *current_tag = (void *)stivale2_struct->tags; for (;;) { // If the tag pointer is NULL (end of linked list), we did not find @@ -89,39 +85,83 @@ void *stivale2_get_tag(struct stivale2_struct *stivale2_struct, uint64_t id) { framebuffer_t *framebuffer; -// The following will be our kernel's entry point. +extern usize _kernel_start; +extern usize _kernel_end; + void _start(struct stivale2_struct *stivale2_struct) { - struct stivale2_struct_tag_framebuffer *tagfb = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID); + struct stivale2_struct_tag_framebuffer *tag_fb = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_FRAMEBUFFER_ID); + struct stivale2_struct_tag_memmap *tag_mmap = stivale2_get_tag(stivale2_struct, STIVALE2_STRUCT_TAG_MEMMAP_ID); - if (tagfb == NULL) { + if (tag_fb == NULL || tag_mmap == NULL) { printf("Requested stivale2 tags were not found, hanging..."); for (;;) { asm ("hlt"); } } - framebuffer->address = (uint8_t*)tagfb->framebuffer_addr; - framebuffer->width = tagfb->framebuffer_width; - framebuffer->height = tagfb->framebuffer_height; - framebuffer->depth = tagfb->framebuffer_bpp; - framebuffer->pitch = tagfb->framebuffer_pitch; - framebuffer->pixelwidth = tagfb->framebuffer_bpp / 8; + + framebuffer->address = (u8*)tag_fb->framebuffer_addr; + framebuffer->width = tag_fb->framebuffer_width; + framebuffer->height = tag_fb->framebuffer_height; + framebuffer->depth = tag_fb->framebuffer_bpp; + framebuffer->pitch = tag_fb->framebuffer_pitch; + framebuffer->pixelwidth = tag_fb->framebuffer_bpp / 8; terminal_descriptor = terminal_initialize(framebuffer); printf("Terminal initialized, descriptor: %d\n", terminal_descriptor); - printf("Framebuffer | addr: %#X, width: %d, height: %d, depth: %d, pitch: %d\n", framebuffer->address, framebuffer->width, framebuffer->height, framebuffer->depth, framebuffer->pitch, framebuffer->pixelwidth); - - kmain(); -} + printf("Framebuffer | addr: %#lX, width: %d, height: %d, depth: %d, pitch: %d\n", (usize)framebuffer->address, framebuffer->width, framebuffer->height, framebuffer->depth, framebuffer->pitch); -void shell() { + u64 total_memory = 0; + for (u64 i = 0; i < tag_mmap->entries; i++) { + struct stivale2_mmap_entry entry = tag_mmap->memmap[i]; + char *entry_name; + switch (entry.type) { + case STIVALE2_MMAP_USABLE: entry_name = "Usable"; break; + case STIVALE2_MMAP_RESERVED: entry_name = "Reserved"; break; + case STIVALE2_MMAP_ACPI_RECLAIMABLE: entry_name = "ACPI Reclaimable"; break; + case STIVALE2_MMAP_ACPI_NVS: entry_name = "ACPI NVS"; break; + case STIVALE2_MMAP_BAD_MEMORY: entry_name = "Bad Memory"; break; + case STIVALE2_MMAP_BOOTLOADER_RECLAIMABLE: entry_name = "Bootloader Reclaimable"; break; + case STIVALE2_MMAP_KERNEL_AND_MODULES: entry_name = "Kernel and Modules"; break; + case STIVALE2_MMAP_FRAMEBUFFER: entry_name = "Framebuffer"; break; + default: entry_name = "Unknown"; + } + total_memory += entry.length; + printf("Memory map entry | name: %s, base: %#lX, length: %ld KiB\n", entry_name, entry.base, entry.length / 1024); + } + printf("Total memory: %ld KiB\n", total_memory / 1024); + //printf("\"\"\"Used\"\"\" memory: %ld B\n", (_kernel_end - _kernel_start)); + + printf("Preparing interrupts... "); + pic_init(); + isr_install(); + printf("done\n"); + /* + printf("Preparing IDE driver... \n"); + printf("Searching for IDE devices... \n"); + ide_init(); + */ + fillrect(framebuffer, 750, 550, 25, 25, 0x00FFD5FF); + + keyboard_descriptor = keyboard_init(); + printf("Keyboard ready, descriptor: %d\n", keyboard_descriptor); + + printf("Are interrupts enabled? "); + if (are_interrupts_enabled() == 1) { + printf("yes\n"); + } else { + printf("no\n"); + } + + printf("_start memory address: %#lX\n", (usize)_start); + printf("----------\n"); printf("hello yes"); while (is_running) { printf("\n> "); while (true) { - uint32_t scancode = (uint32_t)read(keyboard_descriptor, NULL); + usize scancode = (usize)read(keyboard_descriptor, NULL); if (!scancode) continue; bool special = true; @@ -153,70 +193,3 @@ void shell() { } } } - -extern void load_page_directory(uint32_t); -extern void enable_paging(); - -uint32_t page_directory[1024] __attribute__((aligned(4096))); -uint32_t first_page_table[1024] __attribute__((aligned(4096))); -uint32_t second_page_table[1024] __attribute__((aligned(4096))); - -#define PAGE_PRESENT 1 << 0 -#define PAGE_WRITABLE 1 << 1 -#define PAGE_USER 1 << 2 -#define PAGE_WRITE_THROUGH 1 << 3 -#define PAGE_CACHE_DISABLE 1 << 4 -#define PAGE_ACCESSED 1 << 5 -#define PAGE_DIRTY 1 << 6 -#define PAGE_LARGE 1 << 7 -#define PAGE_GLOBAL 1 << 8 -/* -void setup_paging() { - // set each entry to not present - for (uint32_t i = 0; i < 1024; i++) { - page_directory[i] = 0; - } - - // i holds the physical address where we want to start mapping these pages to. - // in this case, we want to map these pages to the very beginning of memory. - // we will fill all 1024 entries in the table, mapping 4 megabytes - for (uint32_t i = 0; i < 1024; i++) { - first_page_table[i] = (i * 0x1000) | PAGE_PRESENT | PAGE_WRITABLE; - } - - page_directory[0] = ((uint32_t)first_page_table) | PAGE_PRESENT | PAGE_WRITABLE; - - load_page_directory((uint32_t)page_directory); - enable_paging(); -} -*/ -void kmain() { - //setup_paging(); - - printf("Preparing interrupts... "); - pic_init(); - isr_install(); - printf("done\n"); - - printf("Preparing IDE driver... \n"); - printf("Searching for IDE devices... \n"); - ide_init(); - - fillrect(framebuffer, 500, 200, 100, 100, 0x00FFD5FF); - fillrect(framebuffer, 600, 300, 100, 100, 0xFF00D5FF); - - keyboard_descriptor = keyboard_init(); - printf("Keyboard ready, descriptor: %d\n", keyboard_descriptor); - - printf("Are interrupts enabled? "); - if (are_interrupts_enabled() == 1) { - printf("yes\n"); - } else { - printf("no\n"); - } - - printf("kmain memory address: %#X\n", (unsigned int)kmain); - - printf("----------\n"); - shell(); -} diff --git a/arch/x86_64/paging.c b/arch/x86_64/paging.c new file mode 100644 index 0000000..8874441 --- /dev/null +++ b/arch/x86_64/paging.c @@ -0,0 +1,18 @@ +#include + +// see amd64 architecture manual https://www.amd.com/system/files/TechDocs/24593.pdf +// page 200 for more information + +void map_page(u64 physical, u64 virtual) { + address_t a; + a.int_address = virtual; + u64 *pdp = (PML4[a.parsed_address.pml4_offset] & PAGE_ADDRESS_MASK) >> 12; + u64 *pd = (pdp[a.parsed_address.pdp_offset] & PAGE_ADDRESS_MASK) >> 12; + u64 *pt = (pd[a.parsed_address.pd_offset] & PAGE_ADDRESS_MASK) >> 12; + pt[a.parsed_address.pt_offset] = (physical & (PAGE_ADDRESS_MASK >> 12)); +} + +void setup_paging(u64 total_memory) { + page_bitmap->size = (total_memory / 4096 + 1) * 8; + memset(page_bitmap->contents, 0, page_bitmap->size / 8); +} diff --git a/arch/i386/std/stdio.c b/arch/x86_64/std/stdio.c similarity index 98% rename from arch/i386/std/stdio.c rename to arch/x86_64/std/stdio.c index bac757f..739f79f 100644 --- a/arch/i386/std/stdio.c +++ b/arch/x86_64/std/stdio.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include // shamelessly stolen from https://wiki.osdev.org/User:A22347/Printf @@ -253,7 +253,7 @@ int vprintf (const char* format, va_list list) } case 'z': { - size_t integer = va_arg(list, size_t); + usize integer = va_arg(list, usize); __int_str(integer, intStrBuffer, base, plusSign, spaceNoSign, lengthSpec, leftJustify, zeroPad); displayString(intStrBuffer, &chars); break; @@ -319,7 +319,7 @@ int vprintf (const char* format, va_list list) } case 'z': { - size_t integer = va_arg(list, size_t); + usize integer = va_arg(list, usize); __int_str(integer, intStrBuffer, base, plusSign, spaceNoSign, lengthSpec, leftJustify, zeroPad); displayString(intStrBuffer, &chars); break; @@ -380,7 +380,7 @@ int vprintf (const char* format, va_list list) *(va_arg(list, intmax_t*)) = chars; break; case 'z': - *(va_arg(list, size_t*)) = chars; + *(va_arg(list, usize*)) = chars; break; case 't': *(va_arg(list, ptrdiff_t*)) = chars; diff --git a/arch/i386/std/string.c b/arch/x86_64/std/string.c similarity index 69% rename from arch/i386/std/string.c rename to arch/x86_64/std/string.c index bd29099..76a3e64 100644 --- a/arch/i386/std/string.c +++ b/arch/x86_64/std/string.c @@ -1,9 +1,9 @@ #include -int memcmp(const void* aptr, const void* bptr, size_t size) { +int memcmp(const void* aptr, const void* bptr, usize size) { const unsigned char* a = (const unsigned char*) aptr; const unsigned char* b = (const unsigned char*) bptr; - for (size_t i = 0; i < size; i++) { + for (usize i = 0; i < size; i++) { if (a[i] < b[i]) return -1; else if (b[i] < a[i]) @@ -12,36 +12,36 @@ int memcmp(const void* aptr, const void* bptr, size_t size) { return 0; } -void* memcpy(void* restrict dstptr, const void* restrict srcptr, size_t size) { +void* memcpy(void* restrict dstptr, const void* restrict srcptr, usize size) { unsigned char* dst = (unsigned char*) dstptr; const unsigned char* src = (const unsigned char*) srcptr; - for (size_t i = 0; i < size; i++) + for (usize i = 0; i < size; i++) dst[i] = src[i]; return dstptr; } -void* memmove(void* dstptr, const void* srcptr, size_t size) { +void* memmove(void* dstptr, const void* srcptr, usize size) { unsigned char* dst = (unsigned char*) dstptr; const unsigned char* src = (const unsigned char*) srcptr; if (dst < src) { - for (size_t i = 0; i < size; i++) + for (usize i = 0; i < size; i++) dst[i] = src[i]; } else { - for (size_t i = size; i != 0; i--) + for (usize i = size; i != 0; i--) dst[i-1] = src[i-1]; } return dstptr; } -void* memset(void* bufptr, int value, size_t size) { +void* memset(void* bufptr, int value, usize size) { unsigned char* buf = (unsigned char*) bufptr; - for (size_t i = 0; i < size; i++) + for (usize i = 0; i < size; i++) buf[i] = (unsigned char) value; return bufptr; } -size_t strlen(const char* str) { - size_t len = 0; +usize strlen(const char* str) { + usize len = 0; while (str[len]) len++; return len; diff --git a/arch/i386/std/util.c b/arch/x86_64/std/util.c similarity index 79% rename from arch/i386/std/util.c rename to arch/x86_64/std/util.c index 9315daf..44050d8 100644 --- a/arch/i386/std/util.c +++ b/arch/x86_64/std/util.c @@ -1,18 +1,13 @@ #include -void* malloc(size_t amount) { - char variable[amount]; - return &variable; -} - -static size_t rand_next = 1; +static usize rand_next = 1; int rand(void) { rand_next = rand_next * 1103515245 + 12345; - return (size_t)(rand_next/65536) % 32768; + return (usize)(rand_next/65536) % 32768; } -void srand(size_t seed) { +void srand(usize seed) { rand_next = seed; } @@ -47,4 +42,4 @@ unsigned int atoi(const char *in) { size += ((in[j - 1] - '0') * count); return size; -} \ No newline at end of file +} diff --git a/include/drivers/ahci/ahci.h b/include/drivers/ahci/ahci.h index 5ef4bc8..e00b03d 100644 --- a/include/drivers/ahci/ahci.h +++ b/include/drivers/ahci/ahci.h @@ -1,9 +1,5 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - // AHCI driver, source: https://wiki.osdev.org/AHCI // FIS = Frame Information Structure @@ -23,51 +19,51 @@ typedef enum { // ---- Various other FIS things (this struct was not found in OSDev wiki) typedef struct tagFIS_SET_DEVICE_BITS { - uint8_t fis_type; - uint8_t pmport:4; - uint8_t rsvd:2; - uint8_t i:1; - uint8_t n:1; - uint8_t statusl:3; - uint8_t rsvd2:1; - uint8_t statush:3; - uint8_t rsvd3:1; - uint8_t error; + u8 fis_type; + u8 pmport:4; + u8 rsvd:2; + u8 i:1; + u8 n:1; + u8 statusl:3; + u8 rsvd2:1; + u8 statush:3; + u8 rsvd3:1; + u8 error; } FIS_DEV_BITS; // ---- Register FIS - Host to Device ---- typedef struct tagFIS_REG_H2D { // DWORD 0 - uint8_t fis_type; // FIS_TYPE_REG_H2D + u8 fis_type; // FIS_TYPE_REG_H2D - uint8_t pmport:4; // Port multiplier - uint8_t rsv0:3; // Reserved - uint8_t c:1; // 1: Command, 0: Control + u8 pmport:4; // Port multiplier + u8 rsv0:3; // Reserved + u8 c:1; // 1: Command, 0: Control - uint8_t command; // Command register - uint8_t featurel; // Feature register, 7:0 + u8 command; // Command register + u8 featurel; // Feature register, 7:0 // DWORD 1 - uint8_t lba0; // LBA low register, 7:0 - uint8_t lba1; // LBA mid register, 15:8 - uint8_t lba2; // LBA high register, 23:16 - uint8_t device; // Device register + u8 lba0; // LBA low register, 7:0 + u8 lba1; // LBA mid register, 15:8 + u8 lba2; // LBA high register, 23:16 + u8 device; // Device register // DWORD 2 - uint8_t lba3; // LBA register, 31:24 - uint8_t lba4; // LBA register, 39:32 - uint8_t lba5; // LBA register, 47:40 - uint8_t featureh; // Feature register, 15:8 + u8 lba3; // LBA register, 31:24 + u8 lba4; // LBA register, 39:32 + u8 lba5; // LBA register, 47:40 + u8 featureh; // Feature register, 15:8 // DWORD 3 - uint8_t countl; // Count register, 7:0 - uint8_t counth; // Count register, 15:8 - uint8_t icc; // Isochronous command completion - uint8_t control; // Control register + u8 countl; // Count register, 7:0 + u8 counth; // Count register, 15:8 + u8 icc; // Isochronous command completion + u8 control; // Control register // DWORD 4 - uint8_t rsv1[4]; // Reserved + u8 rsv1[4]; // Reserved } FIS_REG_H2D; // ---- Register FIS – Device to Host ---- @@ -75,164 +71,164 @@ typedef struct tagFIS_REG_H2D typedef struct tagFIS_REG_D2H { // DWORD 0 - uint8_t fis_type; // FIS_TYPE_REG_D2H + u8 fis_type; // FIS_TYPE_REG_D2H - uint8_t pmport:4; // Port multiplier - uint8_t rsv0:2; // Reserved - uint8_t i:1; // Interrupt bit - uint8_t rsv1:1; // Reserved + u8 pmport:4; // Port multiplier + u8 rsv0:2; // Reserved + u8 i:1; // Interrupt bit + u8 rsv1:1; // Reserved - uint8_t status; // Status register - uint8_t error; // Error register + u8 status; // Status register + u8 error; // Error register // DWORD 1 - uint8_t lba0; // LBA low register, 7:0 - uint8_t lba1; // LBA mid register, 15:8 - uint8_t lba2; // LBA high register, 23:16 - uint8_t device; // Device register + u8 lba0; // LBA low register, 7:0 + u8 lba1; // LBA mid register, 15:8 + u8 lba2; // LBA high register, 23:16 + u8 device; // Device register // DWORD 2 - uint8_t lba3; // LBA register, 31:24 - uint8_t lba4; // LBA register, 39:32 - uint8_t lba5; // LBA register, 47:40 - uint8_t rsv2; // Reserved + u8 lba3; // LBA register, 31:24 + u8 lba4; // LBA register, 39:32 + u8 lba5; // LBA register, 47:40 + u8 rsv2; // Reserved // DWORD 3 - uint8_t countl; // Count register, 7:0 - uint8_t counth; // Count register, 15:8 - uint8_t rsv3[2]; // Reserved + u8 countl; // Count register, 7:0 + u8 counth; // Count register, 15:8 + u8 rsv3[2]; // Reserved // DWORD 4 - uint8_t rsv4[4]; // Reserved + u8 rsv4[4]; // Reserved } FIS_REG_D2H; // ---- Data FIS – Bidirectional ---- // This FIS is used by the host or device to send data payload. The data size can be varied. typedef struct tagFIS_DATA { // DWORD 0 - uint8_t fis_type; // FIS_TYPE_DATA + u8 fis_type; // FIS_TYPE_DATA - uint8_t pmport:4; // Port multiplier - uint8_t rsv0:4; // Reserved + u8 pmport:4; // Port multiplier + u8 rsv0:4; // Reserved - uint8_t rsv1[2]; // Reserved + u8 rsv1[2]; // Reserved // DWORD 1 ~ N - uint32_t data[1]; // Payload + u32 data[1]; // Payload } FIS_DATA; // ---- PIO Setup – Device to Host ---- // This FIS is used by the device to tell the host that it’s about to send or ready to receive a PIO data payload. typedef struct tagFIS_PIO_SETUP { // DWORD 0 - uint8_t fis_type; // FIS_TYPE_PIO_SETUP + u8 fis_type; // FIS_TYPE_PIO_SETUP - uint8_t pmport:4; // Port multiplier - uint8_t rsv0:1; // Reserved - uint8_t d:1; // Data transfer direction, 1 - device to host - uint8_t i:1; // Interrupt bit - uint8_t rsv1:1; + u8 pmport:4; // Port multiplier + u8 rsv0:1; // Reserved + u8 d:1; // Data transfer direction, 1 - device to host + u8 i:1; // Interrupt bit + u8 rsv1:1; - uint8_t status; // Status register - uint8_t error; // Error register + u8 status; // Status register + u8 error; // Error register // DWORD 1 - uint8_t lba0; // LBA low register, 7:0 - uint8_t lba1; // LBA mid register, 15:8 - uint8_t lba2; // LBA high register, 23:16 - uint8_t device; // Device register + u8 lba0; // LBA low register, 7:0 + u8 lba1; // LBA mid register, 15:8 + u8 lba2; // LBA high register, 23:16 + u8 device; // Device register // DWORD 2 - uint8_t lba3; // LBA register, 31:24 - uint8_t lba4; // LBA register, 39:32 - uint8_t lba5; // LBA register, 47:40 - uint8_t rsv2; // Reserved + u8 lba3; // LBA register, 31:24 + u8 lba4; // LBA register, 39:32 + u8 lba5; // LBA register, 47:40 + u8 rsv2; // Reserved // DWORD 3 - uint8_t countl; // Count register, 7:0 - uint8_t counth; // Count register, 15:8 - uint8_t rsv3; // Reserved - uint8_t e_status; // New value of status register + u8 countl; // Count register, 7:0 + u8 counth; // Count register, 15:8 + u8 rsv3; // Reserved + u8 e_status; // New value of status register // DWORD 4 - uint16_t tc; // Transfer count - uint8_t rsv4[2]; // Reserved + u16 tc; // Transfer count + u8 rsv4[2]; // Reserved } FIS_PIO_SETUP; // ---- DMA Setup – Device to Host ---- typedef struct tagFIS_DMA_SETUP { // DWORD 0 - uint8_t fis_type; // FIS_TYPE_DMA_SETUP + u8 fis_type; // FIS_TYPE_DMA_SETUP - uint8_t pmport:4; // Port multiplier - uint8_t rsv0:1; // Reserved - uint8_t d:1; // Data transfer direction, 1 - device to host - uint8_t i:1; // Interrupt bit - uint8_t a:1; // Auto-activate. Specifies if DMA Activate FIS is needed + u8 pmport:4; // Port multiplier + u8 rsv0:1; // Reserved + u8 d:1; // Data transfer direction, 1 - device to host + u8 i:1; // Interrupt bit + u8 a:1; // Auto-activate. Specifies if DMA Activate FIS is needed - uint8_t rsved[2]; // Reserved + u8 rsved[2]; // Reserved //DWORD 1&2 - uint64_t DMAbufferID; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work. + u64 DMAbufferID; // DMA Buffer Identifier. Used to Identify DMA buffer in host memory. SATA Spec says host specific and not in Spec. Trying AHCI spec might work. //DWORD 3 - uint32_t rsvd; //More reserved + u32 rsvd; //More reserved //DWORD 4 - uint32_t DMAbufOffset; //Byte offset into buffer. First 2 bits must be 0 + u32 DMAbufOffset; //Byte offset into buffer. First 2 bits must be 0 //DWORD 5 - uint32_t TransferCount; //Number of bytes to transfer. Bit 0 must be 0 + u32 TransferCount; //Number of bytes to transfer. Bit 0 must be 0 //DWORD 6 - uint32_t resvd; //Reserved + u32 resvd; //Reserved } FIS_DMA_SETUP; // ---- Memory structs (HBA memory registers) ---- typedef volatile struct tagHBA_PORT { - uint32_t clb; // 0x00, command list base address, 1K-byte aligned - uint32_t clbu; // 0x04, command list base address upper 32 bits - uint32_t fb; // 0x08, FIS base address, 256-byte aligned - uint32_t fbu; // 0x0C, FIS base address upper 32 bits - uint32_t is; // 0x10, interrupt status - uint32_t ie; // 0x14, interrupt enable - uint32_t cmd; // 0x18, command and status - uint32_t rsv0; // 0x1C, Reserved - uint32_t tfd; // 0x20, task file data - uint32_t sig; // 0x24, signature - uint32_t ssts; // 0x28, SATA status (SCR0:SStatus) - uint32_t sctl; // 0x2C, SATA control (SCR2:SControl) - uint32_t serr; // 0x30, SATA error (SCR1:SError) - uint32_t sact; // 0x34, SATA active (SCR3:SActive) - uint32_t ci; // 0x38, command issue - uint32_t sntf; // 0x3C, SATA notification (SCR4:SNotification) - uint32_t fbs; // 0x40, FIS-based switch control - uint32_t rsv1[11]; // 0x44 ~ 0x6F, Reserved - uint32_t vendor[4]; // 0x70 ~ 0x7F, vendor specific + u32 clb; // 0x00, command list base address, 1K-byte aligned + u32 clbu; // 0x04, command list base address upper 32 bits + u32 fb; // 0x08, FIS base address, 256-byte aligned + u32 fbu; // 0x0C, FIS base address upper 32 bits + u32 is; // 0x10, interrupt status + u32 ie; // 0x14, interrupt enable + u32 cmd; // 0x18, command and status + u32 rsv0; // 0x1C, Reserved + u32 tfd; // 0x20, task file data + u32 sig; // 0x24, signature + u32 ssts; // 0x28, SATA status (SCR0:SStatus) + u32 sctl; // 0x2C, SATA control (SCR2:SControl) + u32 serr; // 0x30, SATA error (SCR1:SError) + u32 sact; // 0x34, SATA active (SCR3:SActive) + u32 ci; // 0x38, command issue + u32 sntf; // 0x3C, SATA notification (SCR4:SNotification) + u32 fbs; // 0x40, FIS-based switch control + u32 rsv1[11]; // 0x44 ~ 0x6F, Reserved + u32 vendor[4]; // 0x70 ~ 0x7F, vendor specific } HBA_PORT; typedef volatile struct tagHBA_MEM { // 0x00 - 0x2B, Generic Host Control - uint32_t cap; // 0x00, Host capability - uint32_t ghc; // 0x04, Global host control - uint32_t is; // 0x08, Interrupt status - uint32_t pi; // 0x0C, Port implemented - uint32_t vs; // 0x10, Version - uint32_t ccc_ctl; // 0x14, Command completion coalescing control - uint32_t ccc_pts; // 0x18, Command completion coalescing ports - uint32_t em_loc; // 0x1C, Enclosure management location - uint32_t em_ctl; // 0x20, Enclosure management control - uint32_t cap2; // 0x24, Host capabilities extended - uint32_t bohc; // 0x28, BIOS/OS handoff control and status + u32 cap; // 0x00, Host capability + u32 ghc; // 0x04, Global host control + u32 is; // 0x08, Interrupt status + u32 pi; // 0x0C, Port implemented + u32 vs; // 0x10, Version + u32 ccc_ctl; // 0x14, Command completion coalescing control + u32 ccc_pts; // 0x18, Command completion coalescing ports + u32 em_loc; // 0x1C, Enclosure management location + u32 em_ctl; // 0x20, Enclosure management control + u32 cap2; // 0x24, Host capabilities extended + u32 bohc; // 0x28, BIOS/OS handoff control and status // 0x2C - 0x9F, Reserved - uint8_t rsv[0xA0-0x2C]; + u8 rsv[0xA0-0x2C]; // 0xA0 - 0xFF, Vendor specific registers - uint8_t vendor[0x100-0xA0]; + u8 vendor[0x100-0xA0]; // 0x100 - 0x10FF, Port control registers HBA_PORT ports[1]; // 1 ~ 32 @@ -242,75 +238,75 @@ typedef volatile struct tagHBA_MEM { typedef volatile struct tagHBA_FIS { // 0x00 FIS_DMA_SETUP dsfis; // DMA Setup FIS - uint8_t pad0[4]; + u8 pad0[4]; // 0x20 FIS_PIO_SETUP psfis; // PIO Setup FIS - uint8_t pad1[12]; + u8 pad1[12]; // 0x40 FIS_REG_D2H rfis; // Register – Device to Host FIS - uint8_t pad2[4]; + u8 pad2[4]; // 0x58 FIS_DEV_BITS sdbfis; // Set Device Bit FIS // 0x60 - uint8_t ufis[64]; + u8 ufis[64]; // 0xA0 - uint8_t rsv[0x100-0xA0]; + u8 rsv[0x100-0xA0]; } HBA_FIS; // ---- Command List ---- typedef struct tagHBA_CMD_HEADER { // DW0 - uint8_t cfl:5; // Command FIS length in DWORDS, 2 ~ 16 - uint8_t a:1; // ATAPI - uint8_t w:1; // Write, 1: H2D, 0: D2H - uint8_t p:1; // Prefetchable + u8 cfl:5; // Command FIS length in DWORDS, 2 ~ 16 + u8 a:1; // ATAPI + u8 w:1; // Write, 1: H2D, 0: D2H + u8 p:1; // Prefetchable - uint8_t r:1; // Reset - uint8_t b:1; // BIST - uint8_t c:1; // Clear busy upon R_OK - uint8_t rsv0:1; // Reserved - uint8_t pmp:4; // Port multiplier port + u8 r:1; // Reset + u8 b:1; // BIST + u8 c:1; // Clear busy upon R_OK + u8 rsv0:1; // Reserved + u8 pmp:4; // Port multiplier port - uint16_t prdtl; // Physical region descriptor table length in entries + u16 prdtl; // Physical region descriptor table length in entries // DW1 volatile - uint32_t prdbc; // Physical region descriptor byte count transferred + u32 prdbc; // Physical region descriptor byte count transferred // DW2, 3 - uint32_t ctba; // Command table descriptor base address - uint32_t ctbau; // Command table descriptor base address upper 32 bits + u32 ctba; // Command table descriptor base address + u32 ctbau; // Command table descriptor base address upper 32 bits // DW4 - 7 - uint32_t rsv1[4]; // Reserved + u32 rsv1[4]; // Reserved } HBA_CMD_HEADER; // ---- Command Table and Physical Region Descriptor Table ---- typedef struct tagHBA_PRDT_ENTRY { - uint32_t dba; // Data base address - uint32_t dbau; // Data base address upper 32 bits - uint32_t rsv0; // Reserved + u32 dba; // Data base address + u32 dbau; // Data base address upper 32 bits + u32 rsv0; // Reserved // DW3 - uint32_t dbc:22; // Byte count, 4M max - uint32_t rsv1:9; // Reserved - uint32_t i:1; // Interrupt on completion + u32 dbc:22; // Byte count, 4M max + u32 rsv1:9; // Reserved + u32 i:1; // Interrupt on completion } HBA_PRDT_ENTRY; typedef struct tagHBA_CMD_TBL { // 0x00 - uint8_t cfis[64]; // Command FIS + u8 cfis[64]; // Command FIS // 0x40 - uint8_t acmd[16]; // ATAPI command, 12 or 16 bytes + u8 acmd[16]; // ATAPI command, 12 or 16 bytes // 0x50 - uint8_t rsv[48]; // Reserved + u8 rsv[48]; // Reserved // 0x80 HBA_PRDT_ENTRY prdt_entry[1]; // Physical region descriptor table entries, 0 ~ 65535 @@ -345,7 +341,3 @@ typedef struct tagHBA_CMD_TBL { // ---- Functions ---- void ahci_init(void); - -#ifdef __cplusplus -} -#endif diff --git a/include/drivers/device/device.h b/include/drivers/device/device.h index 59819fe..9ff947e 100644 --- a/include/drivers/device/device.h +++ b/include/drivers/device/device.h @@ -1,9 +1,5 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - struct device { void* (*write)(void* data); void* (*read)(void* data); @@ -13,7 +9,3 @@ int push_device(struct device device); void* read(int descriptor, void* data); void* write(int descriptor, void* data); - -#ifdef __cplusplus -} -#endif diff --git a/include/drivers/ide/ide.h b/include/drivers/ide/ide.h index bb304bc..fb29749 100644 --- a/include/drivers/ide/ide.h +++ b/include/drivers/ide/ide.h @@ -1,11 +1,7 @@ #pragma once -#include -#include -#ifdef __cplusplus -extern "C" { -#endif +#include // ----> IDE Driver // Source: https://wiki.osdev.org/PCI_IDE_Controller @@ -103,8 +99,4 @@ extern "C" { // ---- Functions ----- void ide_init(); -uint8_t ide_write_sectors(unsigned char drive, unsigned int lba, uint8_t *buf); - -#ifdef __cplusplus -} -#endif +u8 ide_write_sectors(unsigned char drive, unsigned int lba, u8 *buf); diff --git a/include/drivers/idt/idt.h b/include/drivers/idt/idt.h index 1a7346f..35cad06 100644 --- a/include/drivers/idt/idt.h +++ b/include/drivers/idt/idt.h @@ -1,34 +1,33 @@ #pragma once -#include +#include #include -#ifdef __cplusplus -extern "C" { -#endif - -#define KERNEL_CODE_SEGMENT_OFFSET 0x08 +#define KERNEL_CODE_SEGMENT_OFFSET 40 #define INTERRUPT_GATE 0x8e -struct idt_entry { - unsigned short int offset_lowerbits; - unsigned short int selector; - unsigned char zero; - unsigned char type_attr; - unsigned short int offset_higherbits; -}; +typedef struct { + u16 isr_low; // The lower 16 bits of the ISR's address + u16 kernel_cs; // The GDT segment selector that the CPU will load into CS before calling the ISR + u8 ist; // The IST in the TSS that the CPU will load into RSP; set to zero for now + u8 attributes; // Type and attributes; see the IDT page + u16 isr_mid; // The higher 16 bits of the lower 32 bits of the ISR's address + u32 isr_high; // The higher 32 bits of the ISR's address + u32 reserved; // Set to zero +} __attribute__((packed)) idt_entry_t; -struct interrupt_frame { +typedef struct { + u16 limit; + u64 base; +} __attribute__((packed)) idtr_t; + +typedef struct { uintptr_t ip; uintptr_t cs; uintptr_t flags; uintptr_t sp; uintptr_t ss; -}; +} interrupt_frame_t; void idt_init(); -void idt_register_handler(uint8_t interrupt, unsigned long address); - -#ifdef __cplusplus -} -#endif +void idt_set_entry(u8 vector, void* isr, u8 flags); diff --git a/include/drivers/idt/isr.h b/include/drivers/idt/isr.h index 6fbd9e3..edd92ad 100644 --- a/include/drivers/idt/isr.h +++ b/include/drivers/idt/isr.h @@ -2,12 +2,4 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - void isr_install(void); - -#ifdef __cplusplus -} -#endif diff --git a/include/drivers/keyboard/keyboard.h b/include/drivers/keyboard/keyboard.h index a85cc79..d3d0c93 100644 --- a/include/drivers/keyboard/keyboard.h +++ b/include/drivers/keyboard/keyboard.h @@ -5,16 +5,8 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif - #define KBD_BUF_SIZE 256 int keyboard_init(void); -uint8_t keyboard_enabled(void); +u8 keyboard_enabled(void); unsigned char keyboard_get_key_from_scancode(unsigned char scancode); - -#ifdef __cplusplus -} -#endif diff --git a/include/drivers/pic/pic.h b/include/drivers/pic/pic.h index b384469..574deb3 100644 --- a/include/drivers/pic/pic.h +++ b/include/drivers/pic/pic.h @@ -2,10 +2,6 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - #define PIC1 0x20 #define PIC2 0xA0 #define PIC1_COMMAND PIC1 @@ -19,10 +15,6 @@ extern "C" { #define ICW4_8086 0x01 void pic_init(); -void pic_send_eoi(uint8_t no); -void pic_irq_enable(uint8_t no); -void pic_irq_disable(uint8_t no); - -#ifdef __cplusplus -} -#endif +void pic_send_eoi(u8 no); +void pic_irq_enable(u8 no); +void pic_irq_disable(u8 no); diff --git a/include/drivers/tar/tar.h b/include/drivers/tar/tar.h index 7a1c84c..a7701ca 100644 --- a/include/drivers/tar/tar.h +++ b/include/drivers/tar/tar.h @@ -1,9 +1,5 @@ #pragma once -#ifdef __cplusplus -extern "C" { -#endif - struct tar_header { char filename[100]; @@ -18,7 +14,3 @@ struct tar_header }; struct tar_header* tar_seek(int fd, char filename[100]); - -#ifdef __cplusplus -} -#endif diff --git a/include/drivers/terminal/terminal.h b/include/drivers/terminal/terminal.h index f5e42b6..686ca95 100644 --- a/include/drivers/terminal/terminal.h +++ b/include/drivers/terminal/terminal.h @@ -1,16 +1,12 @@ #pragma once -#include -#include + +#include #include #include #include #include -#ifdef __cplusplus -extern "C" { -#endif - /* Hardware text mode color constants. */ enum vga_color { VGA_COLOR_BLACK = 0, @@ -31,33 +27,32 @@ enum vga_color { VGA_COLOR_WHITE = 15, }; -static inline uint8_t vga_entry_color(const enum vga_color fg, const enum vga_color bg) { +static inline u8 vga_entry_color(const enum vga_color fg, const enum vga_color bg) { return fg | (bg << 4); } -static inline uint16_t vga_entry(const uint8_t uc, const uint8_t color) { - return (uint16_t) uc | (uint16_t) color << 8; +static inline u16 vga_entry(const u8 uc, const u8 color) { + return (u16) uc | (u16) color << 8; } -static const size_t VGA_WIDTH = 80; -static const size_t VGA_HEIGHT = 25; +static usize terminal_width; +static usize terminal_height; -extern size_t terminal_row; -extern size_t terminal_column; -extern uint8_t terminal_color; -extern uint16_t *terminal_buffer; +extern usize terminal_row; +extern usize terminal_column; +extern u8 terminal_color; +extern u16 *terminal_buffer; void terminal_clear(); int terminal_initialize(framebuffer_t *terminal_fb); -void terminal_setcolor(uint8_t color); -void terminal_clearline(size_t line); -void terminal_clearlines(size_t from, size_t to); +void terminal_setcolor(u8 color); +void terminal_clearline(usize line); +void terminal_clearlines(usize from, usize to); void terminal_updatecursor(); -void terminal_scrollup(); void terminal_checknewline(); -void terminal_putentryat(char c, uint8_t color, size_t x, size_t y); +void terminal_putentryat(char c, u8 color, usize x, usize y); void terminal_putchar(char c); -void terminal_write(const char* data, size_t size); +void terminal_write(const char* data, usize size); static inline void terminal_writestring(const char *data) { terminal_write(data, strlen(data)); @@ -67,7 +62,3 @@ static inline void terminal_writeline(const char *data) { terminal_writestring(data); terminal_putchar('\n'); } - -#ifdef __cplusplus -} -#endif diff --git a/include/framebuffer.h b/include/framebuffer.h index 14a412d..9a049c9 100644 --- a/include/framebuffer.h +++ b/include/framebuffer.h @@ -1,24 +1,16 @@ #pragma once -#include -#include -#ifdef __cplusplus -extern "C" { -#endif +#include typedef struct { - uint8_t *address; - uint32_t width; - uint32_t height; - uint32_t depth; - uint32_t pitch; - uint32_t pixelwidth; + u8 *address; + u32 width; + u32 height; + u32 depth; + u32 pitch; + u32 pixelwidth; } framebuffer_t; -void putpixel(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint32_t color); -void fillrect(framebuffer_t *framebuffer, uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint32_t color); - -#ifdef __cplusplus -} -#endif +void putpixel(framebuffer_t *framebuffer, u16 x, u16 y, u32 color); +void fillrect(framebuffer_t *framebuffer, u16 x, u16 y, u16 w, u16 h, u32 color); diff --git a/include/paging.h b/include/paging.h new file mode 100644 index 0000000..36b4f26 --- /dev/null +++ b/include/paging.h @@ -0,0 +1,36 @@ +#pragma once + +#include + +#define PAGE_PRESENT 1 << 0 +#define PAGE_WRITABLE 1 << 1 +#define PAGE_USER 1 << 2 +#define PAGE_WRITE_THROUGH 1 << 3 +#define PAGE_CACHE_DISABLE 1 << 4 +#define PAGE_ACCESSED 1 << 5 +#define PAGE_DIRTY 1 << 6 +#define PAGE_GLOBAL 1 << 8 +#define PAGE_NO_EXECUTE 1 << 63 + +#define PAGE_ADDRESS_MASK 0x000FFFFFFFFFF000 + +typedef struct { + u16 page_offset : 12; + u16 pt_offset : 9; + u16 pd_offset : 9; + u16 pdp_offset : 9; + u16 pml4_offset : 9; + u16 sign_extend : 16; +} __attribute__((packed)) parsed_address_t; + +typedef union { + u64 int_address; + parsed_address_t parsed_address; +} address_t; + +static u64 PML4[512] __attribute__((aligned(4096))); + +static bitmap_t *page_bitmap; + +void setup_paging(u64 total_memory); +void map_page(u64 physical, u64 virtual); diff --git a/include/psf.h b/include/psf.h index 829ca50..95362a6 100644 --- a/include/psf.h +++ b/include/psf.h @@ -1,24 +1,19 @@ #pragma once -#include -#include +#include #include -#ifdef __cplusplus -extern "C" { -#endif - #define PSF_FONT_MAGIC 0x864ab572 typedef struct { - uint32_t magic; /* magic bytes to identify PSF */ - uint32_t version; /* zero */ - uint32_t headersize; /* whereet of bitmaps in file, 32 */ - uint32_t flags; /* 0 if there's no unicode table */ - uint32_t numglyph; /* number of glyphs */ - uint32_t bytesperglyph; /* size of each glyph */ - uint32_t height; /* height in pixels */ - uint32_t width; /* width in pixels */ + u32 magic; /* magic bytes to identify PSF */ + u32 version; /* zero */ + u32 headersize; /* whereet of bitmaps in file, 32 */ + u32 flags; /* 0 if there's no unicode table */ + u32 numglyph; /* number of glyphs */ + u32 bytesperglyph; /* size of each glyph */ + u32 height; /* height in pixels */ + u32 width; /* width in pixels */ } PSF_font; // these are linked using objcopy @@ -26,8 +21,4 @@ extern char _binary_font_psfu_start; extern char _binary_font_psfu_end; // c is a unicode character, cx and cy are cursor position in characters -void draw_psf_char(framebuffer_t *framebuffer, uint32_t c, uint16_t cx, uint16_t cy, uint32_t fg, uint32_t bg); - -#ifdef __cplusplus -} -#endif +void draw_psf_char(framebuffer_t *framebuffer, u32 c, u16 cx, u16 cy, u32 fg, u32 bg); diff --git a/include/std/ctype.h b/include/std/ctype.h index f505716..8337686 100644 --- a/include/std/ctype.h +++ b/include/std/ctype.h @@ -2,14 +2,6 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - inline int isdigit(int c) { return c >= '0' && c <= '9'; } - -#ifdef __cplusplus -} -#endif diff --git a/include/std/inline.h b/include/std/inline.h index 11e5b52..34785ed 100644 --- a/include/std/inline.h +++ b/include/std/inline.h @@ -1,21 +1,17 @@ #pragma once #include -#include +#include -#ifdef __cplusplus -extern "C" { -#endif - -static inline void outportb(const uint16_t port, const uint8_t val) { +static inline void outportb(const u16 port, const u8 val) { asm volatile ( "outb %0, %1" : : "a"(val), "Nd"(port) ); } -static inline void outportw(const uint16_t port, const uint16_t val) { +static inline void outportw(const u16 port, const u16 val) { asm volatile ( "outw %0, %1" : : "a"(val), "Nd"(port) ); } -static inline void outportl(const uint16_t port, const uint32_t val) { +static inline void outportl(const u16 port, const u32 val) { asm volatile ( "outl %0, %1" : : "a"(val), "Nd"(port) ); } @@ -23,20 +19,20 @@ static inline void outportsm(unsigned short port, unsigned char* data, unsigned asm volatile ("rep outsw" : "+S" (data), "+c" (size) : "d" (port)); } -static inline uint8_t inportb(const uint16_t port) { - uint8_t ret; +static inline u8 inportb(const u16 port) { + u8 ret; asm volatile ( "inb %1, %0" : "=a"(ret) : "Nd"(port) ); return ret; } -static inline uint16_t inportw(const uint16_t port) { - uint16_t ret; +static inline u16 inportw(const u16 port) { + u16 ret; asm volatile ( "inw %1, %0" : "=a"(ret) : "Nd"(port) ); return ret; } -static inline uint32_t inportl(const uint16_t port) { - uint32_t ret; +static inline u32 inportl(const u16 port) { + u32 ret; asm volatile ( "inl %1, %0" : "=a"(ret) : "Nd"(port) ); return ret; } @@ -63,7 +59,3 @@ static inline void insl(unsigned reg, unsigned int *buffer, int quads) { buffer[index] = inportl(reg); } } - -#ifdef __cplusplus -} -#endif diff --git a/include/std/stdio.h b/include/std/stdio.h index 5ea24be..79d72fa 100644 --- a/include/std/stdio.h +++ b/include/std/stdio.h @@ -2,16 +2,8 @@ #include -#ifdef __cplusplus -extern "C" { -#endif - inline void putchar(char c) { terminal_putchar(c); } __attribute__ ((format (printf, 1, 2))) int printf (const char* format, ...); - -#ifdef __cplusplus -} -#endif diff --git a/include/std/string.h b/include/std/string.h index ec91667..740009e 100644 --- a/include/std/string.h +++ b/include/std/string.h @@ -1,19 +1,11 @@ #pragma once -#include +#include -#ifdef __cplusplus -extern "C" { -#endif - -int memcmp(const void* aptr, const void* bptr, size_t size); -void* memcpy(void* __restrict dstptr, const void* __restrict srcptr, size_t size); -void* memmove(void* dstptr, const void* srcptr, size_t size); -void* memset(void* bufptr, int value, size_t size); -size_t strlen(const char* str); +int memcmp(const void* aptr, const void* bptr, usize size); +void* memcpy(void* __restrict dstptr, const void* __restrict srcptr, usize size); +void* memmove(void* dstptr, const void* srcptr, usize size); +void* memset(void* bufptr, int value, usize size); +usize strlen(const char* str); char* strcpy(char* dst, const char* src); char* strcat(char* dst, const char* src); - -#ifdef __cplusplus -} -#endif diff --git a/include/std/util.h b/include/std/util.h index 2b0faa3..6bda8bc 100644 --- a/include/std/util.h +++ b/include/std/util.h @@ -1,21 +1,24 @@ #pragma once -#include +#include -#ifdef __cplusplus -extern "C" { -#endif +#define LOW_16(address) (u16)((address) & 0xFFFF) +#define HIGH_16(address) (u16)(((address) >> 16) & 0xFFFF) -#define LOW_16(address) (uint16_t)((address) & 0xFFFF) -#define HIGH_16(address) (uint16_t)(((address) >> 16) & 0xFFFF) - -void* malloc(size_t amount); +void* malloc(usize amount); int rand(void); -void srand(size_t seed); +void srand(usize seed); char* itoa(int res); unsigned int atoi(const char *in); -#ifdef __cplusplus +inline bool bitmap_get(bitmap_t *bitmap, usize index) { + if (index >= bitmap->size) return false; + return (bitmap->contents[index / 8] >> (index % 8)) & 1; +} + +inline u8 bitmap_set(bitmap_t *bitmap, usize index, bool value) { + if (index >= bitmap->size) return -1; + bitmap->contents[index / 8] &= !value << (index % 8); + return 0; } -#endif diff --git a/include/stivale2.h b/include/stivale2.h index ccddfa2..5d83036 100644 --- a/include/stivale2.h +++ b/include/stivale2.h @@ -1,30 +1,30 @@ #ifndef __STIVALE__STIVALE2_H__ #define __STIVALE__STIVALE2_H__ -#include +#include struct stivale2_tag { - uint64_t identifier; - uint64_t next; + u64 identifier; + u64 next; } __attribute__((__packed__)); /* --- Header --------------------------------------------------------------- */ /* Information passed from the kernel to the bootloader */ struct stivale2_header { - uint64_t entry_point; - uint64_t stack; - uint64_t flags; - uint64_t tags; + u64 entry_point; + u64 stack; + u64 flags; + u64 tags; } __attribute__((__packed__)); #define STIVALE2_HEADER_TAG_FRAMEBUFFER_ID 0x3ecc1bc43d0f7971 struct stivale2_header_tag_framebuffer { struct stivale2_tag tag; - uint16_t framebuffer_width; - uint16_t framebuffer_height; - uint16_t framebuffer_bpp; + u16 framebuffer_width; + u16 framebuffer_height; + u16 framebuffer_bpp; } __attribute__((__packed__)); #define STIVALE2_HEADER_TAG_FB_MTRR_ID 0x4c7bb07731282e00 @@ -33,14 +33,14 @@ struct stivale2_header_tag_framebuffer { struct stivale2_header_tag_terminal { struct stivale2_tag tag; - uint64_t flags; + u64 flags; } __attribute__((__packed__)); #define STIVALE2_HEADER_TAG_SMP_ID 0x1ab015085f3273df struct stivale2_header_tag_smp { struct stivale2_tag tag; - uint64_t flags; + u64 flags; } __attribute__((__packed__)); #define STIVALE2_HEADER_TAG_5LV_PAGING_ID 0x932f477032007e8f @@ -57,14 +57,14 @@ struct stivale2_struct { #define STIVALE2_BOOTLOADER_VERSION_SIZE 64 char bootloader_version[STIVALE2_BOOTLOADER_VERSION_SIZE]; - uint64_t tags; + u64 tags; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_CMDLINE_ID 0xe5e76a1b4597a781 struct stivale2_struct_tag_cmdline { struct stivale2_tag tag; - uint64_t cmdline; + u64 cmdline; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_MEMMAP_ID 0x2187f79e8612de07 @@ -79,15 +79,15 @@ struct stivale2_struct_tag_cmdline { #define STIVALE2_MMAP_FRAMEBUFFER 0x1002 struct stivale2_mmap_entry { - uint64_t base; - uint64_t length; - uint32_t type; - uint32_t unused; + u64 base; + u64 length; + u32 type; + u32 unused; } __attribute__((__packed__)); struct stivale2_struct_tag_memmap { struct stivale2_tag tag; - uint64_t entries; + u64 entries; struct stivale2_mmap_entry memmap[]; } __attribute__((__packed__)); @@ -97,26 +97,26 @@ struct stivale2_struct_tag_memmap { struct stivale2_struct_tag_framebuffer { struct stivale2_tag tag; - uint64_t framebuffer_addr; - uint16_t framebuffer_width; - uint16_t framebuffer_height; - uint16_t framebuffer_pitch; - uint16_t framebuffer_bpp; - uint8_t memory_model; - uint8_t red_mask_size; - uint8_t red_mask_shift; - uint8_t green_mask_size; - uint8_t green_mask_shift; - uint8_t blue_mask_size; - uint8_t blue_mask_shift; + u64 framebuffer_addr; + u16 framebuffer_width; + u16 framebuffer_height; + u16 framebuffer_pitch; + u16 framebuffer_bpp; + u8 memory_model; + u8 red_mask_size; + u8 red_mask_shift; + u8 green_mask_size; + u8 green_mask_shift; + u8 blue_mask_size; + u8 blue_mask_shift; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_EDID_ID 0x968609d7af96b845 struct stivale2_struct_tag_edid { struct stivale2_tag tag; - uint64_t edid_size; - uint8_t edid_information[]; + u64 edid_size; + u8 edid_information[]; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_FB_MTRR_ID 0x6bc1a78ebe871172 @@ -125,17 +125,17 @@ struct stivale2_struct_tag_edid { struct stivale2_struct_tag_terminal { struct stivale2_tag tag; - uint32_t flags; - uint16_t cols; - uint16_t rows; - uint64_t term_write; + u32 flags; + u16 cols; + u16 rows; + u64 term_write; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_MODULES_ID 0x4b6fe466aade04ce struct stivale2_module { - uint64_t begin; - uint64_t end; + u64 begin; + u64 end; #define STIVALE2_MODULE_STRING_SIZE 128 char string[STIVALE2_MODULE_STRING_SIZE]; @@ -143,7 +143,7 @@ struct stivale2_module { struct stivale2_struct_tag_modules { struct stivale2_tag tag; - uint64_t module_count; + u64 module_count; struct stivale2_module modules[]; } __attribute__((__packed__)); @@ -151,14 +151,14 @@ struct stivale2_struct_tag_modules { struct stivale2_struct_tag_rsdp { struct stivale2_tag tag; - uint64_t rsdp; + u64 rsdp; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_EPOCH_ID 0x566a7bed888e1407 struct stivale2_struct_tag_epoch { struct stivale2_tag tag; - uint64_t epoch; + u64 epoch; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_FIRMWARE_ID 0x359d837855e3858c @@ -167,55 +167,55 @@ struct stivale2_struct_tag_epoch { struct stivale2_struct_tag_firmware { struct stivale2_tag tag; - uint64_t flags; + u64 flags; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_EFI_SYSTEM_TABLE_ID 0x4bc5ec15845b558e struct stivale2_struct_tag_efi_system_table { struct stivale2_tag tag; - uint64_t system_table; + u64 system_table; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_KERNEL_FILE_ID 0xe599d90c2975584a struct stivale2_struct_tag_kernel_file { struct stivale2_tag tag; - uint64_t kernel_file; + u64 kernel_file; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_KERNEL_SLIDE_ID 0xee80847d01506c57 struct stivale2_struct_tag_kernel_slide { struct stivale2_tag tag; - uint64_t kernel_slide; + u64 kernel_slide; } __attribute__((packed)); #define STIVALE2_STRUCT_TAG_SMBIOS_ID 0x274bd246c62bf7d1 struct stivale2_struct_tag_smbios { struct stivale2_tag tag; - uint64_t flags; - uint64_t smbios_entry_32; - uint64_t smbios_entry_64; + u64 flags; + u64 smbios_entry_32; + u64 smbios_entry_64; } __attribute__((packed)); #define STIVALE2_STRUCT_TAG_SMP_ID 0x34d1d96339647025 struct stivale2_smp_info { - uint32_t processor_id; - uint32_t lapic_id; - uint64_t target_stack; - uint64_t goto_address; - uint64_t extra_argument; + u32 processor_id; + u32 lapic_id; + u64 target_stack; + u64 goto_address; + u64 extra_argument; } __attribute__((__packed__)); struct stivale2_struct_tag_smp { struct stivale2_tag tag; - uint64_t flags; - uint32_t bsp_lapic_id; - uint32_t unused; - uint64_t cpu_count; + u64 flags; + u32 bsp_lapic_id; + u32 unused; + u64 cpu_count; struct stivale2_smp_info smp_info[]; } __attribute__((__packed__)); @@ -223,29 +223,29 @@ struct stivale2_struct_tag_smp { struct stivale2_struct_tag_pxe_server_info { struct stivale2_tag tag; - uint32_t server_ip; + u32 server_ip; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_MMIO32_UART 0xb813f9b8dbc78797 struct stivale2_struct_tag_mmio32_uart { struct stivale2_tag tag; - uint64_t addr; + u64 addr; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_DTB 0xabb29bd49a2833fa struct stivale2_struct_tag_dtb { struct stivale2_tag tag; - uint64_t addr; - uint64_t size; + u64 addr; + u64 size; } __attribute__((__packed__)); #define STIVALE2_STRUCT_TAG_VMAP 0xb0ed257db18cb58f struct stivale2_struct_vmap { struct stivale2_tag tag; - uint64_t addr; + u64 addr; } __attribute__((__packed__)); #endif \ No newline at end of file diff --git a/include/types.h b/include/types.h new file mode 100644 index 0000000..d5eac73 --- /dev/null +++ b/include/types.h @@ -0,0 +1,21 @@ +#pragma once + +#include +#include +#include + +typedef uint8_t u8; +typedef uint16_t u16; +typedef uint32_t u32; +typedef uint64_t u64; +typedef size_t usize; + +typedef int8_t i8; +typedef int16_t i16; +typedef int32_t i32; +typedef int64_t i64; + +typedef struct { + u8 *contents; + usize size; +} bitmap_t; diff --git a/linker.ld b/linker.ld index 877fe56..52b1fc0 100644 --- a/linker.ld +++ b/linker.ld @@ -7,7 +7,9 @@ SECTIONS /* Since we are going to use PIE, this is just the base load address, but the */ /* bootloader will be able to relocate us as it sees fit. */ . = 0xffffffff80200000; - + + _kernel_start = .; + /* We place the .stivale2hdr section containing the header in its own section, */ /* and we use the KEEP directive on it to make sure it doesn't get discarded. */ .stivale2hdr : { @@ -31,4 +33,6 @@ SECTIONS *(COMMON) *(.bss*) } + + _kernel_end = .; } \ No newline at end of file