From 2d59766eb330b9d15a9bcbcd7e1695809fc099c5 Mon Sep 17 00:00:00 2001 From: EmulatedSeasons <89668582+EmulatedSeasons@users.noreply.github.com> Date: Fri, 3 May 2024 03:39:47 -0400 Subject: renamed i386 to x86 --- kernel/arch/i386/boot.asm | 103 ------------ kernel/arch/i386/crti.asm | 12 -- kernel/arch/i386/crtn.asm | 9 - kernel/arch/i386/gdt.asm | 35 ---- kernel/arch/i386/gdt2.cpp | 51 ------ kernel/arch/i386/idt.cpp | 133 --------------- kernel/arch/i386/isr.asm | 324 ------------------------------------ kernel/arch/i386/isr_handler.cpp | 21 --- kernel/arch/i386/linker.ld | 38 ----- kernel/arch/i386/multiboot.cpp | 30 ---- kernel/arch/i386/multiboot.h | 274 ------------------------------ kernel/arch/i386/pic.cpp | 97 ----------- kernel/arch/i386/ps2_controller.cpp | 191 --------------------- kernel/arch/i386/tmtty.cpp | 78 --------- kernel/arch/i386/vga.h | 35 ---- kernel/arch/x86/boot.asm | 103 ++++++++++++ kernel/arch/x86/crti.asm | 12 ++ kernel/arch/x86/crtn.asm | 9 + kernel/arch/x86/gdt.asm | 35 ++++ kernel/arch/x86/gdt2.cpp | 51 ++++++ kernel/arch/x86/idt.cpp | 133 +++++++++++++++ kernel/arch/x86/isr.asm | 324 ++++++++++++++++++++++++++++++++++++ kernel/arch/x86/isr_handler.cpp | 21 +++ kernel/arch/x86/linker.ld | 38 +++++ kernel/arch/x86/multiboot.cpp | 30 ++++ kernel/arch/x86/multiboot.h | 274 ++++++++++++++++++++++++++++++ kernel/arch/x86/pic.cpp | 97 +++++++++++ kernel/arch/x86/ps2_controller.cpp | 191 +++++++++++++++++++++ kernel/arch/x86/tmtty.cpp | 78 +++++++++ kernel/arch/x86/vga.h | 35 ++++ kernel/makefile | 7 - 31 files changed, 1431 insertions(+), 1438 deletions(-) delete mode 100644 kernel/arch/i386/boot.asm delete mode 100644 kernel/arch/i386/crti.asm delete mode 100644 kernel/arch/i386/crtn.asm delete mode 100644 kernel/arch/i386/gdt.asm delete mode 100644 kernel/arch/i386/gdt2.cpp delete mode 100644 kernel/arch/i386/idt.cpp delete mode 100644 kernel/arch/i386/isr.asm delete mode 100644 kernel/arch/i386/isr_handler.cpp delete mode 100644 kernel/arch/i386/linker.ld delete mode 100644 kernel/arch/i386/multiboot.cpp delete mode 100644 kernel/arch/i386/multiboot.h delete mode 100644 kernel/arch/i386/pic.cpp delete mode 100644 kernel/arch/i386/ps2_controller.cpp delete mode 100644 kernel/arch/i386/tmtty.cpp delete mode 100644 kernel/arch/i386/vga.h create mode 100644 kernel/arch/x86/boot.asm create mode 100644 kernel/arch/x86/crti.asm create mode 100644 kernel/arch/x86/crtn.asm create mode 100644 kernel/arch/x86/gdt.asm create mode 100644 kernel/arch/x86/gdt2.cpp create mode 100644 kernel/arch/x86/idt.cpp create mode 100644 kernel/arch/x86/isr.asm create mode 100644 kernel/arch/x86/isr_handler.cpp create mode 100644 kernel/arch/x86/linker.ld create mode 100644 kernel/arch/x86/multiboot.cpp create mode 100644 kernel/arch/x86/multiboot.h create mode 100644 kernel/arch/x86/pic.cpp create mode 100644 kernel/arch/x86/ps2_controller.cpp create mode 100644 kernel/arch/x86/tmtty.cpp create mode 100644 kernel/arch/x86/vga.h (limited to 'kernel') diff --git a/kernel/arch/i386/boot.asm b/kernel/arch/i386/boot.asm deleted file mode 100644 index 42c11e6..0000000 --- a/kernel/arch/i386/boot.asm +++ /dev/null @@ -1,103 +0,0 @@ -; multiboot header constants -MBALIGN equ 1 << 0 -MEMINFO equ 1 << 1 -MBFLAGS equ MBALIGN | MEMINFO -MAGIC equ 0x1BADB002 -CHECKSUM equ -(MAGIC+MBFLAGS) - -; multiboot header -section .multiboot -align 4 - dd MAGIC - dd MBFLAGS - dd CHECKSUM - -section .data -%include "arch/i386/gdt.asm" - -; defines the stack -section .bss -align 16 -stack_bottom: -resb 16384 ; 16 KiB -stack_top: - -; temporary paging tables -align 4 -boot_page_directory: - resb 4096 -boot_page_table: - resb 4096 - - -section .text -global _start:function (_start.end - _start) -_start: - cli - ; setup stack - mov esp, stack_top - - ; push the multiboot header data into the stack for later use - push eax - push ebx - - ; get multiboot header data (for memory map) - ;extern multiboot_main - ;call multiboot_main - - ;extern _init - ;Scall _init - - lgdt [gdt_descriptor] - jmp 0x08:.gdt_jmp - -.gdt_jmp: - mov ax, DATA_SEG - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax - mov ss, ax - jmp .gdt_jmp2 - -.gdt_jmp2: - ; setup paging (to map kernel to the higher half) - ;mov eax, 0 - ;mov cr3, eax - ;mov eax, cr0 - ;or eax, 0x80000001 - ;mov cr0, eax - - ; setup idt - extern idt_setup - call idt_setup - extern idtr - lidt [idtr] - - ; initialize pic - push ebp - mov ebp, esp - mov ebx, 0x28 - push ebx - mov ebx, 0x20 - push ebx - - extern pic_remap - call pic_remap - - pop ebx - pop ebx - mov esp, ebp - pop ebp - - sti - - ; enter the kernel - extern kernel_main - call kernel_main - - ; indefinite loop once system exits - ;cli -.hang: hlt - jmp .hang -.end: \ No newline at end of file diff --git a/kernel/arch/i386/crti.asm b/kernel/arch/i386/crti.asm deleted file mode 100644 index 51f27d9..0000000 --- a/kernel/arch/i386/crti.asm +++ /dev/null @@ -1,12 +0,0 @@ -; x86 crti.asm -section .init -global _init:function -_init: - push ebp - mov ebp, esp - -section .fini -global _fini:function -_fini: - push ebp - mov ebp, esp \ No newline at end of file diff --git a/kernel/arch/i386/crtn.asm b/kernel/arch/i386/crtn.asm deleted file mode 100644 index 370f4ae..0000000 --- a/kernel/arch/i386/crtn.asm +++ /dev/null @@ -1,9 +0,0 @@ -; x86 crtn.asm - -section .init - pop ebp - ret - -section .fini - pop ebp - ret \ No newline at end of file diff --git a/kernel/arch/i386/gdt.asm b/kernel/arch/i386/gdt.asm deleted file mode 100644 index e3af8bd..0000000 --- a/kernel/arch/i386/gdt.asm +++ /dev/null @@ -1,35 +0,0 @@ -; gdt.asm -; GDT is defined here - -gdt_start: - -gdt_null: ; Null segment - dd 0x0 - dd 0x0 - -gdt_kcode: ; Kernel code segment. Kernel has seperate segment from users for ring level - ; flag and access byte description on osdev wiki - dw 0xffff ; low limit - dw 0x0 ;low base - db 0x0 ; mid base - db 10011010b ; order (reversed): ac, rw, dc, ex, s, privl, pr - db 11001111b ; flags then limit. order (reversed): 0, 0, size bit, granularity bit - db 0x0 ; high limit - -gdt_kdata: ; same as gdt_kcode but for the data segment - dw 0xffff ;low limit - dw 0x0 ;low base - db 0x0 ;mid base - db 10010010b ; order: same as code seg. changed for data seg - db 11001111b ; same as kcode - db 0x0 ; high limit - -gdt_end: - -gdt_descriptor: ; describes the gdt to the lgdt register - dw gdt_end - gdt_start - 1 - - dd gdt_start - -CODE_SEG equ gdt_kcode - gdt_start -DATA_SEG equ gdt_kdata - gdt_start \ No newline at end of file diff --git a/kernel/arch/i386/gdt2.cpp b/kernel/arch/i386/gdt2.cpp deleted file mode 100644 index 0acdb0e..0000000 --- a/kernel/arch/i386/gdt2.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include -#include -/* -// structure to be encoded at encodeGdtEntry() -struct GDT -{ - uint32_t base; - uint32_t limit; - uint8_t access_byte; - uint8_t flags; -}; - -GDT strnulldesc {0, 0, 0, 0}; -GDT strkernelcode {0, 0xFFFFF, 0x9A, 0xC}; -GDT strkerneldata {0, 0xFFFFF, 0x92, 0xC}; -GDT strusercode {0, 0xFFFFF, 0xFA, 0xC}; -GDT struserdata {0, 0xFFFFF, 0xF2, 0xC}; - -uint8_t* nulldesc; -uint8_t* kernelcode; -uint8_t* kerneldata; -uint8_t* usercode; -uint8_t* userdata; - - -void encodeGdtEntry(uint8_t *target, struct GDT source) -{ - // Check the limit to make sure that it can be encoded - if (source.limit > 0xFFFFF) {printf("GDT cannot encode limits larger than 0xFFFFF\n");} - - // Encode the limit - target[0] = source.limit & 0xFF; - target[1] = (source.limit >> 8) & 0xFF; - target[6] = (source.limit >> 16) & 0x0F; - - // Encode the base - target[2] = source.base & 0xFF; - target[3] = (source.base >> 8) & 0xFF; - target[4] = (source.base >> 16) & 0xFF; - target[7] = (source.base >> 24) & 0xFF; - - // Encode the access byte - target[5] = source.access_byte; - - // Encode the flags - target[6] |= (source.flags << 4); -} - -extern "C" void setupGdt() { - -} */ \ No newline at end of file diff --git a/kernel/arch/i386/idt.cpp b/kernel/arch/i386/idt.cpp deleted file mode 100644 index a8f3ff4..0000000 --- a/kernel/arch/i386/idt.cpp +++ /dev/null @@ -1,133 +0,0 @@ -#include -#include - -/* Function prototypes for the ISR functions. IDT[0] to IDT[31] are reserved for hardware exceptions */ -extern "C" void isr0(); -extern "C" void isr1(); -extern "C" void isr2(); -extern "C" void isr3(); -extern "C" void isr4(); -extern "C" void isr5(); -extern "C" void isr6(); -extern "C" void isr7(); -extern "C" void isr8(); -extern "C" void isr9(); -extern "C" void isr10(); -extern "C" void isr11(); -extern "C" void isr12(); -extern "C" void isr13(); -extern "C" void isr14(); -extern "C" void isr15(); -extern "C" void isr16(); -extern "C" void isr17(); -extern "C" void isr18(); -extern "C" void isr19(); -extern "C" void isr20(); -extern "C" void isr21(); -extern "C" void isr22(); -extern "C" void isr23(); -extern "C" void isr24(); -extern "C" void isr25(); -extern "C" void isr26(); -extern "C" void isr27(); -extern "C" void isr28(); -extern "C" void isr29(); -extern "C" void isr30(); -extern "C" void isr31(); -extern "C" void isr32(); -extern "C" void isr33(); -extern "C" void isr34(); -extern "C" void isr35(); -extern "C" void isr36(); -extern "C" void isr37(); -extern "C" void isr38(); -extern "C" void isr39(); -extern "C" void isr40(); -extern "C" void isr41(); -extern "C" void isr42(); -extern "C" void isr43(); -extern "C" void isr44(); -extern "C" void isr45(); -extern "C" void isr46(); -extern "C" void isr47(); - -struct idt_entry -{ - uint16_t offset_low; - uint16_t selector; - uint8_t always0; - uint8_t type_attributes; - uint16_t offset_high; -}__attribute__((packed)); - -struct str_idtr { - uint16_t limit; - uint32_t base; -}__attribute__((packed)); - -idt_entry idt[256]; -str_idtr idtr; - -void idt_new_entry(int num, uint32_t offset, uint16_t sel, uint8_t type_attribs) { - idt[num].offset_low = (offset & 0xFFFF); - idt[num].selector = sel; - idt[num].always0 = 0; - idt[num].type_attributes = type_attribs; - idt[num].offset_high = (offset >> 16) & 0xFFFF; -} - -extern "C" void idt_setup() { - idtr.limit = (sizeof(struct idt_entry) * 256) - 1; - idtr.base = (uint32_t)idt; - - // todo: is there really no other way? - idt_new_entry(0, (unsigned)isr0, 0x08, 0x8E); - idt_new_entry(1, (unsigned)isr1, 0x08, 0x8E); - idt_new_entry(2, (unsigned)isr2, 0x08, 0x8E); - idt_new_entry(3, (unsigned)isr3, 0x08, 0x8E); - idt_new_entry(4, (unsigned)isr4, 0x08, 0x8E); - idt_new_entry(5, (unsigned)isr5, 0x08, 0x8E); - idt_new_entry(6, (unsigned)isr6, 0x08, 0x8E); - idt_new_entry(7, (unsigned)isr7, 0x08, 0x8E); - idt_new_entry(8, (unsigned)isr8, 0x08, 0x8E); - idt_new_entry(9, (unsigned)isr9, 0x08, 0x8E); - idt_new_entry(10, (unsigned)isr10, 0x08, 0x8E); - idt_new_entry(11, (unsigned)isr11, 0x08, 0x8E); - idt_new_entry(12, (unsigned)isr12, 0x08, 0x8E); - idt_new_entry(13, (unsigned)isr13, 0x08, 0x8E); - idt_new_entry(14, (unsigned)isr14, 0x08, 0x8E); - idt_new_entry(15, (unsigned)isr15, 0x08, 0x8E); - idt_new_entry(16, (unsigned)isr16, 0x08, 0x8E); - idt_new_entry(17, (unsigned)isr17, 0x08, 0x8E); - idt_new_entry(18, (unsigned)isr18, 0x08, 0x8E); - idt_new_entry(19, (unsigned)isr19, 0x08, 0x8E); - idt_new_entry(20, (unsigned)isr20, 0x08, 0x8E); - idt_new_entry(21, (unsigned)isr21, 0x08, 0x8E); - idt_new_entry(22, (unsigned)isr22, 0x08, 0x8E); - idt_new_entry(23, (unsigned)isr23, 0x08, 0x8E); - idt_new_entry(24, (unsigned)isr24, 0x08, 0x8E); - idt_new_entry(25, (unsigned)isr25, 0x08, 0x8E); - idt_new_entry(26, (unsigned)isr26, 0x08, 0x8E); - idt_new_entry(27, (unsigned)isr27, 0x08, 0x8E); - idt_new_entry(28, (unsigned)isr28, 0x08, 0x8E); - idt_new_entry(29, (unsigned)isr29, 0x08, 0x8E); - idt_new_entry(30, (unsigned)isr30, 0x08, 0x8E); - idt_new_entry(31, (unsigned)isr31, 0x08, 0x8E); - //PIC entries - idt_new_entry(32, (unsigned)isr32, 0x08, 0x8E); - idt_new_entry(33, (unsigned)isr33, 0x08, 0x8E); - idt_new_entry(34, (unsigned)isr34, 0x08, 0x8E); - idt_new_entry(35, (unsigned)isr35, 0x08, 0x8E); - idt_new_entry(36, (unsigned)isr36, 0x08, 0x8E); - idt_new_entry(37, (unsigned)isr37, 0x08, 0x8E); - idt_new_entry(38, (unsigned)isr38, 0x08, 0x8E); - idt_new_entry(39, (unsigned)isr39, 0x08, 0x8E); - idt_new_entry(40, (unsigned)isr40, 0x08, 0x8E); - idt_new_entry(41, (unsigned)isr41, 0x08, 0x8E); - idt_new_entry(42, (unsigned)isr42, 0x08, 0x8E); - idt_new_entry(43, (unsigned)isr43, 0x08, 0x8E); - idt_new_entry(44, (unsigned)isr44, 0x08, 0x8E); - idt_new_entry(45, (unsigned)isr45, 0x08, 0x8E); - idt_new_entry(46, (unsigned)isr46, 0x08, 0x8E); - idt_new_entry(47, (unsigned)isr47, 0x08, 0x8E); -} \ No newline at end of file diff --git a/kernel/arch/i386/isr.asm b/kernel/arch/i386/isr.asm deleted file mode 100644 index 4ccbaf9..0000000 --- a/kernel/arch/i386/isr.asm +++ /dev/null @@ -1,324 +0,0 @@ -; isr.asm -; ISR functions are defined here. Most code is done in isr_handlers.cpp - -global isr0 -global isr1 -global isr2 -global isr3 -global isr4 -global isr5 -global isr6 -global isr7 -global isr8 -global isr9 -global isr10 -global isr11 -global isr12 -global isr13 -global isr14 -global isr15 -global isr16 -global isr17 -global isr18 -global isr19 -global isr20 -global isr21 -global isr22 -global isr23 -global isr24 -global isr25 -global isr26 -global isr27 -global isr28 -global isr29 -global isr30 -global isr31 -global isr32 -global isr33 -global isr34 -global isr35 -global isr36 -global isr37 -global isr38 -global isr39 -global isr40 -global isr41 -global isr42 -global isr43 -global isr44 -global isr45 -global isr46 -global isr47 - -section .text -align 4 - -isr0: - pushad - mov ebx, 0 - call exception_stub - hlt - popad - iret - -isr1: - pushad - popad - iret - -isr2: - pushad - popad - iret - -isr3: - pushad - popad - iret - -isr4: - pushad - popad - iret - -isr5: - pushad - popad - iret - -isr6: - pushad - mov ebx, 6 - call exception_stub - popad - iret - -isr7: - pushad - popad - iret - -isr8: - pushad - mov ebx, 8 - call exception_stub - popad - iret - -isr9: - pushad - popad - iret - -isr10: - pushad - popad - iret - -isr11: - pushad - mov ebx, 11 - call exception_stub - popad - iret - -isr12: - pushad - popad - iret - -isr13: - pushad - mov ebx, 13 - call exception_stub - popad - iret - -isr14: - pushad - mov ebx, 14 - call exception_stub - popad - iret - -isr15: - pushad - popad - iret - -isr16: - pushad - popad - iret - -isr17: - pushad - popad - iret - -isr18: - pushad - popad - iret - -isr19: - pushad - popad - iret - -isr20: - pushad - popad - iret - -isr21: - pushad - popad - iret - -isr22: - pushad - popad - iret - -isr23: - pushad - popad - iret - -isr24: - pushad - popad - iret - -isr25: - pushad - popad - iret - -isr26: - pushad - popad - iret - -isr27: - pushad - popad - iret -isr28: - pushad - popad - iret - -isr29: - pushad - popad - iret - -isr30: - pushad - popad - iret - -isr31: - pushad - popad - iret - -isr32: - pushad - ;extern pit_handler - ;call pit_handler - popad - iret - -isr33: - pushad - extern ps2_handler - call ps2_handler - popad - iret - -isr34: - pushad - popad - iret - -isr35: - pushad - popad - iret - -isr36: - pushad - popad - iret -isr37: - pushad - popad - iret - -isr38: - pushad - popad - iret - -isr39: - pushad - popad - iret - -isr40: - pushad - xchg bx, bx - popad - iret - -isr41: - pushad - popad - iret - -isr42: - pushad - popad - iret - -isr43: - pushad - popad - iret - -isr44: - pushad - popad - iret - -isr45: - pushad - popad - iret - -isr46: - pushad - popad - iret - -isr47: - pushad - popad - iret - -exception_stub: - push ebp - mov ebp, esp - - push ebx - ;cld - extern exception_handler - call exception_handler - pop ebx - - mov esp, ebp - pop ebp - ret \ No newline at end of file diff --git a/kernel/arch/i386/isr_handler.cpp b/kernel/arch/i386/isr_handler.cpp deleted file mode 100644 index ac8fb49..0000000 --- a/kernel/arch/i386/isr_handler.cpp +++ /dev/null @@ -1,21 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include - -extern "C" void exception_handler(int e) { - //unsigned char errorcode[2]{((unsigned char) e) + 48}; - //terminal_initialize(); - printf("Exception %x\n", e); -} - -#define PS2_DATA 0x60 -extern "C" void ps2_handler() { - keyboard_write(inb(PS2_DATA)); - - pic_send_eoi(1); -} \ No newline at end of file diff --git a/kernel/arch/i386/linker.ld b/kernel/arch/i386/linker.ld deleted file mode 100644 index c4bfa3b..0000000 --- a/kernel/arch/i386/linker.ld +++ /dev/null @@ -1,38 +0,0 @@ -/* Excecution start point symbol */ -ENTRY(_start) - -SECTIONS -{ - . = 1M; - - /* Used to get the beginning and end address of the kernel */ - _kernel_begin = .; - - /* code. multiboot header comes first */ - .text BLOCK(4K) : ALIGN(4K) - { - *(.multiboot) - *(.text) - } - - /* read only data */ - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } - - /* read write data (initialized) */ - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } - - /* read write data (uninitialized) and stack */ - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) - } - - _kernel_end = .; -} \ No newline at end of file diff --git a/kernel/arch/i386/multiboot.cpp b/kernel/arch/i386/multiboot.cpp deleted file mode 100644 index 9f3eedb..0000000 --- a/kernel/arch/i386/multiboot.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include -#include -#include -#include "multiboot.h" -#include - -// gets the memory map and stuff -extern "C" void multiboot_main(multiboot_info_t* mbd, uint32_t magic) { - terminal_initialize(); - //printf("multiboot struc addr: %x\n", mbd); - if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { - printf("Invalid multiboot magic number\n"); - abort(); - } - - // checks bit 6 to see if there's a valid memory map - if (!(mbd->flags >> 6 & 0x1)) { - printf("Invalid GRUB memory map\n"); - abort(); - } - - // loop through memory map and display the values - for (int i = 0; i < mbd->mmap_length; i += sizeof(multiboot_memory_map_t)) { - multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(mbd->mmap_addr + i); - - printf("Start Addr: 0x%lx | Length: 0x%lx | Size: 0x%x | Type: %d\n", - mmmt->addr, mmmt->len, mmmt->size, mmmt->type); - //printf("%lx,%x,%x,%d\n", mmmt->size, mmmt->size, mmmt->size, mmmt->size); - } -} \ No newline at end of file diff --git a/kernel/arch/i386/multiboot.h b/kernel/arch/i386/multiboot.h deleted file mode 100644 index 0951ebe..0000000 --- a/kernel/arch/i386/multiboot.h +++ /dev/null @@ -1,274 +0,0 @@ -/* 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_uint64_t addr; - multiboot_uint64_t len; -#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/arch/i386/pic.cpp b/kernel/arch/i386/pic.cpp deleted file mode 100644 index 78cbcf8..0000000 --- a/kernel/arch/i386/pic.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include -#include -#include -#include - -#define PIC1 0x20 -#define PIC2 0xA0 -#define PIC1_CMD PIC1 -#define PIC1_DATA (PIC1 + 1) -#define PIC2_CMD PIC2 -#define PIC2_DATA (PIC2 + 1) -#define PIC_READ_IRR 0x0a // OCW3 irq ready next CMD read -#define PIC_READ_ISR 0x0b // OCW3 irq service next CMD read - -#define PIC_EOI 0x20 - -// pic reinitialization constants -#define ICW1_ICW4 0x01 // indicates icw4 will be present -#define ICW1_SINGLE 0x02 // single cascade mode -#define ICW1_INTERVAL4 0x04 // call address interval 4 -#define ICW1_LEVEL 0x08 // level triggered (edge) mode -#define ICW1_INIT 0x10 // initialization - -#define ICW4_8086 0x01 // 8086 mode -#define ICW4_AUTO 0x02 // auto (normal) eoi -#define ICW4_BUF_SLAVE 0x08 // buffered mode/slave -#define ICW4_BUF_MASTER 0x0C // buffered mode/master -#define ICW4_SFNM 0x10 // special fully nested (not) - -void pic_send_eoi(unsigned char irq) { - if (irq >= 8) { - outb(PIC2_CMD, PIC_EOI); - } - outb(PIC1_CMD, PIC_EOI); -} - -// offset 1 is for master, offset 2 is for slave -void pic_remap(int offset1, int offset2) { - unsigned char a1, a2; - - a1 = inb(PIC1_DATA); // save masks - a2 = inb(PIC2_DATA); - - outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4); // starts initialization in cascade mode - io_wait(); - outb(PIC2_CMD, ICW1_INIT | ICW1_ICW4); - io_wait(); - outb(PIC1_DATA, offset1); // icw2: master and slave vector offset set - io_wait(); - outb(PIC2_DATA, offset2); - io_wait(); - outb(PIC1_DATA, 4); // tells master pic theres a slave pic at irq2 - io_wait(); - outb(PIC2_DATA, 2); // tells slave pic its cascade identity - io_wait(); - - outb(PIC1_DATA, ICW4_8086); - io_wait(); - outb(PIC2_DATA, ICW4_8086); - io_wait(); - - outb(PIC1_DATA, a1); // restore masks - outb(PIC2_DATA, a2); - - for (char i = 0; i < 15; i++) - { - irq_set_mask(i); - } -} - -void irq_set_mask(unsigned char irq) { - uint16_t port; - uint8_t value; - - if (irq < 8) { - port = PIC1_DATA; - } else { - port = PIC2_DATA; - irq -= 8; - } - value = inb(port) | (1 << irq); - outb(port, value); -} - -void irq_clear_mask(unsigned char irq) { - uint16_t port; - uint8_t value; - - if (irq < 8) { - port = PIC1_DATA; - } else { - port = PIC2_DATA; - irq -= 8; - } - value = inb(port) & ~(1 << irq); - outb(port, value); -} \ No newline at end of file diff --git a/kernel/arch/i386/ps2_controller.cpp b/kernel/arch/i386/ps2_controller.cpp deleted file mode 100644 index 9424233..0000000 --- a/kernel/arch/i386/ps2_controller.cpp +++ /dev/null @@ -1,191 +0,0 @@ -#include -#include -#include -#include - -#define PS2_DATA 0x60 // data port -#define PS2_STATUS 0x64 // status register -#define PS2_COMMAND 0x64 // command register - -// set to true if 2nd ps2 port is available -bool ps2SecondaryEnabled = false; - -void initialize_ps2_controller() { - inputbuffer_wait(); - outb(PS2_COMMAND, 0xAD); // disable devices - inputbuffer_wait(); - outb(PS2_COMMAND, 0xA7); - - outputbuffer_wait(); - inb(PS2_DATA); // flush output buffer - inb(PS2_DATA); - inb(PS2_DATA); - inb(PS2_DATA); - inb(PS2_DATA); - inb(PS2_DATA); - inb(PS2_DATA); - inb(PS2_DATA); - inb(PS2_DATA); - inb(PS2_DATA); - - - inputbuffer_wait(); - outb(PS2_COMMAND, 0x20); // set controller configuration byte - outputbuffer_wait(); - uint8_t conconfig = inb(PS2_DATA); - conconfig &= 0b00110100; - inputbuffer_wait(); - outb(PS2_COMMAND, 0x60); - inputbuffer_wait(); - outb(PS2_DATA, conconfig); - - inputbuffer_wait(); - outb(PS2_COMMAND, 0xAA); // performs controller self test - outputbuffer_wait(); - if (inb(PS2_DATA) == 0xFC) { - printf("PS/2 controller failed self test\n"); - } - inputbuffer_wait(); - outb(PS2_COMMAND, 0x60); // in case the controller resets from the test - inputbuffer_wait(); - outb(PS2_DATA, conconfig); - - int portcount = 1; - inputbuffer_wait(); - outb(PS2_COMMAND, 0xA8); // check if ps2 controller is dual channel - inputbuffer_wait(); - outb(PS2_COMMAND, 0x20); - outputbuffer_wait(); - conconfig = inb(PS2_DATA); - if ((conconfig & 0b00100000) == 0b00000000) { // checks if bit 5 is cleared - ps2SecondaryEnabled = true; - //printf("Dual channel PS/2\n"); - portcount = 2; - } else { - //printf("Single channel PS/2\n"); - } - - inputbuffer_wait(); - outb(PS2_COMMAND, 0xAB); // tests ps2 ports - outputbuffer_wait(); - if (inb(PS2_DATA) != 0x00) { - printf("PS/2 port 1 failed self test\n"); - --portcount; - } - if (ps2SecondaryEnabled) { - inputbuffer_wait(); - outb(PS2_COMMAND, 0xA9); - outputbuffer_wait(); - if (inb(PS2_DATA) != 0x00) { - printf("PS/2 port 2 failed self test\n"); - --portcount; - } - } - if (!portcount) { - printf("PS/2 initialization failed\n"); - return; - } - - conconfig |= 0b00000011; - inputbuffer_wait(); - outb(PS2_COMMAND, 0xAE); // enable ps2 ports - conconfig |= 0b00000001; - if (ps2SecondaryEnabled) { - inputbuffer_wait(); - outb(PS2_COMMAND, 0xA8); - outb(PS2_COMMAND, 0x60); - conconfig |= 0b00000011; - outb(PS2_DATA, conconfig); - } else { - inputbuffer_wait(); - outb(PS2_COMMAND, 0x60); - conconfig |= 0b00000001; - outb(PS2_DATA, conconfig); - } - - //ps2_dev_send_command(0, 0xFF); // reset devices - //inb(PS2_DATA); - //io_wait(); - if (ps2SecondaryEnabled) { - //ps2_dev_send_command(1, 0xFF); - //inb(PS2_DATA); - //io_wait(); - } - - //printf("PS/2 controller initialized\n"); -} - -// waits for input buffer (write) to be filled -void inputbuffer_wait() { - for (int i = 0; i < 15; i++) { - uint8_t status_reg = inb(PS2_STATUS); - if ((status_reg & 0b00000010)) { - return; - } - io_wait(); - } -} - -// waits for outbut buffer (read) to be filled -void outputbuffer_wait() { - for (int i = 0; i < 15; i++) { - uint8_t status_reg = inb(PS2_STATUS); - if ((status_reg & 0b00000001)) { - return; - } - io_wait(); - } -} - -// checks if inpbut buffer is set -bool inputbuffer_check() { - uint8_t status_reg = inb(PS2_STATUS); - if ((status_reg & 0b00000010)) { - return true; - } else { - return false; - } -} - -bool outputbuffer_check() { - uint8_t status_reg = inb(PS2_STATUS); - if ((status_reg & 0b00000001)) { - return true; - } else { - return false; - } -} - -/* Sends a command byte to a ps2 device -Port numbers start from 0 */ -int ps2_dev_send_command(int port, unsigned char command) { - //bool commandRecieved = false; - switch (port) - { - case 0: - for (int i = 0; i < 5; i++) { - uint8_t status_reg = inb(PS2_STATUS); - if ((status_reg & 0b00000010) == 0b00000000) { - outb(PS2_DATA, command); - return 0; - } - inb(PS2_DATA); - io_wait(); - } - return 1; // error returned if timeout expires - case 1: - outb(PS2_COMMAND, 0xD4); - for (int i = 0; i < 5; i++) { - uint8_t status_reg = inb(PS2_STATUS); - if ((status_reg & 0b00000010) == 0b00000000) { - outb(PS2_DATA, command); - return 0; - } - inb(PS2_DATA); - io_wait(); - } - return 1; - default: - return 2; // out of port range - } -} \ No newline at end of file diff --git a/kernel/arch/i386/tmtty.cpp b/kernel/arch/i386/tmtty.cpp deleted file mode 100644 index d4dc772..0000000 --- a/kernel/arch/i386/tmtty.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include -#include -#include -#include -#include - -#include "vga.h" - -/* Text mode tty */ - -static const size_t VGA_WIDTH = 80; -static const size_t VGA_HEIGHT = 25; -static uint16_t* const VGA_MEMORY = (uint16_t*) 0xB8000; - -size_t terminal_row; -size_t terminal_column; -uint8_t terminal_color; -uint16_t* terminal_buffer; - -void terminal_clear(void) { - terminal_row = 0; - terminal_column = 0; - for (size_t y = 0; y < VGA_HEIGHT; y++) { - for (size_t x = 0; x < VGA_WIDTH; x++) { - const size_t i = y * VGA_WIDTH + x; - terminal_buffer[i] = vga_entry(' ', terminal_color); - } - } -} - -void terminal_initialize(void) { - terminal_color = vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK); - terminal_buffer = VGA_MEMORY; - terminal_clear(); -} - -void terminal_setcolor(uint8_t color) { - terminal_color = color; -} - -void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) { - const size_t i = y * VGA_WIDTH + x; - terminal_buffer[i] = vga_entry(c, color); -} - -void terminal_scroll() { - memmove(VGA_MEMORY, (VGA_MEMORY + VGA_WIDTH), (VGA_HEIGHT * VGA_WIDTH) - VGA_WIDTH); - memset(VGA_MEMORY + (VGA_WIDTH * VGA_HEIGHT) - VGA_WIDTH, 0x0, VGA_WIDTH * 2); - --terminal_row; -} - -void terminal_putchar(char c) { - unsigned char uc = c; - if (uc == '\n') { - terminal_column = 0; - if (terminal_row++ == VGA_HEIGHT) - terminal_scroll(); - return; - } - terminal_putentryat(uc, terminal_color, terminal_column, terminal_row); - - if (++terminal_column == VGA_WIDTH) { - terminal_column = 0; - if (++terminal_row == VGA_HEIGHT) { - terminal_scroll(); - } - } -} - -void terminal_write(const char* data, size_t size) { - for (size_t i = 0; i < size; i++) { - terminal_putchar(data[i]); - } -} - -void terminal_writestring(const char* data) { - terminal_write(data, strlen(data)); -} \ No newline at end of file diff --git a/kernel/arch/i386/vga.h b/kernel/arch/i386/vga.h deleted file mode 100644 index 5b6b351..0000000 --- a/kernel/arch/i386/vga.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef ARCH_I386_VGA_H -#define ARCH_I386_VGA_H - -#include - -// hardware text mode constants -enum vga_color { - VGA_COLOR_BLACK = 0, - VGA_COLOR_BLUE = 1, - VGA_COLOR_GREEN = 2, - VGA_COLOR_CYAN = 3, - VGA_COLOR_RED = 4, - VGA_COLOR_MAGENTA = 5, - VGA_COLOR_BROWN = 6, - VGA_COLOR_LIGHT_GREY = 7, - VGA_COLOR_DARK_GREY = 8, - VGA_COLOR_LIGHT_BLUE = 9, - VGA_COLOR_LIGHT_GREEN = 10, - VGA_COLOR_LIGHT_CYAN = 11, - VGA_COLOR_LIGHT_RED = 12, - VGA_COLOR_LIGHT_MAGENTA = 13, - VGA_COLOR_LIGHT_BROWN = 14, - VGA_COLOR_WHITE = 15, -}; - -static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) { - return fg | bg << 4; -} - -// returns the character/color of a terminal entry -static inline uint16_t vga_entry(unsigned char uc, uint8_t color) { - return (uint16_t) uc | (uint16_t) color << 8; -} - -#endif \ No newline at end of file diff --git a/kernel/arch/x86/boot.asm b/kernel/arch/x86/boot.asm new file mode 100644 index 0000000..42c11e6 --- /dev/null +++ b/kernel/arch/x86/boot.asm @@ -0,0 +1,103 @@ +; multiboot header constants +MBALIGN equ 1 << 0 +MEMINFO equ 1 << 1 +MBFLAGS equ MBALIGN | MEMINFO +MAGIC equ 0x1BADB002 +CHECKSUM equ -(MAGIC+MBFLAGS) + +; multiboot header +section .multiboot +align 4 + dd MAGIC + dd MBFLAGS + dd CHECKSUM + +section .data +%include "arch/i386/gdt.asm" + +; defines the stack +section .bss +align 16 +stack_bottom: +resb 16384 ; 16 KiB +stack_top: + +; temporary paging tables +align 4 +boot_page_directory: + resb 4096 +boot_page_table: + resb 4096 + + +section .text +global _start:function (_start.end - _start) +_start: + cli + ; setup stack + mov esp, stack_top + + ; push the multiboot header data into the stack for later use + push eax + push ebx + + ; get multiboot header data (for memory map) + ;extern multiboot_main + ;call multiboot_main + + ;extern _init + ;Scall _init + + lgdt [gdt_descriptor] + jmp 0x08:.gdt_jmp + +.gdt_jmp: + mov ax, DATA_SEG + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + mov ss, ax + jmp .gdt_jmp2 + +.gdt_jmp2: + ; setup paging (to map kernel to the higher half) + ;mov eax, 0 + ;mov cr3, eax + ;mov eax, cr0 + ;or eax, 0x80000001 + ;mov cr0, eax + + ; setup idt + extern idt_setup + call idt_setup + extern idtr + lidt [idtr] + + ; initialize pic + push ebp + mov ebp, esp + mov ebx, 0x28 + push ebx + mov ebx, 0x20 + push ebx + + extern pic_remap + call pic_remap + + pop ebx + pop ebx + mov esp, ebp + pop ebp + + sti + + ; enter the kernel + extern kernel_main + call kernel_main + + ; indefinite loop once system exits + ;cli +.hang: hlt + jmp .hang +.end: \ No newline at end of file diff --git a/kernel/arch/x86/crti.asm b/kernel/arch/x86/crti.asm new file mode 100644 index 0000000..51f27d9 --- /dev/null +++ b/kernel/arch/x86/crti.asm @@ -0,0 +1,12 @@ +; x86 crti.asm +section .init +global _init:function +_init: + push ebp + mov ebp, esp + +section .fini +global _fini:function +_fini: + push ebp + mov ebp, esp \ No newline at end of file diff --git a/kernel/arch/x86/crtn.asm b/kernel/arch/x86/crtn.asm new file mode 100644 index 0000000..370f4ae --- /dev/null +++ b/kernel/arch/x86/crtn.asm @@ -0,0 +1,9 @@ +; x86 crtn.asm + +section .init + pop ebp + ret + +section .fini + pop ebp + ret \ No newline at end of file diff --git a/kernel/arch/x86/gdt.asm b/kernel/arch/x86/gdt.asm new file mode 100644 index 0000000..e3af8bd --- /dev/null +++ b/kernel/arch/x86/gdt.asm @@ -0,0 +1,35 @@ +; gdt.asm +; GDT is defined here + +gdt_start: + +gdt_null: ; Null segment + dd 0x0 + dd 0x0 + +gdt_kcode: ; Kernel code segment. Kernel has seperate segment from users for ring level + ; flag and access byte description on osdev wiki + dw 0xffff ; low limit + dw 0x0 ;low base + db 0x0 ; mid base + db 10011010b ; order (reversed): ac, rw, dc, ex, s, privl, pr + db 11001111b ; flags then limit. order (reversed): 0, 0, size bit, granularity bit + db 0x0 ; high limit + +gdt_kdata: ; same as gdt_kcode but for the data segment + dw 0xffff ;low limit + dw 0x0 ;low base + db 0x0 ;mid base + db 10010010b ; order: same as code seg. changed for data seg + db 11001111b ; same as kcode + db 0x0 ; high limit + +gdt_end: + +gdt_descriptor: ; describes the gdt to the lgdt register + dw gdt_end - gdt_start - 1 + + dd gdt_start + +CODE_SEG equ gdt_kcode - gdt_start +DATA_SEG equ gdt_kdata - gdt_start \ No newline at end of file diff --git a/kernel/arch/x86/gdt2.cpp b/kernel/arch/x86/gdt2.cpp new file mode 100644 index 0000000..0acdb0e --- /dev/null +++ b/kernel/arch/x86/gdt2.cpp @@ -0,0 +1,51 @@ +#include +#include +/* +// structure to be encoded at encodeGdtEntry() +struct GDT +{ + uint32_t base; + uint32_t limit; + uint8_t access_byte; + uint8_t flags; +}; + +GDT strnulldesc {0, 0, 0, 0}; +GDT strkernelcode {0, 0xFFFFF, 0x9A, 0xC}; +GDT strkerneldata {0, 0xFFFFF, 0x92, 0xC}; +GDT strusercode {0, 0xFFFFF, 0xFA, 0xC}; +GDT struserdata {0, 0xFFFFF, 0xF2, 0xC}; + +uint8_t* nulldesc; +uint8_t* kernelcode; +uint8_t* kerneldata; +uint8_t* usercode; +uint8_t* userdata; + + +void encodeGdtEntry(uint8_t *target, struct GDT source) +{ + // Check the limit to make sure that it can be encoded + if (source.limit > 0xFFFFF) {printf("GDT cannot encode limits larger than 0xFFFFF\n");} + + // Encode the limit + target[0] = source.limit & 0xFF; + target[1] = (source.limit >> 8) & 0xFF; + target[6] = (source.limit >> 16) & 0x0F; + + // Encode the base + target[2] = source.base & 0xFF; + target[3] = (source.base >> 8) & 0xFF; + target[4] = (source.base >> 16) & 0xFF; + target[7] = (source.base >> 24) & 0xFF; + + // Encode the access byte + target[5] = source.access_byte; + + // Encode the flags + target[6] |= (source.flags << 4); +} + +extern "C" void setupGdt() { + +} */ \ No newline at end of file diff --git a/kernel/arch/x86/idt.cpp b/kernel/arch/x86/idt.cpp new file mode 100644 index 0000000..a8f3ff4 --- /dev/null +++ b/kernel/arch/x86/idt.cpp @@ -0,0 +1,133 @@ +#include +#include + +/* Function prototypes for the ISR functions. IDT[0] to IDT[31] are reserved for hardware exceptions */ +extern "C" void isr0(); +extern "C" void isr1(); +extern "C" void isr2(); +extern "C" void isr3(); +extern "C" void isr4(); +extern "C" void isr5(); +extern "C" void isr6(); +extern "C" void isr7(); +extern "C" void isr8(); +extern "C" void isr9(); +extern "C" void isr10(); +extern "C" void isr11(); +extern "C" void isr12(); +extern "C" void isr13(); +extern "C" void isr14(); +extern "C" void isr15(); +extern "C" void isr16(); +extern "C" void isr17(); +extern "C" void isr18(); +extern "C" void isr19(); +extern "C" void isr20(); +extern "C" void isr21(); +extern "C" void isr22(); +extern "C" void isr23(); +extern "C" void isr24(); +extern "C" void isr25(); +extern "C" void isr26(); +extern "C" void isr27(); +extern "C" void isr28(); +extern "C" void isr29(); +extern "C" void isr30(); +extern "C" void isr31(); +extern "C" void isr32(); +extern "C" void isr33(); +extern "C" void isr34(); +extern "C" void isr35(); +extern "C" void isr36(); +extern "C" void isr37(); +extern "C" void isr38(); +extern "C" void isr39(); +extern "C" void isr40(); +extern "C" void isr41(); +extern "C" void isr42(); +extern "C" void isr43(); +extern "C" void isr44(); +extern "C" void isr45(); +extern "C" void isr46(); +extern "C" void isr47(); + +struct idt_entry +{ + uint16_t offset_low; + uint16_t selector; + uint8_t always0; + uint8_t type_attributes; + uint16_t offset_high; +}__attribute__((packed)); + +struct str_idtr { + uint16_t limit; + uint32_t base; +}__attribute__((packed)); + +idt_entry idt[256]; +str_idtr idtr; + +void idt_new_entry(int num, uint32_t offset, uint16_t sel, uint8_t type_attribs) { + idt[num].offset_low = (offset & 0xFFFF); + idt[num].selector = sel; + idt[num].always0 = 0; + idt[num].type_attributes = type_attribs; + idt[num].offset_high = (offset >> 16) & 0xFFFF; +} + +extern "C" void idt_setup() { + idtr.limit = (sizeof(struct idt_entry) * 256) - 1; + idtr.base = (uint32_t)idt; + + // todo: is there really no other way? + idt_new_entry(0, (unsigned)isr0, 0x08, 0x8E); + idt_new_entry(1, (unsigned)isr1, 0x08, 0x8E); + idt_new_entry(2, (unsigned)isr2, 0x08, 0x8E); + idt_new_entry(3, (unsigned)isr3, 0x08, 0x8E); + idt_new_entry(4, (unsigned)isr4, 0x08, 0x8E); + idt_new_entry(5, (unsigned)isr5, 0x08, 0x8E); + idt_new_entry(6, (unsigned)isr6, 0x08, 0x8E); + idt_new_entry(7, (unsigned)isr7, 0x08, 0x8E); + idt_new_entry(8, (unsigned)isr8, 0x08, 0x8E); + idt_new_entry(9, (unsigned)isr9, 0x08, 0x8E); + idt_new_entry(10, (unsigned)isr10, 0x08, 0x8E); + idt_new_entry(11, (unsigned)isr11, 0x08, 0x8E); + idt_new_entry(12, (unsigned)isr12, 0x08, 0x8E); + idt_new_entry(13, (unsigned)isr13, 0x08, 0x8E); + idt_new_entry(14, (unsigned)isr14, 0x08, 0x8E); + idt_new_entry(15, (unsigned)isr15, 0x08, 0x8E); + idt_new_entry(16, (unsigned)isr16, 0x08, 0x8E); + idt_new_entry(17, (unsigned)isr17, 0x08, 0x8E); + idt_new_entry(18, (unsigned)isr18, 0x08, 0x8E); + idt_new_entry(19, (unsigned)isr19, 0x08, 0x8E); + idt_new_entry(20, (unsigned)isr20, 0x08, 0x8E); + idt_new_entry(21, (unsigned)isr21, 0x08, 0x8E); + idt_new_entry(22, (unsigned)isr22, 0x08, 0x8E); + idt_new_entry(23, (unsigned)isr23, 0x08, 0x8E); + idt_new_entry(24, (unsigned)isr24, 0x08, 0x8E); + idt_new_entry(25, (unsigned)isr25, 0x08, 0x8E); + idt_new_entry(26, (unsigned)isr26, 0x08, 0x8E); + idt_new_entry(27, (unsigned)isr27, 0x08, 0x8E); + idt_new_entry(28, (unsigned)isr28, 0x08, 0x8E); + idt_new_entry(29, (unsigned)isr29, 0x08, 0x8E); + idt_new_entry(30, (unsigned)isr30, 0x08, 0x8E); + idt_new_entry(31, (unsigned)isr31, 0x08, 0x8E); + //PIC entries + idt_new_entry(32, (unsigned)isr32, 0x08, 0x8E); + idt_new_entry(33, (unsigned)isr33, 0x08, 0x8E); + idt_new_entry(34, (unsigned)isr34, 0x08, 0x8E); + idt_new_entry(35, (unsigned)isr35, 0x08, 0x8E); + idt_new_entry(36, (unsigned)isr36, 0x08, 0x8E); + idt_new_entry(37, (unsigned)isr37, 0x08, 0x8E); + idt_new_entry(38, (unsigned)isr38, 0x08, 0x8E); + idt_new_entry(39, (unsigned)isr39, 0x08, 0x8E); + idt_new_entry(40, (unsigned)isr40, 0x08, 0x8E); + idt_new_entry(41, (unsigned)isr41, 0x08, 0x8E); + idt_new_entry(42, (unsigned)isr42, 0x08, 0x8E); + idt_new_entry(43, (unsigned)isr43, 0x08, 0x8E); + idt_new_entry(44, (unsigned)isr44, 0x08, 0x8E); + idt_new_entry(45, (unsigned)isr45, 0x08, 0x8E); + idt_new_entry(46, (unsigned)isr46, 0x08, 0x8E); + idt_new_entry(47, (unsigned)isr47, 0x08, 0x8E); +} \ No newline at end of file diff --git a/kernel/arch/x86/isr.asm b/kernel/arch/x86/isr.asm new file mode 100644 index 0000000..4ccbaf9 --- /dev/null +++ b/kernel/arch/x86/isr.asm @@ -0,0 +1,324 @@ +; isr.asm +; ISR functions are defined here. Most code is done in isr_handlers.cpp + +global isr0 +global isr1 +global isr2 +global isr3 +global isr4 +global isr5 +global isr6 +global isr7 +global isr8 +global isr9 +global isr10 +global isr11 +global isr12 +global isr13 +global isr14 +global isr15 +global isr16 +global isr17 +global isr18 +global isr19 +global isr20 +global isr21 +global isr22 +global isr23 +global isr24 +global isr25 +global isr26 +global isr27 +global isr28 +global isr29 +global isr30 +global isr31 +global isr32 +global isr33 +global isr34 +global isr35 +global isr36 +global isr37 +global isr38 +global isr39 +global isr40 +global isr41 +global isr42 +global isr43 +global isr44 +global isr45 +global isr46 +global isr47 + +section .text +align 4 + +isr0: + pushad + mov ebx, 0 + call exception_stub + hlt + popad + iret + +isr1: + pushad + popad + iret + +isr2: + pushad + popad + iret + +isr3: + pushad + popad + iret + +isr4: + pushad + popad + iret + +isr5: + pushad + popad + iret + +isr6: + pushad + mov ebx, 6 + call exception_stub + popad + iret + +isr7: + pushad + popad + iret + +isr8: + pushad + mov ebx, 8 + call exception_stub + popad + iret + +isr9: + pushad + popad + iret + +isr10: + pushad + popad + iret + +isr11: + pushad + mov ebx, 11 + call exception_stub + popad + iret + +isr12: + pushad + popad + iret + +isr13: + pushad + mov ebx, 13 + call exception_stub + popad + iret + +isr14: + pushad + mov ebx, 14 + call exception_stub + popad + iret + +isr15: + pushad + popad + iret + +isr16: + pushad + popad + iret + +isr17: + pushad + popad + iret + +isr18: + pushad + popad + iret + +isr19: + pushad + popad + iret + +isr20: + pushad + popad + iret + +isr21: + pushad + popad + iret + +isr22: + pushad + popad + iret + +isr23: + pushad + popad + iret + +isr24: + pushad + popad + iret + +isr25: + pushad + popad + iret + +isr26: + pushad + popad + iret + +isr27: + pushad + popad + iret +isr28: + pushad + popad + iret + +isr29: + pushad + popad + iret + +isr30: + pushad + popad + iret + +isr31: + pushad + popad + iret + +isr32: + pushad + ;extern pit_handler + ;call pit_handler + popad + iret + +isr33: + pushad + extern ps2_handler + call ps2_handler + popad + iret + +isr34: + pushad + popad + iret + +isr35: + pushad + popad + iret + +isr36: + pushad + popad + iret +isr37: + pushad + popad + iret + +isr38: + pushad + popad + iret + +isr39: + pushad + popad + iret + +isr40: + pushad + xchg bx, bx + popad + iret + +isr41: + pushad + popad + iret + +isr42: + pushad + popad + iret + +isr43: + pushad + popad + iret + +isr44: + pushad + popad + iret + +isr45: + pushad + popad + iret + +isr46: + pushad + popad + iret + +isr47: + pushad + popad + iret + +exception_stub: + push ebp + mov ebp, esp + + push ebx + ;cld + extern exception_handler + call exception_handler + pop ebx + + mov esp, ebp + pop ebp + ret \ No newline at end of file diff --git a/kernel/arch/x86/isr_handler.cpp b/kernel/arch/x86/isr_handler.cpp new file mode 100644 index 0000000..ac8fb49 --- /dev/null +++ b/kernel/arch/x86/isr_handler.cpp @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" void exception_handler(int e) { + //unsigned char errorcode[2]{((unsigned char) e) + 48}; + //terminal_initialize(); + printf("Exception %x\n", e); +} + +#define PS2_DATA 0x60 +extern "C" void ps2_handler() { + keyboard_write(inb(PS2_DATA)); + + pic_send_eoi(1); +} \ No newline at end of file diff --git a/kernel/arch/x86/linker.ld b/kernel/arch/x86/linker.ld new file mode 100644 index 0000000..c4bfa3b --- /dev/null +++ b/kernel/arch/x86/linker.ld @@ -0,0 +1,38 @@ +/* Excecution start point symbol */ +ENTRY(_start) + +SECTIONS +{ + . = 1M; + + /* Used to get the beginning and end address of the kernel */ + _kernel_begin = .; + + /* code. multiboot header comes first */ + .text BLOCK(4K) : ALIGN(4K) + { + *(.multiboot) + *(.text) + } + + /* read only data */ + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + /* read write data (initialized) */ + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + /* read write data (uninitialized) and stack */ + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + } + + _kernel_end = .; +} \ No newline at end of file diff --git a/kernel/arch/x86/multiboot.cpp b/kernel/arch/x86/multiboot.cpp new file mode 100644 index 0000000..9f3eedb --- /dev/null +++ b/kernel/arch/x86/multiboot.cpp @@ -0,0 +1,30 @@ +#include +#include +#include +#include "multiboot.h" +#include + +// gets the memory map and stuff +extern "C" void multiboot_main(multiboot_info_t* mbd, uint32_t magic) { + terminal_initialize(); + //printf("multiboot struc addr: %x\n", mbd); + if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { + printf("Invalid multiboot magic number\n"); + abort(); + } + + // checks bit 6 to see if there's a valid memory map + if (!(mbd->flags >> 6 & 0x1)) { + printf("Invalid GRUB memory map\n"); + abort(); + } + + // loop through memory map and display the values + for (int i = 0; i < mbd->mmap_length; i += sizeof(multiboot_memory_map_t)) { + multiboot_memory_map_t* mmmt = (multiboot_memory_map_t*)(mbd->mmap_addr + i); + + printf("Start Addr: 0x%lx | Length: 0x%lx | Size: 0x%x | Type: %d\n", + mmmt->addr, mmmt->len, mmmt->size, mmmt->type); + //printf("%lx,%x,%x,%d\n", mmmt->size, mmmt->size, mmmt->size, mmmt->size); + } +} \ No newline at end of file diff --git a/kernel/arch/x86/multiboot.h b/kernel/arch/x86/multiboot.h new file mode 100644 index 0000000..0951ebe --- /dev/null +++ b/kernel/arch/x86/multiboot.h @@ -0,0 +1,274 @@ +/* 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_uint64_t addr; + multiboot_uint64_t len; +#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/arch/x86/pic.cpp b/kernel/arch/x86/pic.cpp new file mode 100644 index 0000000..78cbcf8 --- /dev/null +++ b/kernel/arch/x86/pic.cpp @@ -0,0 +1,97 @@ +#include +#include +#include +#include + +#define PIC1 0x20 +#define PIC2 0xA0 +#define PIC1_CMD PIC1 +#define PIC1_DATA (PIC1 + 1) +#define PIC2_CMD PIC2 +#define PIC2_DATA (PIC2 + 1) +#define PIC_READ_IRR 0x0a // OCW3 irq ready next CMD read +#define PIC_READ_ISR 0x0b // OCW3 irq service next CMD read + +#define PIC_EOI 0x20 + +// pic reinitialization constants +#define ICW1_ICW4 0x01 // indicates icw4 will be present +#define ICW1_SINGLE 0x02 // single cascade mode +#define ICW1_INTERVAL4 0x04 // call address interval 4 +#define ICW1_LEVEL 0x08 // level triggered (edge) mode +#define ICW1_INIT 0x10 // initialization + +#define ICW4_8086 0x01 // 8086 mode +#define ICW4_AUTO 0x02 // auto (normal) eoi +#define ICW4_BUF_SLAVE 0x08 // buffered mode/slave +#define ICW4_BUF_MASTER 0x0C // buffered mode/master +#define ICW4_SFNM 0x10 // special fully nested (not) + +void pic_send_eoi(unsigned char irq) { + if (irq >= 8) { + outb(PIC2_CMD, PIC_EOI); + } + outb(PIC1_CMD, PIC_EOI); +} + +// offset 1 is for master, offset 2 is for slave +void pic_remap(int offset1, int offset2) { + unsigned char a1, a2; + + a1 = inb(PIC1_DATA); // save masks + a2 = inb(PIC2_DATA); + + outb(PIC1_CMD, ICW1_INIT | ICW1_ICW4); // starts initialization in cascade mode + io_wait(); + outb(PIC2_CMD, ICW1_INIT | ICW1_ICW4); + io_wait(); + outb(PIC1_DATA, offset1); // icw2: master and slave vector offset set + io_wait(); + outb(PIC2_DATA, offset2); + io_wait(); + outb(PIC1_DATA, 4); // tells master pic theres a slave pic at irq2 + io_wait(); + outb(PIC2_DATA, 2); // tells slave pic its cascade identity + io_wait(); + + outb(PIC1_DATA, ICW4_8086); + io_wait(); + outb(PIC2_DATA, ICW4_8086); + io_wait(); + + outb(PIC1_DATA, a1); // restore masks + outb(PIC2_DATA, a2); + + for (char i = 0; i < 15; i++) + { + irq_set_mask(i); + } +} + +void irq_set_mask(unsigned char irq) { + uint16_t port; + uint8_t value; + + if (irq < 8) { + port = PIC1_DATA; + } else { + port = PIC2_DATA; + irq -= 8; + } + value = inb(port) | (1 << irq); + outb(port, value); +} + +void irq_clear_mask(unsigned char irq) { + uint16_t port; + uint8_t value; + + if (irq < 8) { + port = PIC1_DATA; + } else { + port = PIC2_DATA; + irq -= 8; + } + value = inb(port) & ~(1 << irq); + outb(port, value); +} \ No newline at end of file diff --git a/kernel/arch/x86/ps2_controller.cpp b/kernel/arch/x86/ps2_controller.cpp new file mode 100644 index 0000000..9424233 --- /dev/null +++ b/kernel/arch/x86/ps2_controller.cpp @@ -0,0 +1,191 @@ +#include +#include +#include +#include + +#define PS2_DATA 0x60 // data port +#define PS2_STATUS 0x64 // status register +#define PS2_COMMAND 0x64 // command register + +// set to true if 2nd ps2 port is available +bool ps2SecondaryEnabled = false; + +void initialize_ps2_controller() { + inputbuffer_wait(); + outb(PS2_COMMAND, 0xAD); // disable devices + inputbuffer_wait(); + outb(PS2_COMMAND, 0xA7); + + outputbuffer_wait(); + inb(PS2_DATA); // flush output buffer + inb(PS2_DATA); + inb(PS2_DATA); + inb(PS2_DATA); + inb(PS2_DATA); + inb(PS2_DATA); + inb(PS2_DATA); + inb(PS2_DATA); + inb(PS2_DATA); + inb(PS2_DATA); + + + inputbuffer_wait(); + outb(PS2_COMMAND, 0x20); // set controller configuration byte + outputbuffer_wait(); + uint8_t conconfig = inb(PS2_DATA); + conconfig &= 0b00110100; + inputbuffer_wait(); + outb(PS2_COMMAND, 0x60); + inputbuffer_wait(); + outb(PS2_DATA, conconfig); + + inputbuffer_wait(); + outb(PS2_COMMAND, 0xAA); // performs controller self test + outputbuffer_wait(); + if (inb(PS2_DATA) == 0xFC) { + printf("PS/2 controller failed self test\n"); + } + inputbuffer_wait(); + outb(PS2_COMMAND, 0x60); // in case the controller resets from the test + inputbuffer_wait(); + outb(PS2_DATA, conconfig); + + int portcount = 1; + inputbuffer_wait(); + outb(PS2_COMMAND, 0xA8); // check if ps2 controller is dual channel + inputbuffer_wait(); + outb(PS2_COMMAND, 0x20); + outputbuffer_wait(); + conconfig = inb(PS2_DATA); + if ((conconfig & 0b00100000) == 0b00000000) { // checks if bit 5 is cleared + ps2SecondaryEnabled = true; + //printf("Dual channel PS/2\n"); + portcount = 2; + } else { + //printf("Single channel PS/2\n"); + } + + inputbuffer_wait(); + outb(PS2_COMMAND, 0xAB); // tests ps2 ports + outputbuffer_wait(); + if (inb(PS2_DATA) != 0x00) { + printf("PS/2 port 1 failed self test\n"); + --portcount; + } + if (ps2SecondaryEnabled) { + inputbuffer_wait(); + outb(PS2_COMMAND, 0xA9); + outputbuffer_wait(); + if (inb(PS2_DATA) != 0x00) { + printf("PS/2 port 2 failed self test\n"); + --portcount; + } + } + if (!portcount) { + printf("PS/2 initialization failed\n"); + return; + } + + conconfig |= 0b00000011; + inputbuffer_wait(); + outb(PS2_COMMAND, 0xAE); // enable ps2 ports + conconfig |= 0b00000001; + if (ps2SecondaryEnabled) { + inputbuffer_wait(); + outb(PS2_COMMAND, 0xA8); + outb(PS2_COMMAND, 0x60); + conconfig |= 0b00000011; + outb(PS2_DATA, conconfig); + } else { + inputbuffer_wait(); + outb(PS2_COMMAND, 0x60); + conconfig |= 0b00000001; + outb(PS2_DATA, conconfig); + } + + //ps2_dev_send_command(0, 0xFF); // reset devices + //inb(PS2_DATA); + //io_wait(); + if (ps2SecondaryEnabled) { + //ps2_dev_send_command(1, 0xFF); + //inb(PS2_DATA); + //io_wait(); + } + + //printf("PS/2 controller initialized\n"); +} + +// waits for input buffer (write) to be filled +void inputbuffer_wait() { + for (int i = 0; i < 15; i++) { + uint8_t status_reg = inb(PS2_STATUS); + if ((status_reg & 0b00000010)) { + return; + } + io_wait(); + } +} + +// waits for outbut buffer (read) to be filled +void outputbuffer_wait() { + for (int i = 0; i < 15; i++) { + uint8_t status_reg = inb(PS2_STATUS); + if ((status_reg & 0b00000001)) { + return; + } + io_wait(); + } +} + +// checks if inpbut buffer is set +bool inputbuffer_check() { + uint8_t status_reg = inb(PS2_STATUS); + if ((status_reg & 0b00000010)) { + return true; + } else { + return false; + } +} + +bool outputbuffer_check() { + uint8_t status_reg = inb(PS2_STATUS); + if ((status_reg & 0b00000001)) { + return true; + } else { + return false; + } +} + +/* Sends a command byte to a ps2 device +Port numbers start from 0 */ +int ps2_dev_send_command(int port, unsigned char command) { + //bool commandRecieved = false; + switch (port) + { + case 0: + for (int i = 0; i < 5; i++) { + uint8_t status_reg = inb(PS2_STATUS); + if ((status_reg & 0b00000010) == 0b00000000) { + outb(PS2_DATA, command); + return 0; + } + inb(PS2_DATA); + io_wait(); + } + return 1; // error returned if timeout expires + case 1: + outb(PS2_COMMAND, 0xD4); + for (int i = 0; i < 5; i++) { + uint8_t status_reg = inb(PS2_STATUS); + if ((status_reg & 0b00000010) == 0b00000000) { + outb(PS2_DATA, command); + return 0; + } + inb(PS2_DATA); + io_wait(); + } + return 1; + default: + return 2; // out of port range + } +} \ No newline at end of file diff --git a/kernel/arch/x86/tmtty.cpp b/kernel/arch/x86/tmtty.cpp new file mode 100644 index 0000000..d4dc772 --- /dev/null +++ b/kernel/arch/x86/tmtty.cpp @@ -0,0 +1,78 @@ +#include +#include +#include +#include +#include + +#include "vga.h" + +/* Text mode tty */ + +static const size_t VGA_WIDTH = 80; +static const size_t VGA_HEIGHT = 25; +static uint16_t* const VGA_MEMORY = (uint16_t*) 0xB8000; + +size_t terminal_row; +size_t terminal_column; +uint8_t terminal_color; +uint16_t* terminal_buffer; + +void terminal_clear(void) { + terminal_row = 0; + terminal_column = 0; + for (size_t y = 0; y < VGA_HEIGHT; y++) { + for (size_t x = 0; x < VGA_WIDTH; x++) { + const size_t i = y * VGA_WIDTH + x; + terminal_buffer[i] = vga_entry(' ', terminal_color); + } + } +} + +void terminal_initialize(void) { + terminal_color = vga_entry_color(VGA_COLOR_WHITE, VGA_COLOR_BLACK); + terminal_buffer = VGA_MEMORY; + terminal_clear(); +} + +void terminal_setcolor(uint8_t color) { + terminal_color = color; +} + +void terminal_putentryat(char c, uint8_t color, size_t x, size_t y) { + const size_t i = y * VGA_WIDTH + x; + terminal_buffer[i] = vga_entry(c, color); +} + +void terminal_scroll() { + memmove(VGA_MEMORY, (VGA_MEMORY + VGA_WIDTH), (VGA_HEIGHT * VGA_WIDTH) - VGA_WIDTH); + memset(VGA_MEMORY + (VGA_WIDTH * VGA_HEIGHT) - VGA_WIDTH, 0x0, VGA_WIDTH * 2); + --terminal_row; +} + +void terminal_putchar(char c) { + unsigned char uc = c; + if (uc == '\n') { + terminal_column = 0; + if (terminal_row++ == VGA_HEIGHT) + terminal_scroll(); + return; + } + terminal_putentryat(uc, terminal_color, terminal_column, terminal_row); + + if (++terminal_column == VGA_WIDTH) { + terminal_column = 0; + if (++terminal_row == VGA_HEIGHT) { + terminal_scroll(); + } + } +} + +void terminal_write(const char* data, size_t size) { + for (size_t i = 0; i < size; i++) { + terminal_putchar(data[i]); + } +} + +void terminal_writestring(const char* data) { + terminal_write(data, strlen(data)); +} \ No newline at end of file diff --git a/kernel/arch/x86/vga.h b/kernel/arch/x86/vga.h new file mode 100644 index 0000000..5b6b351 --- /dev/null +++ b/kernel/arch/x86/vga.h @@ -0,0 +1,35 @@ +#ifndef ARCH_I386_VGA_H +#define ARCH_I386_VGA_H + +#include + +// hardware text mode constants +enum vga_color { + VGA_COLOR_BLACK = 0, + VGA_COLOR_BLUE = 1, + VGA_COLOR_GREEN = 2, + VGA_COLOR_CYAN = 3, + VGA_COLOR_RED = 4, + VGA_COLOR_MAGENTA = 5, + VGA_COLOR_BROWN = 6, + VGA_COLOR_LIGHT_GREY = 7, + VGA_COLOR_DARK_GREY = 8, + VGA_COLOR_LIGHT_BLUE = 9, + VGA_COLOR_LIGHT_GREEN = 10, + VGA_COLOR_LIGHT_CYAN = 11, + VGA_COLOR_LIGHT_RED = 12, + VGA_COLOR_LIGHT_MAGENTA = 13, + VGA_COLOR_LIGHT_BROWN = 14, + VGA_COLOR_WHITE = 15, +}; + +static inline uint8_t vga_entry_color(enum vga_color fg, enum vga_color bg) { + return fg | bg << 4; +} + +// returns the character/color of a terminal entry +static inline uint16_t vga_entry(unsigned char uc, uint8_t color) { + return (uint16_t) uc | (uint16_t) color << 8; +} + +#endif \ No newline at end of file diff --git a/kernel/makefile b/kernel/makefile index 88659d9..7d02b32 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -1,25 +1,18 @@ # Kernel makefile -ifndef GAS - GAS = i686-elf-as -endif - ifndef CFLAGS CFLAGS = -ffreestanding -Wall -Wextra -g -std=gnu99 -O2 -Iinclude - CFLAGS += --sysroot="$(SYSROOT)" CFLAGS += -isystem="/usr/include" endif ifndef CXXFLAGS CXXFLAGS = -ffreestanding -Wall -Wextra -fno-exceptions -fno-rtti -D__is_kernel -g -O2 -Iinclude CXXFLAGS += -Iinclude - CXXFLAGS += --sysroot="$(SYSROOT)" CXXFLAGS += -isystem="/usr/include" endif ifndef LDFLAGS LDFLAGS = -T arch/$(ARCH)/linker.ld -ffreestanding -g -O2 -Iinclude - LDFLAGS += --sysroot="$(SYSROOT)" LDFLAGS += -isystem="/usr/include" endif -- cgit v1.2.3-70-g09d2