From 5e668f5e67579ba16974031955b9818f2272c055 Mon Sep 17 00:00:00 2001 From: Nigel Barink Date: Wed, 12 May 2021 23:03:00 +0100 Subject: [PATCH 01/11] Basics for an proper GDT and IDT --- Makefile | 6 +- src/kernel/arch/i386/boot.s | 381 +++++++++++++++++++++++++++++-- src/kernel/arch/i386/tty/kterm.c | 1 - src/kernel/arch/i386/tty/kterm.h | 1 + src/kernel/gdtc.cpp | 29 +++ src/kernel/gdtc.h | 20 ++ src/kernel/idt.cpp | 64 ++++++ src/kernel/idt.h | 70 ++++++ src/kernel/kernel.cpp | 39 +++- src/kernel/kernel.h | 5 +- 10 files changed, 590 insertions(+), 26 deletions(-) create mode 100644 src/kernel/gdtc.cpp create mode 100644 src/kernel/gdtc.h create mode 100644 src/kernel/idt.cpp create mode 100644 src/kernel/idt.h diff --git a/Makefile b/Makefile index 4611669..f329535 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc CPP = ${HOME}/opt/cross/bin/i686-elf-g++ CFLAGS = -ffreestanding -O2 -Wall -Wextra -OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o +OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o SRC_DIR = src BUILD_DIR = build @@ -56,4 +56,6 @@ $(BUILD_DIR)/crtn.o: $(BUILD_DIR)/io.o: $(CPP) -c $(SRC_DIR)/kernel/io.cpp -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti $(BUILD_DIR)/MMU.o: - $(CPP) -c $(SRC_DIR)/kernel/MMU.cpp -o $(BUILD_DIR)/MMU.o $(CFLAGS) -fno-exceptions -fno-rtti \ No newline at end of file + $(CPP) -c $(SRC_DIR)/kernel/MMU.cpp -o $(BUILD_DIR)/MMU.o $(CFLAGS) -fno-exceptions -fno-rtti +$(BUILD_DIR)/idt.o: + $(CPP) -c $(SRC_DIR)/kernel/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti \ No newline at end of file diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s index 99fa270..91c47df 100644 --- a/src/kernel/arch/i386/boot.s +++ b/src/kernel/arch/i386/boot.s @@ -20,8 +20,12 @@ stack_bottom: .skip 16384 # 16 KiB stack_top: - - +.text +.globl idt_flush +idt_flush: + mov 4(%esp), %eax + lidt (%eax) + ret .text .globl enablePaging @@ -51,20 +55,369 @@ loadPageDirectory: .global _start .type _start, @function _start: - - - + /*Setup the stack pointer to point to the beginning of our stack */ + /* I believe its a hight address growing down to lower adress for the stack on x86*/ mov $stack_top, %esp - + call early_main + + load_gdt: + lgdt gdt + + # set the segment selecters + + movw $0x10, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + ljmp $0x08, $flush + + flush: + #load idt + call init_idt + + # Try enable A20 + # mov $0x2401, %ax + # int $0x15 - call _init - call kernel_main - + # enable protected mode + mov %cr0, %eax + or $1, %eax + mov %eax, %cr0 - cli -1: hlt - jmp 1b - + + call kernel_main -.size _start, . - _start \ No newline at end of file + + cli + 1: hlt + jmp 1b + + + + + /* Tell processor to use our gdt*/ + gdt: + .word (gdt_end - gdt_start -1) # Size of the GDT in bytes minus 1 for math reasons + .int gdt_start # linear address of our GDT + + + + +.att_syntax + + +.size _start, . - _start + + +/* +* Interupt handlers +*/ + +.text +.macro irq_NoErrCode code:req + .globl irq\code + irq\code: + cli + pushb $0 + pushb \code + jmp irq_common +.endm + +.text +.macro irq_ErrCode code + .globl irq\code + irq\code: + cli + pushb \code + jmp irq_common +.endm + + + +.globl irq0 +irq0: + cli + push $0 + push $0 + jmp irq_common + +.globl irq1 +irq1: + cli + push $0 + push $1 + jmp irq_common + +.globl irq2 +irq2: + cli + push $0 + push $2 + jmp irq_common + +.globl irq3 +irq3: + cli + push $0 + push $3 + jmp irq_common + +.globl irq4 +irq4: + cli + push $0 + push $4 + jmp irq_common + +.globl irq5 +irq5: + cli + push $0 + push $5 + jmp irq_common + +.globl irq6 +irq6: + cli + push $0 + push $6 + jmp irq_common + +.globl irq7 +irq7: + cli + push $0 + push $7 + jmp irq_common + +.globl irq8 +irq8: + cli + push $0 + push $8 + jmp irq_common + +.globl irq9 +irq9: + cli + push $0 + push $9 + jmp irq_common + +.globl irq10 +irq10: + cli + push $0 + push $10 + jmp irq_common + +.globl irq11 +irq11: + cli + push $0 + push $11 + jmp irq_common + +.globl irq12 +irq12: + cli + push $0 + push $12 + jmp irq_common + +.globl irq13 +irq13: + cli + push $0 + push $13 + jmp irq_common + +.globl irq14 +irq14: + cli + push $0 + push $14 + jmp irq_common + +.globl irq15 +irq15: + cli + push $0 + push $15 + jmp irq_common + +.globl irq16 +irq16: + cli + push $0 + push $16 + jmp irq_common + +.globl irq17 +irq17: + cli + push $0 + push $17 + jmp irq_common + +.globl irq18 +irq18: + cli + push $0 + push $18 + jmp irq_common + +.globl irq19 +irq19: + cli + push $0 + push $19 + jmp irq_common + +.globl irq20 +irq20: + cli + push $0 + push $20 + jmp irq_common + +.globl irq21 +irq21: + cli + push $0 + push $21 + jmp irq_common + +.globl irq22 +irq22: + cli + push $0 + push $22 + jmp irq_common + +.globl irq23 +irq23: + cli + push $0 + push $23 + jmp irq_common + +.globl irq24 +irq24: + cli + push $0 + push $24 + jmp irq_common + +.globl irq25 +irq25: + cli + push $0 + push $25 + jmp irq_common + +.globl irq26 +irq26: + cli + push $0 + push $26 + jmp irq_common + +.globl irq27 +irq27: + cli + push $0 + push $27 + jmp irq_common + +.globl irq28 +irq28: + cli + push $0 + push $28 + jmp irq_common + +.globl irq29 +irq29: + cli + push $0 + push $29 + jmp irq_common + +.globl irq30 +irq30: + cli + push $0 + push $30 + jmp irq_common + +.globl irq31 +irq31: + cli + push $0 + push $31 + jmp irq_common + + + + + + +.text +irq_common: + pusha # Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax + + + mov %ds, %ax + push %eax + + /* load the kernel data segment descriptor*/ + + mov $0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + + call irq_handler + + pop %eax + + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + + popa + add $8, %esp # cleans push error and irq code + sti + iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP + +/* +* Create the GDT +*/ +.section .data +gdt_start: +gdt_null: +.long 0x0 +.long 0x0 + +gdt_kcode: +.word 0xFFFF # limit +.word 0x0 # base +.byte 0x0 # base +.byte 0b10011010 # 1st flags | type flags +.byte 0b11001111 # 2nd flags | limit +.byte 0x0 # base + +gdt_kdata: +.word 0xFFFF # limit +.word 0x0 # base +.byte 0x0 # base +.byte 0b10010010 # 1st flags | type flags +.byte 0b11001111 # 2nd flags | limit +.byte 0x0 # base +gdt_end: \ No newline at end of file diff --git a/src/kernel/arch/i386/tty/kterm.c b/src/kernel/arch/i386/tty/kterm.c index 2021e22..6dab47f 100644 --- a/src/kernel/arch/i386/tty/kterm.c +++ b/src/kernel/arch/i386/tty/kterm.c @@ -89,4 +89,3 @@ void kterm_writestring(const char* data ){ AS_KERNEL(); kterm_write(data, strlen(data)); } - diff --git a/src/kernel/arch/i386/tty/kterm.h b/src/kernel/arch/i386/tty/kterm.h index 6cf784e..f1570c6 100644 --- a/src/kernel/arch/i386/tty/kterm.h +++ b/src/kernel/arch/i386/tty/kterm.h @@ -15,6 +15,7 @@ void kterm_putat(char, uint8_t, size_t, size_t); void kterm_put(char); void kterm_write(const char*, size_t); void kterm_writestring(const char*); + void kterm_scrollup(); #define KernelTag "[Kernel]: " diff --git a/src/kernel/gdtc.cpp b/src/kernel/gdtc.cpp new file mode 100644 index 0000000..f21e80f --- /dev/null +++ b/src/kernel/gdtc.cpp @@ -0,0 +1,29 @@ +#include "gdtc.h" + + +gdtEntry_t gdt[3]; + + +void gdtSetGate(int num, uint64_t base, uint64_t limit, uint8_t access, + uint8_t gran){ + gdt[num].lBase = (base & 0xFFFF); + gdt[num].mBase = (base >> 16) & 0xFF; + gdt[num].hBase = (base >> 24) & 0xFF; + + gdt[num].lLimit = (limit & 0xFFFF); + gdt[num].granularity = ((limit >> 16) & 0x0F); + + gdt[num].granularity |= (gran & 0xF0); + gdt[num].access = access; +} + +void setupGdt(){ + gdtPointer.limit = (sizeof(gdtEntry_t) * 3) - 1; + gdtPointer.base = &gdt; + + gdtSetGate(0, 0, 0, 0, 0); + gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); + gdtSetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); + + loadGdt(); +} diff --git a/src/kernel/gdtc.h b/src/kernel/gdtc.h new file mode 100644 index 0000000..2b34997 --- /dev/null +++ b/src/kernel/gdtc.h @@ -0,0 +1,20 @@ +#include +extern "c"{ + +typedef struct { + uint16_t lLimit; + uint16_t lBase; + uint8_t mBase; + uint8_t access; + uint8_t granularity; + uint8_t hBase; +} gdtEntry_t; + +struct { + uint16_t limit; + uint32_t base; +} gdtPointer; + +extern void loadGdt(); +void setupGdt(); +} \ No newline at end of file diff --git a/src/kernel/idt.cpp b/src/kernel/idt.cpp new file mode 100644 index 0000000..2ba7165 --- /dev/null +++ b/src/kernel/idt.cpp @@ -0,0 +1,64 @@ +#include "idt.h" + +IDT_entry idt_table[256]; +IDT_ptr idt_ptr; + +void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){ + idt_table[num].offset_1 = base & 0xFFFF; + idt_table[num].selector = sel; + idt_table[num].zero = 0; + idt_table[num].type_attr = flags; + idt_table[num].offset_2 = (base >> 16) & 0xFFFF; + +}; + + +void irq_handler (registers regs) { + kterm_writestring("received interrupt!"); +} + + +void init_idt(){ + // Initialise the IDT pointer + idt_ptr.length = sizeof(IDT_entry) * 255; + idt_ptr.base = (uint32_t)&idt_table; + + + // TODO: Set everything to zero first + + set_id_entry(0, (uint32_t) irq0 , 0x08, 0x8E); + set_id_entry(1, (uint32_t) irq1 , 0x08, 0x8E); + set_id_entry(2, (uint32_t) irq2 , 0x08, 0x8E); + set_id_entry(3, (uint32_t) irq3 , 0x08, 0x8E); + set_id_entry(4, (uint32_t) irq4 , 0x08, 0x8E); + set_id_entry(5, (uint32_t) irq5 , 0x08, 0x8E); + set_id_entry(6, (uint32_t) irq6 , 0x08, 0x8E); + set_id_entry(7, (uint32_t) irq7 , 0x08, 0x8E); + set_id_entry(8, (uint32_t) irq8 , 0x08, 0x8E); + set_id_entry(9, (uint32_t) irq9 , 0x08, 0x8E); + set_id_entry(10, (uint32_t) irq10 , 0x08, 0x8E); + set_id_entry(11, (uint32_t) irq11 , 0x08, 0x8E); + set_id_entry(12, (uint32_t) irq12 , 0x08, 0x8E); + set_id_entry(13, (uint32_t) irq13 , 0x08, 0x8E); + set_id_entry(14, (uint32_t) irq14 , 0x08, 0x8E); + set_id_entry(15, (uint32_t) irq15 , 0x08, 0x8E); + set_id_entry(16, (uint32_t) irq16 , 0x08, 0x8E); + set_id_entry(17, (uint32_t) irq17 , 0x08, 0x8E); + set_id_entry(18, (uint32_t) irq18 , 0x08, 0x8E); + set_id_entry(19, (uint32_t) irq19 , 0x08, 0x8E); + set_id_entry(20, (uint32_t) irq20 , 0x08, 0x8E); + set_id_entry(21, (uint32_t) irq21 , 0x08, 0x8E); + set_id_entry(22, (uint32_t) irq22 , 0x08, 0x8E); + set_id_entry(23, (uint32_t) irq23 , 0x08, 0x8E); + set_id_entry(24, (uint32_t) irq24 , 0x08, 0x8E); + set_id_entry(25, (uint32_t) irq25 , 0x08, 0x8E); + set_id_entry(26, (uint32_t) irq26 , 0x08, 0x8E); + set_id_entry(27, (uint32_t) irq27 , 0x08, 0x8E); + set_id_entry(28, (uint32_t) irq28 , 0x08, 0x8E); + set_id_entry(29, (uint32_t) irq29 , 0x08, 0x8E); + set_id_entry(30, (uint32_t) irq30 , 0x08, 0x8E); + set_id_entry(31, (uint32_t) irq31 , 0x08, 0x8E); + + + idt_flush((uint32_t)&idt_ptr); +} diff --git a/src/kernel/idt.h b/src/kernel/idt.h new file mode 100644 index 0000000..78b9a3d --- /dev/null +++ b/src/kernel/idt.h @@ -0,0 +1,70 @@ +#pragma once +#include "stdint.h" + +extern "C" void kterm_writestring(const char* data ); + +extern "C" { + struct __attribute__((__packed__)) IDT_entry { + uint16_t offset_1; + uint16_t selector; + uint8_t zero; + uint8_t type_attr; + uint16_t offset_2; + }; + + struct __attribute__((__packed__)) IDT_ptr { + unsigned short length; + unsigned long base; + }; + + struct registers { + uint32_t ds; // Data segment selector + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha. + uint32_t int_no, err_code; // Interrupt number and error code (if applicable) + uint32_t eip, cs, eflags, useresp, ss; + }; + + + extern void idt_flush(uint32_t); + void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags); + void init_idt(); + + void irq_handler (registers regs); + + extern void irq0 (); + extern void irq1 (); + extern void irq2 (); + extern void irq3 (); + extern void irq4 (); + extern void irq5 (); + extern void irq6 (); + extern void irq7 (); + extern void irq8 (); + extern void irq9 (); + extern void irq10 (); + extern void irq11 (); + extern void irq12 (); + extern void irq13 (); + extern void irq14 (); + extern void irq15 (); + extern void irq16 (); + extern void irq17 (); + extern void irq18 (); + extern void irq19 (); + extern void irq20 (); + extern void irq21 (); + extern void irq22 (); + extern void irq23 (); + extern void irq24 (); + extern void irq25 (); + extern void irq26 (); + extern void irq27 (); + extern void irq28 (); + extern void irq29 (); + extern void irq30 (); + extern void irq31 (); + + + + +} diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 14f0321..ddb9402 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -74,6 +74,12 @@ char read_serial() { } +void print_serial(const char* string ){ + for(size_t i = 0; i < strlen(string); i ++){ + write_serial(string[i]); + } +} + void test_serial(){ /** Serial test **/ kterm_writestring("Writing to COM1 serial port:"); @@ -93,11 +99,34 @@ void test_serial(){ } + extern "C" { + + void early_main(){ + + init_serial(); + print_serial("\033[31;42mEarly main called!\n"); + + + } + void kernel_main (void) { + + print_serial("\033[31;42mKernel main called!\n"); + + /** initialize terminal interface */ kterm_init(); + /** Setup the MMU **/ + kterm_writestring("Starting MMU...\n"); + auto mmu = MMU(); + mmu.enable(); + kterm_writestring("MMU enabled!\n"); + + + + /** Wrtite stuff to the screen to test the terminal**/ kterm_writestring("Hello world!\n"); kterm_writestring("We got newline support!\n"); @@ -114,14 +143,11 @@ extern "C" { auto testObject = Test(); testObject.printMe(); - /** Setup the MMU **/ - kterm_writestring("Starting MMU...\n"); - auto mmu = MMU(); - mmu.enable(); - kterm_writestring("MMU enabled!\n"); - + /** test interrupt handlers **/ + //asm volatile ("int $0x3"); + //asm volatile ("int $0x4"); /** Lets start using the serial port for debugging .. **/ // Hopefully once we go into realmode or do something that @@ -129,7 +155,6 @@ extern "C" { // some situational awareness //Serial serialbus = Serial::init(); - test_serial(); } diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 080869a..4b2b306 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -1,7 +1,8 @@ #pragma once extern "C" { -#include "../libc/include/string.h" -#include "arch/i386/tty/kterm.h" + #include "../libc/include/string.h" + #include "arch/i386/tty/kterm.h" } #include "MMU.h" #include "io.h" +#include "idt.h" \ No newline at end of file From 0d0c06ab09e6c4058d0da247e9cb6452a9cc3546 Mon Sep 17 00:00:00 2001 From: Nigel Barink Date: Wed, 12 May 2021 23:48:06 +0100 Subject: [PATCH 02/11] Working on PIC --- src/kernel/arch/i386/boot.s | 300 ++++++++++++++++++++++++------------ src/kernel/idt.cpp | 85 ++++++---- src/kernel/idt.h | 50 ++++-- src/kernel/io.cpp | 10 +- src/kernel/io.h | 3 +- src/kernel/kernel.cpp | 49 +++++- src/kernel/kernel.h | 3 +- 7 files changed, 342 insertions(+), 158 deletions(-) diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s index 91c47df..5f1b4e8 100644 --- a/src/kernel/arch/i386/boot.s +++ b/src/kernel/arch/i386/boot.s @@ -20,103 +20,13 @@ stack_bottom: .skip 16384 # 16 KiB stack_top: -.text -.globl idt_flush -idt_flush: - mov 4(%esp), %eax - lidt (%eax) - ret - -.text -.globl enablePaging -enablePaging: - push %ebp - mov %esp, %ebp - mov %cr0, %eax - or $0x80000000, %eax - mov %eax, %cr0 - mov %ebp, %esp - pop %ebp - ret - -.text -.globl loadPageDirectory -loadPageDirectory: - push %ebp - mov %esp, %ebp - mov 8(%esp), %eax - mov %eax, %cr3 - mov %ebp, %esp - pop %ebp - ret - - .section .text -.global _start -.type _start, @function -_start: - /*Setup the stack pointer to point to the beginning of our stack */ - /* I believe its a hight address growing down to lower adress for the stack on x86*/ - mov $stack_top, %esp - call early_main - - load_gdt: - lgdt gdt - - # set the segment selecters - - movw $0x10, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %ax, %ss - ljmp $0x08, $flush - - flush: - #load idt - call init_idt - - # Try enable A20 - # mov $0x2401, %ax - # int $0x15 - - - # enable protected mode - mov %cr0, %eax - or $1, %eax - mov %eax, %cr0 - - - call kernel_main - - - cli - 1: hlt - jmp 1b - - - - - /* Tell processor to use our gdt*/ - gdt: - .word (gdt_end - gdt_start -1) # Size of the GDT in bytes minus 1 for math reasons - .int gdt_start # linear address of our GDT - - - - -.att_syntax - - -.size _start, . - _start - /* * Interupt handlers */ - -.text +# NOTE: I have no clue how I should use these macros. +# Have tried to use them in a myriad of ways, none would actually work .macro irq_NoErrCode code:req .globl irq\code irq\code: @@ -126,7 +36,6 @@ _start: jmp irq_common .endm -.text .macro irq_ErrCode code .globl irq\code irq\code: @@ -135,8 +44,6 @@ _start: jmp irq_common .endm - - .globl irq0 irq0: cli @@ -362,11 +269,120 @@ irq31: jmp irq_common +.globl irq0 +irq0: + cli + push $0 + push $0 + jmp irq_common + +.globl irq1 +irq1: + cli + push $0 + push $1 + jmp irq_common + +.globl irq2 +irq2: + cli + push $0 + push $2 + jmp irq_common + +.globl irq3 +irq3: + cli + push $0 + push $3 + jmp irq_common + +.globl irq4 +irq4: + cli + push $0 + push $4 + jmp irq_common + +.globl irq5 +irq5: + cli + push $0 + push $5 + jmp irq_common + +.globl irq6 +irq6: + cli + push $0 + push $6 + jmp irq_common + +.globl irq7 +irq7: + cli + push $0 + push $7 + jmp irq_common + +.globl irq8 +irq8: + cli + push $0 + push $8 + jmp irq_common + +.globl irq9 +irq9: + cli + push $0 + push $9 + jmp irq_common + +.globl irq10 +irq10: + cli + push $0 + push $10 + jmp irq_common + +.globl irq11 +irq11: + cli + push $0 + push $11 + jmp irq_common + +.globl irq12 +irq12: + cli + push $0 + push $12 + jmp irq_common + +.globl irq13 +irq13: + cli + push $0 + push $13 + jmp irq_common + +.globl irq14 +irq14: + cli + push $0 + push $14 + jmp irq_common + +.globl irq15 +irq15: + cli + push $0 + push $15 + jmp irq_common - -.text irq_common: pusha # Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax @@ -396,6 +412,96 @@ irq_common: sti iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP +.globl idt_flush +idt_flush: + mov 4(%esp), %eax + lidt (%eax) + ret + +.globl enablePaging +enablePaging: + push %ebp + mov %esp, %ebp + mov %cr0, %eax + or $0x80000000, %eax + mov %eax, %cr0 + mov %ebp, %esp + pop %ebp + ret + +.globl loadPageDirectory +loadPageDirectory: + push %ebp + mov %esp, %ebp + mov 8(%esp), %eax + mov %eax, %cr3 + mov %ebp, %esp + pop %ebp + ret + +.global _start +.type _start, @function +_start: + /*Setup the stack pointer to point to the beginning of our stack */ + /* I believe its a hight address growing down to lower adress for the stack on x86*/ + mov $stack_top, %esp + call early_main + cli + load_gdt: + lgdt gdt + + # set the segment selecters + + movw $0x10, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + movw %ax, %ss + ljmp $0x08, $flush + + flush: + + + #load idt + call init_idt + sti + + # Try enable A20 + # mov $0x2401, %ax + # int $0x15 + + + # enable protected mode + mov %cr0, %eax + or $1, %eax + mov %eax, %cr0 + + + call kernel_main + + + cli + 1: hlt + jmp 1b + + + + + /* Tell processor to use our gdt*/ + gdt: + .word (gdt_end - gdt_start -1) # Size of the GDT in bytes minus 1 for math reasons + .int gdt_start # linear address of our GDT + + + + +.att_syntax + + +.size _start, . - _start + + /* * Create the GDT */ diff --git a/src/kernel/idt.cpp b/src/kernel/idt.cpp index 2ba7165..abe1c4d 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/idt.cpp @@ -14,7 +14,7 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){ void irq_handler (registers regs) { - kterm_writestring("received interrupt!"); + kterm_writestring("received interrupt!\n"); } @@ -26,39 +26,58 @@ void init_idt(){ // TODO: Set everything to zero first - set_id_entry(0, (uint32_t) irq0 , 0x08, 0x8E); - set_id_entry(1, (uint32_t) irq1 , 0x08, 0x8E); - set_id_entry(2, (uint32_t) irq2 , 0x08, 0x8E); - set_id_entry(3, (uint32_t) irq3 , 0x08, 0x8E); - set_id_entry(4, (uint32_t) irq4 , 0x08, 0x8E); - set_id_entry(5, (uint32_t) irq5 , 0x08, 0x8E); - set_id_entry(6, (uint32_t) irq6 , 0x08, 0x8E); - set_id_entry(7, (uint32_t) irq7 , 0x08, 0x8E); - set_id_entry(8, (uint32_t) irq8 , 0x08, 0x8E); - set_id_entry(9, (uint32_t) irq9 , 0x08, 0x8E); - set_id_entry(10, (uint32_t) irq10 , 0x08, 0x8E); - set_id_entry(11, (uint32_t) irq11 , 0x08, 0x8E); - set_id_entry(12, (uint32_t) irq12 , 0x08, 0x8E); - set_id_entry(13, (uint32_t) irq13 , 0x08, 0x8E); - set_id_entry(14, (uint32_t) irq14 , 0x08, 0x8E); - set_id_entry(15, (uint32_t) irq15 , 0x08, 0x8E); - set_id_entry(16, (uint32_t) irq16 , 0x08, 0x8E); - set_id_entry(17, (uint32_t) irq17 , 0x08, 0x8E); - set_id_entry(18, (uint32_t) irq18 , 0x08, 0x8E); - set_id_entry(19, (uint32_t) irq19 , 0x08, 0x8E); - set_id_entry(20, (uint32_t) irq20 , 0x08, 0x8E); - set_id_entry(21, (uint32_t) irq21 , 0x08, 0x8E); - set_id_entry(22, (uint32_t) irq22 , 0x08, 0x8E); - set_id_entry(23, (uint32_t) irq23 , 0x08, 0x8E); - set_id_entry(24, (uint32_t) irq24 , 0x08, 0x8E); - set_id_entry(25, (uint32_t) irq25 , 0x08, 0x8E); - set_id_entry(26, (uint32_t) irq26 , 0x08, 0x8E); - set_id_entry(27, (uint32_t) irq27 , 0x08, 0x8E); - set_id_entry(28, (uint32_t) irq28 , 0x08, 0x8E); - set_id_entry(29, (uint32_t) irq29 , 0x08, 0x8E); - set_id_entry(30, (uint32_t) irq30 , 0x08, 0x8E); - set_id_entry(31, (uint32_t) irq31 , 0x08, 0x8E); + set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8E); + set_id_entry(1, (uint32_t) irs1 , 0x08, 0x8E); + set_id_entry(2, (uint32_t) irs2 , 0x08, 0x8E); + set_id_entry(3, (uint32_t) irs3 , 0x08, 0x8E); + set_id_entry(4, (uint32_t) irs4 , 0x08, 0x8E); + set_id_entry(5, (uint32_t) irs5 , 0x08, 0x8E); + set_id_entry(6, (uint32_t) irs6 , 0x08, 0x8E); + set_id_entry(7, (uint32_t) irs7 , 0x08, 0x8E); + set_id_entry(8, (uint32_t) irs8 , 0x08, 0x8E); + set_id_entry(9, (uint32_t) irs9 , 0x08, 0x8E); + set_id_entry(10, (uint32_t) irs10 , 0x08, 0x8E); + set_id_entry(11, (uint32_t) irs11 , 0x08, 0x8E); + set_id_entry(12, (uint32_t) irs12 , 0x08, 0x8E); + set_id_entry(13, (uint32_t) irs13 , 0x08, 0x8E); + set_id_entry(14, (uint32_t) irs14 , 0x08, 0x8E); + set_id_entry(15, (uint32_t) irs15 , 0x08, 0x8E); + set_id_entry(16, (uint32_t) irs16 , 0x08, 0x8E); + set_id_entry(17, (uint32_t) irs17 , 0x08, 0x8E); + set_id_entry(18, (uint32_t) irs18 , 0x08, 0x8E); + set_id_entry(19, (uint32_t) irs19 , 0x08, 0x8E); + set_id_entry(20, (uint32_t) irs20 , 0x08, 0x8E); + set_id_entry(21, (uint32_t) irs21 , 0x08, 0x8E); + set_id_entry(22, (uint32_t) irs22 , 0x08, 0x8E); + set_id_entry(23, (uint32_t) irs23 , 0x08, 0x8E); + set_id_entry(24, (uint32_t) irs24 , 0x08, 0x8E); + set_id_entry(25, (uint32_t) irs25 , 0x08, 0x8E); + set_id_entry(26, (uint32_t) irs26 , 0x08, 0x8E); + set_id_entry(27, (uint32_t) irs27 , 0x08, 0x8E); + set_id_entry(28, (uint32_t) irs28 , 0x08, 0x8E); + set_id_entry(29, (uint32_t) irs29 , 0x08, 0x8E); + set_id_entry(30, (uint32_t) irs30 , 0x08, 0x8E); + set_id_entry(31, (uint32_t) irs31 , 0x08, 0x8E); + + // pic IRQ Table + set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E); + set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E); + set_id_entry(34, (uint32_t)irq2, 0x08, 0x8E); + set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E); + set_id_entry(36, (uint32_t)irq4, 0x08, 0x8E); + set_id_entry(37, (uint32_t)irq5, 0x08, 0x8E); + set_id_entry(38, (uint32_t)irq6, 0x08, 0x8E); + set_id_entry(39, (uint32_t)irq7, 0x08, 0x8E); + set_id_entry(40, (uint32_t)irq8, 0x08, 0x8E); + set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E); + set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E); + set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E); + set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E); + set_id_entry(45, (uint32_t)irq13, 0x08, 0x8E); + set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E); + set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E); + idt_flush((uint32_t)&idt_ptr); } diff --git a/src/kernel/idt.h b/src/kernel/idt.h index 78b9a3d..d239f43 100644 --- a/src/kernel/idt.h +++ b/src/kernel/idt.h @@ -31,6 +31,39 @@ extern "C" { void irq_handler (registers regs); + extern void irs0 (); + extern void irs1 (); + extern void irs2 (); + extern void irs3 (); + extern void irs4 (); + extern void irs5 (); + extern void irs6 (); + extern void irs7 (); + extern void irs8 (); + extern void irs9 (); + extern void irs10 (); + extern void irs11 (); + extern void irs12 (); + extern void irs13 (); + extern void irs14 (); + extern void irs15 (); + extern void irs16 (); + extern void irs17 (); + extern void irs18 (); + extern void irs19 (); + extern void irs20 (); + extern void irs21 (); + extern void irs22 (); + extern void irs23 (); + extern void irs24 (); + extern void irs25 (); + extern void irs26 (); + extern void irs27 (); + extern void irs28 (); + extern void irs29 (); + extern void irs30 (); + extern void irs31 (); + extern void irq0 (); extern void irq1 (); extern void irq2 (); @@ -47,23 +80,6 @@ extern "C" { extern void irq13 (); extern void irq14 (); extern void irq15 (); - extern void irq16 (); - extern void irq17 (); - extern void irq18 (); - extern void irq19 (); - extern void irq20 (); - extern void irq21 (); - extern void irq22 (); - extern void irq23 (); - extern void irq24 (); - extern void irq25 (); - extern void irq26 (); - extern void irq27 (); - extern void irq28 (); - extern void irq29 (); - extern void irq30 (); - extern void irq31 (); - diff --git a/src/kernel/io.cpp b/src/kernel/io.cpp index 11dbc3b..f9ed07d 100644 --- a/src/kernel/io.cpp +++ b/src/kernel/io.cpp @@ -56,4 +56,12 @@ void outsw(unsigned short , const void *, void outsl(unsigned short , const void *, unsigned long ){ - } \ No newline at end of file + } + +void io_wait(void) +{ + /* TODO: This is probably fragile. */ + asm volatile ( "jmp 1f\n\t" + "1:jmp 2f\n\t" + "2:" ); +} \ No newline at end of file diff --git a/src/kernel/io.h b/src/kernel/io.h index 8b729f9..c7fd561 100644 --- a/src/kernel/io.h +++ b/src/kernel/io.h @@ -40,4 +40,5 @@ void outsb(unsigned short port, const void *addr, void outsw(unsigned short port, const void *addr, unsigned long count); void outsl(unsigned short port, const void *addr, - unsigned long count); \ No newline at end of file + unsigned long count); +void io_wait(); \ No newline at end of file diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index ddb9402..4360aac 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -107,22 +107,37 @@ extern "C" { init_serial(); print_serial("\033[31;42mEarly main called!\n"); + print_serial("Remapping PIC\n"); + // remap the PIC IRQ table + outb(0x20, 0x11); + outb(0xA0, 0x11); + outb(0x21, 0x20); + outb(0xA1, 0x28); + outb(0x21, 0x04); + outb(0xA1, 0x02); + outb(0x21, 0x01); + outb(0xA1, 0x01); + outb(0x21, 0x0); + outb(0xA1, 0x0); + + + print_serial("done... \n"); } void kernel_main (void) { - - print_serial("\033[31;42mKernel main called!\n"); + + print_serial("Kernel main called!\n"); /** initialize terminal interface */ kterm_init(); /** Setup the MMU **/ - kterm_writestring("Starting MMU...\n"); - auto mmu = MMU(); - mmu.enable(); - kterm_writestring("MMU enabled!\n"); + //kterm_writestring("Starting MMU...\n"); + //auto mmu = MMU(); + //mmu.enable(); + //kterm_writestring("MMU enabled!\n"); @@ -143,11 +158,29 @@ extern "C" { auto testObject = Test(); testObject.printMe(); + IRQ_set_mask(0); + IRQ_set_mask(1); + IRQ_set_mask(2); + IRQ_set_mask(3); + IRQ_set_mask(4); + IRQ_set_mask(5); + IRQ_set_mask(6); + IRQ_set_mask(7); + IRQ_set_mask(8); + IRQ_set_mask(9); + IRQ_set_mask(10); + IRQ_set_mask(11); + IRQ_set_mask(12); + IRQ_set_mask(13); + IRQ_set_mask(14); + IRQ_set_mask(15); + + /** test interrupt handlers **/ - //asm volatile ("int $0x3"); + asm volatile ("int $0x03"); - //asm volatile ("int $0x4"); + //asm volatile ("int $4"); /** Lets start using the serial port for debugging .. **/ // Hopefully once we go into realmode or do something that diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 4b2b306..50fc89b 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -5,4 +5,5 @@ extern "C" { } #include "MMU.h" #include "io.h" -#include "idt.h" \ No newline at end of file +#include "idt.h" +#include "pic.h" \ No newline at end of file From 28ac6a05afed8ce88c00208bc987073e0d65ef3d Mon Sep 17 00:00:00 2001 From: nigel Date: Wed, 12 May 2021 20:43:15 -0400 Subject: [PATCH 03/11] Interrupts are working.. processor no longer resets --- Makefile | 2 +- src/kernel/arch/i386/boot.s | 112 -------------------- src/kernel/idt.cpp | 205 +++++++++++++++++++++++++++--------- src/kernel/idt.h | 73 +++++++------ src/kernel/kernel.cpp | 14 ++- src/kernel/kernel.h | 2 +- 6 files changed, 207 insertions(+), 201 deletions(-) diff --git a/Makefile b/Makefile index f329535..3aec044 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ all: clean build build: build_kernel run run: - $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio + $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std build_kernel: $(OBJ_LINK_LIST) diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s index 5f1b4e8..0ea809c 100644 --- a/src/kernel/arch/i386/boot.s +++ b/src/kernel/arch/i386/boot.s @@ -138,7 +138,6 @@ irq12: .globl irq13 irq13: cli - push $0 push $13 jmp irq_common @@ -269,117 +268,6 @@ irq31: jmp irq_common -.globl irq0 -irq0: - cli - push $0 - push $0 - jmp irq_common - -.globl irq1 -irq1: - cli - push $0 - push $1 - jmp irq_common - -.globl irq2 -irq2: - cli - push $0 - push $2 - jmp irq_common - -.globl irq3 -irq3: - cli - push $0 - push $3 - jmp irq_common - -.globl irq4 -irq4: - cli - push $0 - push $4 - jmp irq_common - -.globl irq5 -irq5: - cli - push $0 - push $5 - jmp irq_common - -.globl irq6 -irq6: - cli - push $0 - push $6 - jmp irq_common - -.globl irq7 -irq7: - cli - push $0 - push $7 - jmp irq_common - -.globl irq8 -irq8: - cli - push $0 - push $8 - jmp irq_common - -.globl irq9 -irq9: - cli - push $0 - push $9 - jmp irq_common - -.globl irq10 -irq10: - cli - push $0 - push $10 - jmp irq_common - -.globl irq11 -irq11: - cli - push $0 - push $11 - jmp irq_common - -.globl irq12 -irq12: - cli - push $0 - push $12 - jmp irq_common - -.globl irq13 -irq13: - cli - push $0 - push $13 - jmp irq_common - -.globl irq14 -irq14: - cli - push $0 - push $14 - jmp irq_common - -.globl irq15 -irq15: - cli - push $0 - push $15 - jmp irq_common diff --git a/src/kernel/idt.cpp b/src/kernel/idt.cpp index abe1c4d..c32d6e4 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/idt.cpp @@ -1,5 +1,103 @@ #include "idt.h" +static void itoa (char *buf, int base, int d) { + char *p = buf; + char *p1, *p2; + unsigned long ud = d; + int divisor = 10; + if ( base == 'd' && d < 0){ + *p++ = '-'; + buf++; + ud = -d; + } else if (base == 'x'){ + divisor = 16; + } + + do { + int remainder = ud % divisor; + + *p++ = (remainder < 10 ) ? remainder + '0' : remainder + 'a' -10; + } while(ud /= divisor); + + /*terminate buf*/ + *p =0; + p1 = buf; + p2 = p -1; + + while (p1 < p2) + { + char tmp = *p1; + *p1 = *p2; + *p2 = tmp; + p1++; + p2--; + + } + +} + +void printf ( const char *format, ...) { + + AS_KERNEL(); + char **arg = (char **)&format; + int c; + char buf[20]; + + arg++; + + while ((c = *format++) != 0){ + if( c != '%') + kterm_put(c); + else{ + char *p, *p2; + int pad0 = 0, pad = 0; + + c = *format++; + if(c =='0'){ + pad0 = 1; + c = *format++; + } + + if ( c >= '0' && c <= '9'){ + pad = c - '0'; + c = *format++; + } + + switch (c) + { + case 'd': + + case 'u': + case 'x': + itoa(buf, c, *((int *) arg++)); + + p = buf; + goto string; + break; + + case 's': + p = *arg++; + if(!p) + p = "(null)"; + + string: + for (p2 = p; *p2; p2++); + for (; p2 < p + pad; p2++) + kterm_put(pad0 ? '0': ' '); + while (*p) + kterm_put(*p++); + break; + + + default: + kterm_put(*((int *)arg++)); + break; + } + } + } +} + + IDT_entry idt_table[256]; IDT_ptr idt_ptr; @@ -15,6 +113,15 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){ void irq_handler (registers regs) { kterm_writestring("received interrupt!\n"); + + + printf(" Interrupt number: %d \n", regs.int_no); + + if( regs.int_no == 13){ + printf(" Error code: %d \n", regs.err_code); + + } + } @@ -26,57 +133,57 @@ void init_idt(){ // TODO: Set everything to zero first - set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8E); - set_id_entry(1, (uint32_t) irs1 , 0x08, 0x8E); - set_id_entry(2, (uint32_t) irs2 , 0x08, 0x8E); - set_id_entry(3, (uint32_t) irs3 , 0x08, 0x8E); - set_id_entry(4, (uint32_t) irs4 , 0x08, 0x8E); - set_id_entry(5, (uint32_t) irs5 , 0x08, 0x8E); - set_id_entry(6, (uint32_t) irs6 , 0x08, 0x8E); - set_id_entry(7, (uint32_t) irs7 , 0x08, 0x8E); - set_id_entry(8, (uint32_t) irs8 , 0x08, 0x8E); - set_id_entry(9, (uint32_t) irs9 , 0x08, 0x8E); - set_id_entry(10, (uint32_t) irs10 , 0x08, 0x8E); - set_id_entry(11, (uint32_t) irs11 , 0x08, 0x8E); - set_id_entry(12, (uint32_t) irs12 , 0x08, 0x8E); - set_id_entry(13, (uint32_t) irs13 , 0x08, 0x8E); - set_id_entry(14, (uint32_t) irs14 , 0x08, 0x8E); - set_id_entry(15, (uint32_t) irs15 , 0x08, 0x8E); - set_id_entry(16, (uint32_t) irs16 , 0x08, 0x8E); - set_id_entry(17, (uint32_t) irs17 , 0x08, 0x8E); - set_id_entry(18, (uint32_t) irs18 , 0x08, 0x8E); - set_id_entry(19, (uint32_t) irs19 , 0x08, 0x8E); - set_id_entry(20, (uint32_t) irs20 , 0x08, 0x8E); - set_id_entry(21, (uint32_t) irs21 , 0x08, 0x8E); - set_id_entry(22, (uint32_t) irs22 , 0x08, 0x8E); - set_id_entry(23, (uint32_t) irs23 , 0x08, 0x8E); - set_id_entry(24, (uint32_t) irs24 , 0x08, 0x8E); - set_id_entry(25, (uint32_t) irs25 , 0x08, 0x8E); - set_id_entry(26, (uint32_t) irs26 , 0x08, 0x8E); - set_id_entry(27, (uint32_t) irs27 , 0x08, 0x8E); - set_id_entry(28, (uint32_t) irs28 , 0x08, 0x8E); - set_id_entry(29, (uint32_t) irs29 , 0x08, 0x8E); - set_id_entry(30, (uint32_t) irs30 , 0x08, 0x8E); - set_id_entry(31, (uint32_t) irs31 , 0x08, 0x8E); - + set_id_entry(0, (uint32_t) irq0 , 0x08, 0x8E); + set_id_entry(1, (uint32_t) irq1 , 0x08, 0x8E); + set_id_entry(2, (uint32_t) irq2 , 0x08, 0x8E); + set_id_entry(3, (uint32_t) irq3 , 0x08, 0x8E); + set_id_entry(4, (uint32_t) irq4 , 0x08, 0x8E); + set_id_entry(5, (uint32_t) irq5 , 0x08, 0x8E); + set_id_entry(6, (uint32_t) irq6 , 0x08, 0x8E); + set_id_entry(7, (uint32_t) irq7 , 0x08, 0x8E); + set_id_entry(8, (uint32_t) irq8 , 0x08, 0x8E); + set_id_entry(9, (uint32_t) irq9 , 0x08, 0x8E); + set_id_entry(10, (uint32_t) irq10 , 0x08, 0x8E); + set_id_entry(11, (uint32_t) irq11 , 0x08, 0x8E); + set_id_entry(12, (uint32_t) irq12 , 0x08, 0x8E); + set_id_entry(13, (uint32_t) irq13 , 0x08, 0x8E); + set_id_entry(14, (uint32_t) irq14 , 0x08, 0x8E); + set_id_entry(15, (uint32_t) irq15 , 0x08, 0x8E); + set_id_entry(16, (uint32_t) irq16 , 0x08, 0x8E); + set_id_entry(17, (uint32_t) irq17 , 0x08, 0x8E); + set_id_entry(18, (uint32_t) irq18 , 0x08, 0x8E); + set_id_entry(19, (uint32_t) irq19 , 0x08, 0x8E); + set_id_entry(20, (uint32_t) irq20 , 0x08, 0x8E); + set_id_entry(21, (uint32_t) irq21 , 0x08, 0x8E); + set_id_entry(22, (uint32_t) irq22 , 0x08, 0x8E); + set_id_entry(23, (uint32_t) irq23 , 0x08, 0x8E); + set_id_entry(24, (uint32_t) irq24 , 0x08, 0x8E); + set_id_entry(25, (uint32_t) irq25 , 0x08, 0x8E); + set_id_entry(26, (uint32_t) irq26 , 0x08, 0x8E); + set_id_entry(27, (uint32_t) irq27 , 0x08, 0x8E); + set_id_entry(28, (uint32_t) irq28 , 0x08, 0x8E); + set_id_entry(29, (uint32_t) irq29 , 0x08, 0x8E); + set_id_entry(30, (uint32_t) irq30 , 0x08, 0x8E); + set_id_entry(31, (uint32_t) irq31 , 0x08, 0x8E); +/* // pic IRQ Table - set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E); - set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E); - set_id_entry(34, (uint32_t)irq2, 0x08, 0x8E); - set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E); - set_id_entry(36, (uint32_t)irq4, 0x08, 0x8E); - set_id_entry(37, (uint32_t)irq5, 0x08, 0x8E); - set_id_entry(38, (uint32_t)irq6, 0x08, 0x8E); - set_id_entry(39, (uint32_t)irq7, 0x08, 0x8E); - set_id_entry(40, (uint32_t)irq8, 0x08, 0x8E); - set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E); - set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E); - set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E); - set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E); - set_id_entry(45, (uint32_t)irq13, 0x08, 0x8E); - set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E); - set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E); + set_id_entry(32, (uint32_t)irs0, 0x08, 0x8E); + set_id_entry(33, (uint32_t)irs1, 0x08, 0x8E); + set_id_entry(34, (uint32_t)irs2, 0x08, 0x8E); + set_id_entry(35, (uint32_t)irs3, 0x08, 0x8E); + set_id_entry(36, (uint32_t)irs4, 0x08, 0x8E); + set_id_entry(37, (uint32_t)irs5, 0x08, 0x8E); + set_id_entry(38, (uint32_t)irs6, 0x08, 0x8E); + set_id_entry(39, (uint32_t)irs7, 0x08, 0x8E); + set_id_entry(40, (uint32_t)irs8, 0x08, 0x8E); + set_id_entry(41, (uint32_t)irs9, 0x08, 0x8E); + set_id_entry(42, (uint32_t)irs10, 0x08, 0x8E); + set_id_entry(43, (uint32_t)irs11, 0x08, 0x8E); + set_id_entry(44, (uint32_t)irs12, 0x08, 0x8E); + set_id_entry(45, (uint32_t)irs13, 0x08, 0x8E); + set_id_entry(46, (uint32_t)irs14, 0x08, 0x8E); + set_id_entry(47, (uint32_t)irs15, 0x08, 0x8E);*/ idt_flush((uint32_t)&idt_ptr); diff --git a/src/kernel/idt.h b/src/kernel/idt.h index d239f43..07c7440 100644 --- a/src/kernel/idt.h +++ b/src/kernel/idt.h @@ -1,7 +1,14 @@ #pragma once #include "stdint.h" +#include "stddef.h" +#include "arch/i386/vga/colors.h" + +#define AS_KERNEL() ( kterm_writestring("[KERNEL]:")) extern "C" void kterm_writestring(const char* data ); +extern "C" void kterm_putat(char, uint8_t, size_t, size_t); +extern "C" void kterm_put(char); + extern "C" { struct __attribute__((__packed__)) IDT_entry { @@ -31,39 +38,6 @@ extern "C" { void irq_handler (registers regs); - extern void irs0 (); - extern void irs1 (); - extern void irs2 (); - extern void irs3 (); - extern void irs4 (); - extern void irs5 (); - extern void irs6 (); - extern void irs7 (); - extern void irs8 (); - extern void irs9 (); - extern void irs10 (); - extern void irs11 (); - extern void irs12 (); - extern void irs13 (); - extern void irs14 (); - extern void irs15 (); - extern void irs16 (); - extern void irs17 (); - extern void irs18 (); - extern void irs19 (); - extern void irs20 (); - extern void irs21 (); - extern void irs22 (); - extern void irs23 (); - extern void irs24 (); - extern void irs25 (); - extern void irs26 (); - extern void irs27 (); - extern void irs28 (); - extern void irs29 (); - extern void irs30 (); - extern void irs31 (); - extern void irq0 (); extern void irq1 (); extern void irq2 (); @@ -80,6 +54,39 @@ extern "C" { extern void irq13 (); extern void irq14 (); extern void irq15 (); + extern void irq16 (); + extern void irq17 (); + extern void irq18 (); + extern void irq19 (); + extern void irq20 (); + extern void irq21 (); + extern void irq22 (); + extern void irq23 (); + extern void irq24 (); + extern void irq25 (); + extern void irq26 (); + extern void irq27 (); + extern void irq28 (); + extern void irq29 (); + extern void irq30 (); + extern void irq31 (); +/* + extern void irq0 (); + extern void irq1 (); + extern void irq2 (); + extern void irq3 (); + extern void irq4 (); + extern void irq5 (); + extern void irq6 (); + extern void irq7 (); + extern void irq8 (); + extern void irq9 (); + extern void irq10 (); + extern void irq11 (); + extern void irq12 (); + extern void irq13 (); + extern void irq14 (); + extern void irq15 ();*/ diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 4360aac..2530c7a 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -9,6 +9,10 @@ void delay(int t){ asm("NOP"); } + + + + class Test { public: Test(); @@ -109,7 +113,7 @@ extern "C" { print_serial("Remapping PIC\n"); // remap the PIC IRQ table - outb(0x20, 0x11); + /*outb(0x20, 0x11); outb(0xA0, 0x11); outb(0x21, 0x20); outb(0xA1, 0x28); @@ -118,7 +122,7 @@ extern "C" { outb(0x21, 0x01); outb(0xA1, 0x01); outb(0x21, 0x0); - outb(0xA1, 0x0); + outb(0xA1, 0x0);*/ print_serial("done... \n"); @@ -158,7 +162,7 @@ extern "C" { auto testObject = Test(); testObject.printMe(); - IRQ_set_mask(0); + /*IRQ_set_mask(0); IRQ_set_mask(1); IRQ_set_mask(2); IRQ_set_mask(3); @@ -174,13 +178,13 @@ extern "C" { IRQ_set_mask(13); IRQ_set_mask(14); IRQ_set_mask(15); - + */ /** test interrupt handlers **/ asm volatile ("int $0x03"); - //asm volatile ("int $4"); + asm volatile ("int $4"); /** Lets start using the serial port for debugging .. **/ // Hopefully once we go into realmode or do something that diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 50fc89b..3b1b0bc 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -6,4 +6,4 @@ extern "C" { #include "MMU.h" #include "io.h" #include "idt.h" -#include "pic.h" \ No newline at end of file +//#include "pic.h" \ No newline at end of file From 592db0ebcf787ac33bf2acb317afa04ef65bfce6 Mon Sep 17 00:00:00 2001 From: Nigel Barink Date: Sun, 16 May 2021 15:53:14 +0100 Subject: [PATCH 04/11] More work on interrupt handling, Started timer interrupt implementation, PIC remapped hopefully successfull --- Makefile | 11 +- README.md | 3 + screenshots/WIP_interruptHandling.png | 3 + src/kernel/arch/i386/boot.s | 426 +++++++++++++++--------- src/kernel/{ => arch/i386/gdt}/gdtc.cpp | 0 src/kernel/{ => arch/i386/gdt}/gdtc.h | 0 src/kernel/{ => arch/i386/idt}/idt.cpp | 111 +++--- src/kernel/arch/i386/idt/idt.h | 81 +++++ src/kernel/arch/i386/pic/pic.cpp | 62 ++++ src/kernel/arch/i386/pic/pic.h | 57 ++++ src/kernel/idt.h | 93 ------ src/kernel/kernel.cpp | 46 +-- src/kernel/kernel.h | 4 +- src/kernel/timer.cpp | 27 ++ src/kernel/timer.h | 6 + 15 files changed, 580 insertions(+), 350 deletions(-) create mode 100644 screenshots/WIP_interruptHandling.png rename src/kernel/{ => arch/i386/gdt}/gdtc.cpp (100%) rename src/kernel/{ => arch/i386/gdt}/gdtc.h (100%) rename src/kernel/{ => arch/i386/idt}/idt.cpp (51%) create mode 100644 src/kernel/arch/i386/idt/idt.h create mode 100644 src/kernel/arch/i386/pic/pic.cpp create mode 100644 src/kernel/arch/i386/pic/pic.h delete mode 100644 src/kernel/idt.h create mode 100644 src/kernel/timer.cpp create mode 100644 src/kernel/timer.h diff --git a/Makefile b/Makefile index 3aec044..aa43673 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc CPP = ${HOME}/opt/cross/bin/i686-elf-g++ CFLAGS = -ffreestanding -O2 -Wall -Wextra -OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o +OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/MMU.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o SRC_DIR = src BUILD_DIR = build @@ -24,7 +24,7 @@ all: clean build build: build_kernel run run: - $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std + $(EMULATOR) -d int -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std build_kernel: $(OBJ_LINK_LIST) @@ -55,7 +55,12 @@ $(BUILD_DIR)/crtn.o: $(BUILD_DIR)/io.o: $(CPP) -c $(SRC_DIR)/kernel/io.cpp -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti + $(BUILD_DIR)/MMU.o: $(CPP) -c $(SRC_DIR)/kernel/MMU.cpp -o $(BUILD_DIR)/MMU.o $(CFLAGS) -fno-exceptions -fno-rtti + $(BUILD_DIR)/idt.o: - $(CPP) -c $(SRC_DIR)/kernel/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti \ No newline at end of file + $(CPP) -c $(SRC_DIR)/kernel/arch/i386/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti + +$(BUILD_DIR)/pic.o: + $(CPP) -c $(SRC_DIR)/kernel/arch/i386/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti diff --git a/README.md b/README.md index cf263a6..eefdecd 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,9 @@ ________________________ The first scrolling boot screen. 😲 + +W.I.P - Working on interrupt handling + ________________________ ### The goal diff --git a/screenshots/WIP_interruptHandling.png b/screenshots/WIP_interruptHandling.png new file mode 100644 index 0000000..6c22b50 --- /dev/null +++ b/screenshots/WIP_interruptHandling.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bfbde3cc43610681eca3f38e56d8af1d0e5d0ad2f465cb743a5b8ea5c3adbe47 +size 16282 diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s index 0ea809c..17432e4 100644 --- a/src/kernel/arch/i386/boot.s +++ b/src/kernel/arch/i386/boot.s @@ -27,251 +27,365 @@ stack_top: */ # NOTE: I have no clue how I should use these macros. # Have tried to use them in a myriad of ways, none would actually work -.macro irq_NoErrCode code:req - .globl irq\code - irq\code: +.macro irs_NoErrCode code:req + .globl irs\code + irs\code: cli pushb $0 pushb \code - jmp irq_common + jmp irs_common .endm -.macro irq_ErrCode code - .globl irq\code - irq\code: +.macro irs_ErrCode code + .globl irs\code + irs\code: cli pushb \code - jmp irq_common + jmp irs_common .endm +.globl irs0 +irs0: + cli + push $0 + push $0 + jmp irs_common + +.globl irs1 +irs1: + cli + push $0 + push $1 + jmp irs_common + +.globl irs2 +irs2: + cli + push $0 + push $2 + jmp irs_common + +.globl irs3 +irs3: + cli + push $0 + push $3 + jmp irs_common + +.globl irs4 +irs4: + cli + push $0 + push $4 + jmp irs_common + +.globl irs5 +irs5: + cli + push $0 + push $5 + jmp irs_common + +.globl irs6 +irs6: + cli + push $0 + push $6 + jmp irs_common + +.globl irs7 +irs7: + cli + push $0 + push $7 + jmp irs_common + +.globl irs8 +irs8: + cli + push $0 + push $8 + jmp irs_common + +.globl irs9 +irs9: + cli + push $0 + push $9 + jmp irs_common + +.globl irs10 +irs10: + cli + push $0 + push $10 + jmp irs_common + +.globl irs11 +irs11: + cli + push $0 + push $11 + jmp irs_common + +.globl irs12 +irs12: + cli + push $0 + push $12 + jmp irs_common + +.globl irs13 +irs13: + cli + push $13 + jmp irs_common + +.globl irs14 +irs14: + cli + push $0 + push $14 + jmp irs_common + +.globl irs15 +irs15: + cli + push $0 + push $15 + jmp irs_common + +.globl irs16 +irs16: + cli + push $0 + push $16 + jmp irs_common + +.globl irs17 +irs17: + cli + push $0 + push $17 + jmp irs_common + +.globl irs18 +irs18: + cli + push $0 + push $18 + jmp irs_common + +.globl irs19 +irs19: + cli + push $0 + push $19 + jmp irs_common + +.globl irs20 +irs20: + cli + push $0 + push $20 + jmp irs_common + +.globl irs21 +irs21: + cli + push $0 + push $21 + jmp irs_common + +.globl irs22 +irs22: + cli + push $0 + push $22 + jmp irs_common + +.globl irs23 +irs23: + cli + push $0 + push $23 + jmp irs_common + +.globl irs24 +irs24: + cli + push $0 + push $24 + jmp irs_common + +.globl irs25 +irs25: + cli + push $0 + push $25 + jmp irs_common + +.globl irs26 +irs26: + cli + push $0 + push $26 + jmp irs_common + +.globl irs27 +irs27: + cli + push $0 + push $27 + jmp irs_common + +.globl irs28 +irs28: + cli + push $0 + push $28 + jmp irs_common + +.globl irs29 +irs29: + cli + push $0 + push $29 + jmp irs_common + +.globl irs30 +irs30: + cli + push $0 + push $30 + jmp irs_common + +.globl irs31 +irs31: + cli + push $0 + push $31 + jmp irs_common + + + .globl irq0 irq0: cli push $0 - push $0 - jmp irq_common + push $32 + jmp irs_common .globl irq1 irq1: cli push $0 - push $1 - jmp irq_common + push $33 + jmp irs_common .globl irq2 irq2: cli push $0 - push $2 - jmp irq_common + push $34 + jmp irs_common .globl irq3 irq3: cli push $0 - push $3 - jmp irq_common + push $35 + jmp irs_common .globl irq4 irq4: cli push $0 - push $4 - jmp irq_common + push $36 + jmp irs_common .globl irq5 irq5: cli push $0 - push $5 - jmp irq_common + push $37 + jmp irs_common .globl irq6 irq6: cli push $0 - push $6 - jmp irq_common + push $38 + jmp irs_common .globl irq7 irq7: cli push $0 - push $7 - jmp irq_common + push $39 + jmp irs_common .globl irq8 irq8: cli push $0 - push $8 - jmp irq_common + push $40 + jmp irs_common .globl irq9 irq9: cli push $0 - push $9 - jmp irq_common + push $41 + jmp irs_common .globl irq10 irq10: cli push $0 - push $10 - jmp irq_common + push $42 + jmp irs_common .globl irq11 irq11: cli push $0 - push $11 - jmp irq_common + push $43 + jmp irs_common + .globl irq12 irq12: cli push $0 - push $12 - jmp irq_common + push $44 + jmp irs_common .globl irq13 irq13: cli - push $13 - jmp irq_common + push $0 + push $45 + jmp irs_common .globl irq14 irq14: cli push $0 - push $14 - jmp irq_common + push $46 + jmp irs_common .globl irq15 irq15: cli push $0 - push $15 - jmp irq_common - -.globl irq16 -irq16: - cli - push $0 - push $16 - jmp irq_common - -.globl irq17 -irq17: - cli - push $0 - push $17 - jmp irq_common - -.globl irq18 -irq18: - cli - push $0 - push $18 - jmp irq_common - -.globl irq19 -irq19: - cli - push $0 - push $19 - jmp irq_common - -.globl irq20 -irq20: - cli - push $0 - push $20 - jmp irq_common - -.globl irq21 -irq21: - cli - push $0 - push $21 - jmp irq_common - -.globl irq22 -irq22: - cli - push $0 - push $22 - jmp irq_common - -.globl irq23 -irq23: - cli - push $0 - push $23 - jmp irq_common - -.globl irq24 -irq24: - cli - push $0 - push $24 - jmp irq_common - -.globl irq25 -irq25: - cli - push $0 - push $25 - jmp irq_common - -.globl irq26 -irq26: - cli - push $0 - push $26 - jmp irq_common - -.globl irq27 -irq27: - cli - push $0 - push $27 - jmp irq_common - -.globl irq28 -irq28: - cli - push $0 - push $28 - jmp irq_common - -.globl irq29 -irq29: - cli - push $0 - push $29 - jmp irq_common - -.globl irq30 -irq30: - cli - push $0 - push $30 - jmp irq_common - -.globl irq31 -irq31: - cli - push $0 - push $31 - jmp irq_common + push $47 + jmp irs_common - -irq_common: +irs_common: pusha # Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax @@ -286,7 +400,7 @@ irq_common: mov %ax, %fs mov %ax, %gs - call irq_handler + call irs_handler pop %eax @@ -296,7 +410,7 @@ irq_common: mov %ax, %gs popa - add $8, %esp # cleans push error and irq code + add $8, %esp # cleans push error and irs code sti iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP diff --git a/src/kernel/gdtc.cpp b/src/kernel/arch/i386/gdt/gdtc.cpp similarity index 100% rename from src/kernel/gdtc.cpp rename to src/kernel/arch/i386/gdt/gdtc.cpp diff --git a/src/kernel/gdtc.h b/src/kernel/arch/i386/gdt/gdtc.h similarity index 100% rename from src/kernel/gdtc.h rename to src/kernel/arch/i386/gdt/gdtc.h diff --git a/src/kernel/idt.cpp b/src/kernel/arch/i386/idt/idt.cpp similarity index 51% rename from src/kernel/idt.cpp rename to src/kernel/arch/i386/idt/idt.cpp index c32d6e4..d515272 100644 --- a/src/kernel/idt.cpp +++ b/src/kernel/arch/i386/idt/idt.cpp @@ -111,10 +111,9 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){ }; -void irq_handler (registers regs) { +void irs_handler (registers regs) { kterm_writestring("received interrupt!\n"); - - + printf(" Interrupt number: %d \n", regs.int_no); if( regs.int_no == 13){ @@ -125,6 +124,10 @@ void irq_handler (registers regs) { } + + + + void init_idt(){ // Initialise the IDT pointer idt_ptr.length = sizeof(IDT_entry) * 255; @@ -133,57 +136,61 @@ void init_idt(){ // TODO: Set everything to zero first - set_id_entry(0, (uint32_t) irq0 , 0x08, 0x8E); - set_id_entry(1, (uint32_t) irq1 , 0x08, 0x8E); - set_id_entry(2, (uint32_t) irq2 , 0x08, 0x8E); - set_id_entry(3, (uint32_t) irq3 , 0x08, 0x8E); - set_id_entry(4, (uint32_t) irq4 , 0x08, 0x8E); - set_id_entry(5, (uint32_t) irq5 , 0x08, 0x8E); - set_id_entry(6, (uint32_t) irq6 , 0x08, 0x8E); - set_id_entry(7, (uint32_t) irq7 , 0x08, 0x8E); - set_id_entry(8, (uint32_t) irq8 , 0x08, 0x8E); - set_id_entry(9, (uint32_t) irq9 , 0x08, 0x8E); - set_id_entry(10, (uint32_t) irq10 , 0x08, 0x8E); - set_id_entry(11, (uint32_t) irq11 , 0x08, 0x8E); - set_id_entry(12, (uint32_t) irq12 , 0x08, 0x8E); - set_id_entry(13, (uint32_t) irq13 , 0x08, 0x8E); - set_id_entry(14, (uint32_t) irq14 , 0x08, 0x8E); - set_id_entry(15, (uint32_t) irq15 , 0x08, 0x8E); - set_id_entry(16, (uint32_t) irq16 , 0x08, 0x8E); - set_id_entry(17, (uint32_t) irq17 , 0x08, 0x8E); - set_id_entry(18, (uint32_t) irq18 , 0x08, 0x8E); - set_id_entry(19, (uint32_t) irq19 , 0x08, 0x8E); - set_id_entry(20, (uint32_t) irq20 , 0x08, 0x8E); - set_id_entry(21, (uint32_t) irq21 , 0x08, 0x8E); - set_id_entry(22, (uint32_t) irq22 , 0x08, 0x8E); - set_id_entry(23, (uint32_t) irq23 , 0x08, 0x8E); - set_id_entry(24, (uint32_t) irq24 , 0x08, 0x8E); - set_id_entry(25, (uint32_t) irq25 , 0x08, 0x8E); - set_id_entry(26, (uint32_t) irq26 , 0x08, 0x8E); - set_id_entry(27, (uint32_t) irq27 , 0x08, 0x8E); - set_id_entry(28, (uint32_t) irq28 , 0x08, 0x8E); - set_id_entry(29, (uint32_t) irq29 , 0x08, 0x8E); - set_id_entry(30, (uint32_t) irq30 , 0x08, 0x8E); - set_id_entry(31, (uint32_t) irq31 , 0x08, 0x8E); + set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8E); + set_id_entry(1, (uint32_t) irs1 , 0x08, 0x8E); + set_id_entry(2, (uint32_t) irs2 , 0x08, 0x8E); + set_id_entry(3, (uint32_t) irs3 , 0x08, 0x8E); + set_id_entry(4, (uint32_t) irs4 , 0x08, 0x8E); + set_id_entry(5, (uint32_t) irs5 , 0x08, 0x8E); + set_id_entry(6, (uint32_t) irs6 , 0x08, 0x8E); + set_id_entry(7, (uint32_t) irs7 , 0x08, 0x8E); + set_id_entry(8, (uint32_t) irs8 , 0x08, 0x8E); + set_id_entry(9, (uint32_t) irs9 , 0x08, 0x8E); + set_id_entry(10, (uint32_t) irs10 , 0x08, 0x8E); + set_id_entry(11, (uint32_t) irs11 , 0x08, 0x8E); + set_id_entry(12, (uint32_t) irs12 , 0x08, 0x8E); + set_id_entry(13, (uint32_t) irs13 , 0x08, 0x8E); + set_id_entry(14, (uint32_t) irs14 , 0x08, 0x8E); + set_id_entry(15, (uint32_t) irs15 , 0x08, 0x8E); + set_id_entry(16, (uint32_t) irs16 , 0x08, 0x8E); + set_id_entry(17, (uint32_t) irs17 , 0x08, 0x8E); + set_id_entry(18, (uint32_t) irs18 , 0x08, 0x8E); + set_id_entry(19, (uint32_t) irs19 , 0x08, 0x8E); + set_id_entry(20, (uint32_t) irs20 , 0x08, 0x8E); + set_id_entry(21, (uint32_t) irs21 , 0x08, 0x8E); + set_id_entry(22, (uint32_t) irs22 , 0x08, 0x8E); + set_id_entry(23, (uint32_t) irs23 , 0x08, 0x8E); + set_id_entry(24, (uint32_t) irs24 , 0x08, 0x8E); + set_id_entry(25, (uint32_t) irs25 , 0x08, 0x8E); + set_id_entry(26, (uint32_t) irs26 , 0x08, 0x8E); + set_id_entry(27, (uint32_t) irs27 , 0x08, 0x8E); + set_id_entry(28, (uint32_t) irs28 , 0x08, 0x8E); + set_id_entry(29, (uint32_t) irs29 , 0x08, 0x8E); + set_id_entry(30, (uint32_t) irs30 , 0x08, 0x8E); + set_id_entry(31, (uint32_t) irs31 , 0x08, 0x8E); + + + //print_serial("Remapping PIC\n"); + PIC_remap(0x20, 0x28); + -/* // pic IRQ Table - set_id_entry(32, (uint32_t)irs0, 0x08, 0x8E); - set_id_entry(33, (uint32_t)irs1, 0x08, 0x8E); - set_id_entry(34, (uint32_t)irs2, 0x08, 0x8E); - set_id_entry(35, (uint32_t)irs3, 0x08, 0x8E); - set_id_entry(36, (uint32_t)irs4, 0x08, 0x8E); - set_id_entry(37, (uint32_t)irs5, 0x08, 0x8E); - set_id_entry(38, (uint32_t)irs6, 0x08, 0x8E); - set_id_entry(39, (uint32_t)irs7, 0x08, 0x8E); - set_id_entry(40, (uint32_t)irs8, 0x08, 0x8E); - set_id_entry(41, (uint32_t)irs9, 0x08, 0x8E); - set_id_entry(42, (uint32_t)irs10, 0x08, 0x8E); - set_id_entry(43, (uint32_t)irs11, 0x08, 0x8E); - set_id_entry(44, (uint32_t)irs12, 0x08, 0x8E); - set_id_entry(45, (uint32_t)irs13, 0x08, 0x8E); - set_id_entry(46, (uint32_t)irs14, 0x08, 0x8E); - set_id_entry(47, (uint32_t)irs15, 0x08, 0x8E);*/ + set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E); + set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E); + set_id_entry(34, (uint32_t)irq2, 0x08, 0x8E); + set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E); + set_id_entry(36, (uint32_t)irq4, 0x08, 0x8E); + set_id_entry(37, (uint32_t)irq5, 0x08, 0x8E); + set_id_entry(38, (uint32_t)irq6, 0x08, 0x8E); + set_id_entry(39, (uint32_t)irq7, 0x08, 0x8E); + set_id_entry(40, (uint32_t)irq8, 0x08, 0x8E); + set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E); + set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E); + set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E); + set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E); + set_id_entry(45, (uint32_t)irq13, 0x08, 0x8E); + set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E); + set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E); idt_flush((uint32_t)&idt_ptr); diff --git a/src/kernel/arch/i386/idt/idt.h b/src/kernel/arch/i386/idt/idt.h new file mode 100644 index 0000000..7281fa9 --- /dev/null +++ b/src/kernel/arch/i386/idt/idt.h @@ -0,0 +1,81 @@ +#pragma once + +#include "stdint.h" +#include "stddef.h" +#include "../vga/colors.h" +#include "../pic/pic.h"; + +#define AS_KERNEL() ( kterm_writestring("[KERNEL]:")) + +extern "C" void kterm_writestring(const char* data ); +extern "C" void kterm_putat(char, uint8_t, size_t, size_t); +extern "C" void kterm_put(char); + + +extern "C" { + struct __attribute__((__packed__)) IDT_entry { + uint16_t offset_1; + uint16_t selector; + uint8_t zero; + uint8_t type_attr; + uint16_t offset_2; + }; + + struct __attribute__((__packed__)) IDT_ptr { + unsigned short length; + unsigned long base; + }; + + struct registers { + uint32_t ds; // Data segment selector + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha. + uint32_t int_no, err_code; // Interrupt number and error code (if applicable) + uint32_t eip, cs, eflags, useresp, ss; + }; + + + extern void idt_flush(uint32_t); + void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags); + void init_idt(); + + void irq_handler (registers regs); + + void irs_handler (registers regs); + + extern void irs0 (); + extern void irs1 (); + extern void irs2 (); + extern void irs3 (); + extern void irs4 (); + extern void irs5 (); + extern void irs6 (); + extern void irs7 (); + extern void irs8 (); + extern void irs9 (); + extern void irs10 (); + extern void irs11 (); + extern void irs12 (); + extern void irs13 (); + extern void irs14 (); + extern void irs15 (); + extern void irs16 (); + extern void irs17 (); + extern void irs18 (); + extern void irs19 (); + extern void irs20 (); + extern void irs21 (); + extern void irs22 (); + extern void irs23 (); + extern void irs24 (); + extern void irs25 (); + extern void irs26 (); + extern void irs27 (); + extern void irs28 (); + extern void irs29 (); + extern void irs30 (); + extern void irs31 (); + + + + +} diff --git a/src/kernel/arch/i386/pic/pic.cpp b/src/kernel/arch/i386/pic/pic.cpp new file mode 100644 index 0000000..5f1967c --- /dev/null +++ b/src/kernel/arch/i386/pic/pic.cpp @@ -0,0 +1,62 @@ +#include "pic.h" + +extern "C" void PIC_sendEOI (unsigned char irq){ + if(irq >= 8) + outb(PIC2_COMMAND, PIC_EOI); + outb(PIC1_COMMAND, PIC_EOI); +} + +/* Helper func */ +static uint16_t __pic_get_irq_reg(int ocw3) +{ + /* OCW3 to PIC CMD to get the register values. PIC2 is chained, and + * represents IRQs 8-15. PIC1 is IRQs 0-7, with 2 being the chain */ + outb(PIC1_COMMAND, ocw3); + outb(PIC2_COMMAND, ocw3); + return (inb(PIC2_COMMAND) << 8) | inb(PIC1_COMMAND); +} + +/* Returns the combined value of the cascaded PICs irq request register */ +uint16_t pic_get_irr(void) +{ + return __pic_get_irq_reg(PIC_READ_IRR); +} + +/* Returns the combined value of the cascaded PICs in-service register */ +uint16_t pic_get_isr(void) +{ + return __pic_get_irq_reg(PIC_READ_ISR); +} + + +void PIC_remap (int offset1, int offset2 ){ + unsigned char a1, a2; + + a1 = inb(PIC1_DATA); + a2 = inb(PIC2_DATA); + + + // Start initialization + + outb(PIC1_COMMAND, ICW1_INIT | ICW1_ICW4); + io_wait(); + outb(PIC2_COMMAND, ICW1_INIT | ICW1_ICW4); + io_wait(); + outb(PIC1_DATA, offset1); + io_wait(); + outb(PIC2_DATA, offset2); + io_wait(); + outb(PIC1_DATA, 4); + io_wait(); + outb(PIC2_DATA, 2); + io_wait(); + + outb(PIC1_DATA, ICW4_8086); + io_wait(); + outb(PIC2_DATA, ICW4_8086); + io_wait(); + + outb(PIC1_DATA, a1); + outb(PIC2_DATA, a2); + +} \ No newline at end of file diff --git a/src/kernel/arch/i386/pic/pic.h b/src/kernel/arch/i386/pic/pic.h new file mode 100644 index 0000000..5358f5a --- /dev/null +++ b/src/kernel/arch/i386/pic/pic.h @@ -0,0 +1,57 @@ +#pragma once +#include "../../../io.h" + +#define PIC1 0x20 /* IO base address for master PIC */ +#define PIC2 0xA0 /* IO base address for slave PIC */ +#define PIC1_COMMAND PIC1 +#define PIC1_DATA (PIC1+1) +#define PIC2_COMMAND PIC2 +#define PIC2_DATA (PIC2+1) + + +#define ICW1_ICW4 0x01 /* ICW4 (not) needed */ +#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ +#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ +#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ +#define ICW1_INIT 0x10 /* Initialization - required! */ + +#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) 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) */ + +#define PIC_EOI 0x20 +#define PIC_READ_IRR 0x0a /* OCW3 irq ready next CMD read */ +#define PIC_READ_ISR 0x0b /* OCW3 irq service next CMD read */ + +extern "C"{ + +extern void irq0 (); +extern void irq1 (); +extern void irq2 (); +extern void irq3 (); +extern void irq4 (); +extern void irq5 (); +extern void irq6 (); +extern void irq7 (); +extern void irq8 (); +extern void irq9 (); +extern void irq10 (); +extern void irq11 (); +extern void irq12 (); +extern void irq13 (); +extern void irq14 (); +extern void irq15 (); + +void PIC_sendEOI (unsigned char irq); + +} + + +static uint16_t __pic_get_irq_reg(int ocw3); +uint16_t pic_get_irr(void); +uint16_t pic_get_isr(void); + + +void PIC_remap (int offset1, int offset2 ); \ No newline at end of file diff --git a/src/kernel/idt.h b/src/kernel/idt.h deleted file mode 100644 index 07c7440..0000000 --- a/src/kernel/idt.h +++ /dev/null @@ -1,93 +0,0 @@ -#pragma once -#include "stdint.h" -#include "stddef.h" -#include "arch/i386/vga/colors.h" - -#define AS_KERNEL() ( kterm_writestring("[KERNEL]:")) - -extern "C" void kterm_writestring(const char* data ); -extern "C" void kterm_putat(char, uint8_t, size_t, size_t); -extern "C" void kterm_put(char); - - -extern "C" { - struct __attribute__((__packed__)) IDT_entry { - uint16_t offset_1; - uint16_t selector; - uint8_t zero; - uint8_t type_attr; - uint16_t offset_2; - }; - - struct __attribute__((__packed__)) IDT_ptr { - unsigned short length; - unsigned long base; - }; - - struct registers { - uint32_t ds; // Data segment selector - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha. - uint32_t int_no, err_code; // Interrupt number and error code (if applicable) - uint32_t eip, cs, eflags, useresp, ss; - }; - - - extern void idt_flush(uint32_t); - void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags); - void init_idt(); - - void irq_handler (registers regs); - - extern void irq0 (); - extern void irq1 (); - extern void irq2 (); - extern void irq3 (); - extern void irq4 (); - extern void irq5 (); - extern void irq6 (); - extern void irq7 (); - extern void irq8 (); - extern void irq9 (); - extern void irq10 (); - extern void irq11 (); - extern void irq12 (); - extern void irq13 (); - extern void irq14 (); - extern void irq15 (); - extern void irq16 (); - extern void irq17 (); - extern void irq18 (); - extern void irq19 (); - extern void irq20 (); - extern void irq21 (); - extern void irq22 (); - extern void irq23 (); - extern void irq24 (); - extern void irq25 (); - extern void irq26 (); - extern void irq27 (); - extern void irq28 (); - extern void irq29 (); - extern void irq30 (); - extern void irq31 (); -/* - extern void irq0 (); - extern void irq1 (); - extern void irq2 (); - extern void irq3 (); - extern void irq4 (); - extern void irq5 (); - extern void irq6 (); - extern void irq7 (); - extern void irq8 (); - extern void irq9 (); - extern void irq10 (); - extern void irq11 (); - extern void irq12 (); - extern void irq13 (); - extern void irq14 (); - extern void irq15 ();*/ - - - -} diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 2530c7a..edd7f22 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -9,10 +9,6 @@ void delay(int t){ asm("NOP"); } - - - - class Test { public: Test(); @@ -20,7 +16,6 @@ class Test { ~Test(); }; - Test::Test(){ kterm_writestring("Create a test object\n"); }; @@ -56,7 +51,6 @@ static int init_serial() { return 0; } - int is_transmit_empty() { return inb(PORT + 5) & 0x20; } @@ -77,7 +71,6 @@ char read_serial() { return inb(PORT); } - void print_serial(const char* string ){ for(size_t i = 0; i < strlen(string); i ++){ write_serial(string[i]); @@ -102,31 +95,13 @@ void test_serial(){ kterm_writestring("\n"); } - - extern "C" { void early_main(){ init_serial(); print_serial("\033[31;42mEarly main called!\n"); - - print_serial("Remapping PIC\n"); - // remap the PIC IRQ table - /*outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, 0x28); - outb(0x21, 0x04); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x0); - outb(0xA1, 0x0);*/ - - - print_serial("done... \n"); - + } void kernel_main (void) { @@ -162,24 +137,7 @@ extern "C" { auto testObject = Test(); testObject.printMe(); - /*IRQ_set_mask(0); - IRQ_set_mask(1); - IRQ_set_mask(2); - IRQ_set_mask(3); - IRQ_set_mask(4); - IRQ_set_mask(5); - IRQ_set_mask(6); - IRQ_set_mask(7); - IRQ_set_mask(8); - IRQ_set_mask(9); - IRQ_set_mask(10); - IRQ_set_mask(11); - IRQ_set_mask(12); - IRQ_set_mask(13); - IRQ_set_mask(14); - IRQ_set_mask(15); - */ - + /** test interrupt handlers **/ asm volatile ("int $0x03"); diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 3b1b0bc..ced720a 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -3,7 +3,7 @@ extern "C" { #include "../libc/include/string.h" #include "arch/i386/tty/kterm.h" } + +#include "arch/i386/idt/idt.h" #include "MMU.h" #include "io.h" -#include "idt.h" -//#include "pic.h" \ No newline at end of file diff --git a/src/kernel/timer.cpp b/src/kernel/timer.cpp new file mode 100644 index 0000000..35a8a4a --- /dev/null +++ b/src/kernel/timer.cpp @@ -0,0 +1,27 @@ +#include "timer.h" + +uint32_t tick = 0; + + +static void timer_callback (registers_t regs ){ + tick ++ ; + kterm_writestring ("tick passed!"); +} + +void init_timer (uint32_t frequency){ + // register timer callback + + uint32_t divisor = 1193180 / frequency; + + // Send the commmand byte + outb(0x43, 0x36); + + // Divisor has to be sent byt-wise , so will send lower then upper bytes + uint8_t low = (uint8_t) (divisor & 0xFF); + uint8_t high = (uint8_t) ((divisor >> 8) & 0xFF); + + outb(0x40, low); + outb(0x40, high); + + +} \ No newline at end of file diff --git a/src/kernel/timer.h b/src/kernel/timer.h new file mode 100644 index 0000000..db8be78 --- /dev/null +++ b/src/kernel/timer.h @@ -0,0 +1,6 @@ +#pragma once + +#include +#include + +void init_timer (uint32_t frequency); \ No newline at end of file From 394882ca2e2f4124a9370a4bbb30c9bb8c7d2c1a Mon Sep 17 00:00:00 2001 From: Nigel Date: Tue, 18 May 2021 21:11:48 +0100 Subject: [PATCH 05/11] Added CMOS time read function, Added cariage return support to kterm --- src/kernel/arch/i386/tty/kterm.c | 105 ++++++++++++++++++++- src/kernel/arch/i386/tty/kterm.h | 10 +- src/kernel/time.h | 151 +++++++++++++++++++++++++++++++ 3 files changed, 261 insertions(+), 5 deletions(-) create mode 100644 src/kernel/time.h diff --git a/src/kernel/arch/i386/tty/kterm.c b/src/kernel/arch/i386/tty/kterm.c index 6dab47f..7ec9ae1 100644 --- a/src/kernel/arch/i386/tty/kterm.c +++ b/src/kernel/arch/i386/tty/kterm.c @@ -62,15 +62,17 @@ void kterm_scrollup(){ } void kterm_put (char c) { - if(++kterm_column == VGA_WIDTH || c == '\n' ) { kterm_column = 0; - if(kterm_row == VGA_HEIGHT-1) { + if(kterm_row == VGA_HEIGHT-1 ) { kterm_scrollup(); } else { kterm_row ++; } - + } + if ( c == '\r'){ + kterm_column = 0; + return; } if(c == '\n') return; @@ -89,3 +91,100 @@ void kterm_writestring(const char* data ){ AS_KERNEL(); kterm_write(data, strlen(data)); } + + +static void itoa (char *buf, int base, int d) { + char *p = buf; + char *p1, *p2; + unsigned long ud = d; + int divisor = 10; + if ( base == 'd' && d < 0){ + *p++ = '-'; + buf++; + ud = -d; + } else if (base == 'x'){ + divisor = 16; + } + + do { + int remainder = ud % divisor; + + *p++ = (remainder < 10 ) ? remainder + '0' : remainder + 'a' -10; + } while(ud /= divisor); + + /*terminate buf*/ + *p =0; + p1 = buf; + p2 = p -1; + + while (p1 < p2) + { + char tmp = *p1; + *p1 = *p2; + *p2 = tmp; + p1++; + p2--; + + } + +} + +void printf ( const char *format, ...) { + + char **arg = (char **)&format; + int c; + char buf[20]; + + arg++; + + while ((c = *format++) != 0){ + if( c != '%') + kterm_put(c); + else{ + char *p, *p2; + int pad0 = 0, pad = 0; + + c = *format++; + if(c =='0'){ + pad0 = 1; + c = *format++; + } + + if ( c >= '0' && c <= '9'){ + pad = c - '0'; + c = *format++; + } + + switch (c) + { + case 'd': + + case 'u': + case 'x': + itoa(buf, c, *((int *) arg++)); + + p = buf; + goto string; + break; + + case 's': + p = *arg++; + if(!p) + p = "(null)"; + + string: + for (p2 = p; *p2; p2++); + for (; p2 < p + pad; p2++) + kterm_put(pad0 ? '0': ' '); + while (*p) + kterm_put(*p++); + break; + + + default: + kterm_put(*((int *)arg++)); + break; + } + } + } +} \ No newline at end of file diff --git a/src/kernel/arch/i386/tty/kterm.h b/src/kernel/arch/i386/tty/kterm.h index f1570c6..d9f704f 100644 --- a/src/kernel/arch/i386/tty/kterm.h +++ b/src/kernel/arch/i386/tty/kterm.h @@ -15,10 +15,16 @@ void kterm_putat(char, uint8_t, size_t, size_t); void kterm_put(char); void kterm_write(const char*, size_t); void kterm_writestring(const char*); - void kterm_scrollup(); + +void printf ( const char *format, ...); + +static void itoa (char *buf, int base, int d); + #define KernelTag "[Kernel]: " #define AS_KERNEL() ( kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\ kterm_write(KernelTag, 10 ), \ - kterm_resetcolor()) \ No newline at end of file + kterm_resetcolor()) + + diff --git a/src/kernel/time.h b/src/kernel/time.h new file mode 100644 index 0000000..6a098b7 --- /dev/null +++ b/src/kernel/time.h @@ -0,0 +1,151 @@ +#define CURRENT_YEAR 2021 // Change this each year! + +int century_register = 0x00; // Set by ACPI table parsing code if possible + +unsigned char second; +unsigned char minute; +unsigned char hour; +unsigned char day; +unsigned char month; +unsigned int year; + + + +enum { + cmos_address = 0x70, + cmos_data = 0x71 +}; + +int get_update_in_progress_flag() { + outb(cmos_address, 0x0A); + return (inb(cmos_data) & 0x80); +} + +unsigned char get_RTC_register(int reg) { + outb(cmos_address, reg); + return inb(cmos_data); +} + +void read_rtc() { + unsigned char century; + unsigned char last_second; + unsigned char last_minute; + unsigned char last_hour; + unsigned char last_day; + unsigned char last_month; + unsigned char last_year; + unsigned char last_century; + unsigned char registerB; + + // Note: This uses the "read registers until you get the same values twice in a row" technique + // to avoid getting dodgy/inconsistent values due to RTC updates + + while (get_update_in_progress_flag()); // Make sure an update isn't in progress + second = get_RTC_register(0x00); + minute = get_RTC_register(0x02); + hour = get_RTC_register(0x04); + day = get_RTC_register(0x07); + month = get_RTC_register(0x08); + year = get_RTC_register(0x09); + if(century_register != 0) { + century = get_RTC_register(century_register); + } + + do { + last_second = second; + last_minute = minute; + last_hour = hour; + last_day = day; + last_month = month; + last_year = year; + last_century = century; + + while (get_update_in_progress_flag()); // Make sure an update isn't in progress + second = get_RTC_register(0x00); + minute = get_RTC_register(0x02); + hour = get_RTC_register(0x04); + day = get_RTC_register(0x07); + month = get_RTC_register(0x08); + year = get_RTC_register(0x09); + if(century_register != 0) { + century = get_RTC_register(century_register); + } + } while( (last_second != second) || (last_minute != minute) || (last_hour != hour) || + (last_day != day) || (last_month != month) || (last_year != year) || + (last_century != century) ); + + registerB = get_RTC_register(0x0B); + + // Convert BCD to binary values if necessary + + if (!(registerB & 0x04)) { + second = (second & 0x0F) + ((second / 16) * 10); + minute = (minute & 0x0F) + ((minute / 16) * 10); + hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80); + day = (day & 0x0F) + ((day / 16) * 10); + month = (month & 0x0F) + ((month / 16) * 10); + year = (year & 0x0F) + ((year / 16) * 10); + if(century_register != 0) { + century = (century & 0x0F) + ((century / 16) * 10); + } + } + + // Convert 12 hour clock to 24 hour clock if necessary + + if (!(registerB & 0x02) && (hour & 0x80)) { + hour = ((hour & 0x7F) + 12) % 24; + } + + // Calculate the full (4-digit) year + + if(century_register != 0) { + year += century * 100; + } else { + year += (CURRENT_YEAR / 100) * 100; + if(year < CURRENT_YEAR) year += 100; + } +} + + +/* +void ReadFromCMOS(unsigned char array[]) +{ + unsigned char tvalue, index; + + for (index = 0; index < 128; index++) + { + asm( + "cli\n\t" // Disable interrupts + "mov al, index\n\t" // Move index address + // since the 0x80 bit of al is not set, NMI is active + "out 0x70,al\n\t" // Copy address to CMOS register + // some kind of real delay here is probably best + "in al,0x71\n\t" // Fetch 1 byte to al + "sti\n\t" // Enable interrupts + "mov tvalue,al\n\t"); + + array[index] = tvalue; + } +} +*/ + +/* +void WriteTOCMOS(unsigned char array[]) +{ + unsigned char index; + + for(index = 0; index < 128; index++) + { + unsigned char tvalue = array[index]; + + asm("cli\n\t" // Clear interrupts + "mov al,index\n\t" // move index address + "out 0x70,al\n\t" // copy address to CMOS register + /* some kind of real delay here is probably best + "mov al,tvalue\n\t" // move value to al + "out 0x71,al\n\t" // write 1 byte to CMOS + "sti\n\\t" ); // Enable interrupts + + } +} +*/ \ No newline at end of file From e0dfa69df8b662d9ab51adb832787be41ab22bcd Mon Sep 17 00:00:00 2001 From: Nigel Date: Tue, 18 May 2021 21:13:14 +0100 Subject: [PATCH 06/11] Removed itoa and printf from idt --- src/kernel/arch/i386/idt/idt.cpp | 97 -------------------------------- src/kernel/arch/i386/idt/idt.h | 9 ++- 2 files changed, 4 insertions(+), 102 deletions(-) diff --git a/src/kernel/arch/i386/idt/idt.cpp b/src/kernel/arch/i386/idt/idt.cpp index d515272..165e7a8 100644 --- a/src/kernel/arch/i386/idt/idt.cpp +++ b/src/kernel/arch/i386/idt/idt.cpp @@ -1,102 +1,5 @@ #include "idt.h" -static void itoa (char *buf, int base, int d) { - char *p = buf; - char *p1, *p2; - unsigned long ud = d; - int divisor = 10; - if ( base == 'd' && d < 0){ - *p++ = '-'; - buf++; - ud = -d; - } else if (base == 'x'){ - divisor = 16; - } - - do { - int remainder = ud % divisor; - - *p++ = (remainder < 10 ) ? remainder + '0' : remainder + 'a' -10; - } while(ud /= divisor); - - /*terminate buf*/ - *p =0; - p1 = buf; - p2 = p -1; - - while (p1 < p2) - { - char tmp = *p1; - *p1 = *p2; - *p2 = tmp; - p1++; - p2--; - - } - -} - -void printf ( const char *format, ...) { - - AS_KERNEL(); - char **arg = (char **)&format; - int c; - char buf[20]; - - arg++; - - while ((c = *format++) != 0){ - if( c != '%') - kterm_put(c); - else{ - char *p, *p2; - int pad0 = 0, pad = 0; - - c = *format++; - if(c =='0'){ - pad0 = 1; - c = *format++; - } - - if ( c >= '0' && c <= '9'){ - pad = c - '0'; - c = *format++; - } - - switch (c) - { - case 'd': - - case 'u': - case 'x': - itoa(buf, c, *((int *) arg++)); - - p = buf; - goto string; - break; - - case 's': - p = *arg++; - if(!p) - p = "(null)"; - - string: - for (p2 = p; *p2; p2++); - for (; p2 < p + pad; p2++) - kterm_put(pad0 ? '0': ' '); - while (*p) - kterm_put(*p++); - break; - - - default: - kterm_put(*((int *)arg++)); - break; - } - } - } -} - IDT_entry idt_table[256]; IDT_ptr idt_ptr; diff --git a/src/kernel/arch/i386/idt/idt.h b/src/kernel/arch/i386/idt/idt.h index 7281fa9..b616b85 100644 --- a/src/kernel/arch/i386/idt/idt.h +++ b/src/kernel/arch/i386/idt/idt.h @@ -3,14 +3,13 @@ #include "stdint.h" #include "stddef.h" #include "../vga/colors.h" -#include "../pic/pic.h"; +#include "../pic/pic.h" +extern "C"{ + #include "../tty/kterm.h" +} #define AS_KERNEL() ( kterm_writestring("[KERNEL]:")) -extern "C" void kterm_writestring(const char* data ); -extern "C" void kterm_putat(char, uint8_t, size_t, size_t); -extern "C" void kterm_put(char); - extern "C" { struct __attribute__((__packed__)) IDT_entry { From 48b65b22768bc1d74d8289033c45e58fc458bd09 Mon Sep 17 00:00:00 2001 From: Nigel Date: Tue, 18 May 2021 21:14:26 +0100 Subject: [PATCH 07/11] Kernel now enter continuous time telling mode --- src/kernel/kernel.cpp | 9 +++++++++ src/kernel/kernel.h | 1 + 2 files changed, 10 insertions(+) diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index edd7f22..1b87e9f 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -144,6 +144,15 @@ extern "C" { asm volatile ("int $4"); + + + while (true){ + // Read time indefinetely + read_rtc(); + printf( "(YY-MM-DD h:mm:ss): %2d-%2d-%2d %2d:%2d:%2d\r" ,year, month, day, hour, minute, second); + delay(1000); + } + /** Lets start using the serial port for debugging .. **/ // Hopefully once we go into realmode or do something that // cause the screen to go black.. this serial comms part will give diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index ced720a..eed09c0 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -7,3 +7,4 @@ extern "C" { #include "arch/i386/idt/idt.h" #include "MMU.h" #include "io.h" +#include "time.h" From 83d220019cbdd7f7ced9c798f3507a0b9dab11dc Mon Sep 17 00:00:00 2001 From: Nigel Date: Sat, 22 May 2021 19:24:29 +0100 Subject: [PATCH 08/11] Nicer time print --- src/kernel/kernel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 1b87e9f..d27944d 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -149,7 +149,7 @@ extern "C" { while (true){ // Read time indefinetely read_rtc(); - printf( "(YY-MM-DD h:mm:ss): %2d-%2d-%2d %2d:%2d:%2d\r" ,year, month, day, hour, minute, second); + printf( "UTC time: %2d-%2d-%2d %2d:%2d:%2d : (YY-MM-DD h:mm:ss)\r" ,year, month, day, hour, minute, second); delay(1000); } From 24a855bb3bb84e90975f9eaddec9d1e95835e7aa Mon Sep 17 00:00:00 2001 From: Nigel Date: Fri, 28 May 2021 22:18:50 +0100 Subject: [PATCH 09/11] Fix up wrong interrupt handler numbers in boot.s --- src/kernel/arch/i386/boot.s | 88 +++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 32 deletions(-) diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s index 17432e4..2de2f8d 100644 --- a/src/kernel/arch/i386/boot.s +++ b/src/kernel/arch/i386/boot.s @@ -273,116 +273,140 @@ irs31: irq0: cli push $0 - push $32 - jmp irs_common + push $0 + jmp irq_common .globl irq1 irq1: cli push $0 - push $33 - jmp irs_common + push $1 + jmp irq_common .globl irq2 irq2: cli push $0 - push $34 - jmp irs_common + push $2 + jmp irq_common .globl irq3 irq3: cli push $0 - push $35 - jmp irs_common + push $3 + jmp irq_common .globl irq4 irq4: cli push $0 - push $36 - jmp irs_common + push $4 + jmp irq_common .globl irq5 irq5: cli push $0 - push $37 - jmp irs_common + push $5 + jmp irq_common .globl irq6 irq6: cli push $0 - push $38 - jmp irs_common + push $6 + jmp irq_common .globl irq7 irq7: cli push $0 - push $39 - jmp irs_common + push $7 + jmp irq_common .globl irq8 irq8: cli push $0 - push $40 - jmp irs_common + push $8 + jmp irq_common .globl irq9 irq9: cli push $0 - push $41 - jmp irs_common + push $9 + jmp irq_common .globl irq10 irq10: cli push $0 - push $42 - jmp irs_common + push $10 + jmp irq_common .globl irq11 irq11: cli push $0 - push $43 - jmp irs_common + push $11 + jmp irq_common .globl irq12 irq12: cli push $0 - push $44 - jmp irs_common + push $12 + jmp irq_common .globl irq13 irq13: cli push $0 - push $45 - jmp irs_common + push $13 + jmp irq_common .globl irq14 irq14: cli push $0 - push $46 - jmp irs_common + push $14 + jmp irq_common .globl irq15 irq15: cli push $0 - push $47 - jmp irs_common + push $15 + jmp irq_common +irq_common: + pusha + mov %ds, %ax + push %eax + + mov $0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + + call irq_handler + + pop %eax + + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + + popa + add $8, %esp # cleans push error and irs code + sti + iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP irs_common: From 04f941a625d225b3edcb5abca860b4047dd73ce8 Mon Sep 17 00:00:00 2001 From: Nigel Date: Fri, 28 May 2021 22:20:13 +0100 Subject: [PATCH 10/11] Kernel now responding to keyboard interrupts --- src/kernel/arch/i386/idt/idt.cpp | 52 ++++++++++++++++++++++++++++++-- src/kernel/kernel.cpp | 9 +++--- 2 files changed, 53 insertions(+), 8 deletions(-) diff --git a/src/kernel/arch/i386/idt/idt.cpp b/src/kernel/arch/i386/idt/idt.cpp index 165e7a8..b81ace6 100644 --- a/src/kernel/arch/i386/idt/idt.cpp +++ b/src/kernel/arch/i386/idt/idt.cpp @@ -1,5 +1,5 @@ #include "idt.h" - +#include "Scancodes.h" IDT_entry idt_table[256]; IDT_ptr idt_ptr; @@ -17,7 +17,7 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){ void irs_handler (registers regs) { kterm_writestring("received interrupt!\n"); - printf(" Interrupt number: %d \n", regs.int_no); + printf("(IRS) Interrupt number: %d \n", regs.int_no); if( regs.int_no == 13){ printf(" Error code: %d \n", regs.err_code); @@ -28,6 +28,52 @@ void irs_handler (registers regs) { +void irq_handler (registers regs) { + + + if ( regs.int_no != 0) { + kterm_writestring("received interrupt!\n"); + printf("(IRQ) Interrupt number: %d \n", regs.int_no); + + } + + if ( regs.int_no == 1 ){ + // Keyboard interrupt !! + + int scan; + register int i; + + // Read scancode + + scan = inb(0x60); + + // Send ack message! + i = inb(0x61); + outb(0x61, i|0x80); + outb(0x61, i); + kterm_writestring("A key was pressed/released\n"); + printf( "Scancode: %x\n", scan); + + + } + + + + outb(0x20, 0x20); // send end of interrupt to master + + if ( regs.int_no > 8 && regs.int_no <= 15) { + outb(0xA0, 0x20); // send end of interrupt to slave + } + + + if( regs.int_no == 13){ + printf(" Error code: %d \n", regs.err_code); + + } + +} + + @@ -39,7 +85,7 @@ void init_idt(){ // TODO: Set everything to zero first - set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8E); + set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8F); set_id_entry(1, (uint32_t) irs1 , 0x08, 0x8E); set_id_entry(2, (uint32_t) irs2 , 0x08, 0x8E); set_id_entry(3, (uint32_t) irs3 , 0x08, 0x8E); diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index d27944d..6764040 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -140,18 +140,17 @@ extern "C" { /** test interrupt handlers **/ - asm volatile ("int $0x03"); + //asm volatile ("int $0x03"); - asm volatile ("int $4"); + //asm volatile ("int $0x04"); - - while (true){ - // Read time indefinetely + //Read time indefinetely read_rtc(); printf( "UTC time: %2d-%2d-%2d %2d:%2d:%2d : (YY-MM-DD h:mm:ss)\r" ,year, month, day, hour, minute, second); delay(1000); } + /** Lets start using the serial port for debugging .. **/ // Hopefully once we go into realmode or do something that From 7409e579c8935accd2c0d076e3963fd6ffa744c2 Mon Sep 17 00:00:00 2001 From: Nigel Date: Wed, 21 Jul 2021 21:31:57 +0100 Subject: [PATCH 11/11] Basic keyboard input --- .../Screenshot from 2021-06-21 14-26-39.png | 3 + src/kernel/arch/i386/idt/idt.cpp | 2 +- src/kernel/arch/i386/idt/scancodes/set1.h | 184 ++++++++++++++++++ 3 files changed, 188 insertions(+), 1 deletion(-) create mode 100644 screenshots/Screenshot from 2021-06-21 14-26-39.png create mode 100644 src/kernel/arch/i386/idt/scancodes/set1.h diff --git a/screenshots/Screenshot from 2021-06-21 14-26-39.png b/screenshots/Screenshot from 2021-06-21 14-26-39.png new file mode 100644 index 0000000..30c104f --- /dev/null +++ b/screenshots/Screenshot from 2021-06-21 14-26-39.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:73b9d3ed540e1bc0b6d55114a00f9aa688006b38a542c1bf048d90b791a748ce +size 141605 diff --git a/src/kernel/arch/i386/idt/idt.cpp b/src/kernel/arch/i386/idt/idt.cpp index b81ace6..4722109 100644 --- a/src/kernel/arch/i386/idt/idt.cpp +++ b/src/kernel/arch/i386/idt/idt.cpp @@ -1,5 +1,5 @@ #include "idt.h" -#include "Scancodes.h" +//#include "scancodes/set1.h" IDT_entry idt_table[256]; IDT_ptr idt_ptr; diff --git a/src/kernel/arch/i386/idt/scancodes/set1.h b/src/kernel/arch/i386/idt/scancodes/set1.h new file mode 100644 index 0000000..2fe6b17 --- /dev/null +++ b/src/kernel/arch/i386/idt/scancodes/set1.h @@ -0,0 +1,184 @@ +#pragma once + + + + + + +// ScanCode set 1 +int ScanCodeToKeyCode [0xD8]; + +/* key pressed scancode */ +ScanCodeToKeyCode[0x01] = 4017; // escape pressed +ScanCodeToKeyCode[0x02] = 4018; // 1 pressed +ScanCodeToKeyCode[0x03] = 4019; // 2 pressed +ScanCodeToKeyCode[0x04] = 4020; // 3 pressed +ScanCodeToKeyCode[0x05] ="" // 4 pressed +ScanCodeToKeyCode[0x06] ="" // 5 pressed +ScanCodeToKeyCode[0x07] ="" // 6 pressed +ScanCodeToKeyCode[0x08] ="" // 7 pressed +ScanCodeToKeyCode[0x09] ="" // 8 pressed +ScanCodeToKeyCode[0x0A] ="" // 9 pressed +ScanCodeToKeyCode[0x0B] ="" // 0 (zero) pressed +ScanCodeToKeyCode[0x0C] ="" // - pressed +ScanCodeToKeyCode[0x0D] ="" // = pressed +ScanCodeToKeyCode[0x0E] ="" // backspace pressed +ScanCodeToKeyCode[0x0F] ="" // tab pressed +ScanCodeToKeyCode[0x10] ="" // Q pressed +ScanCodeToKeyCode[0x11] ="" // W pressed +ScanCodeToKeyCode[0x12] ="" // E pressed +ScanCodeToKeyCode[0x13] ="" // R pressed +ScanCodeToKeyCode[0x14] ="" // T pressed +ScanCodeToKeyCode[0x15] ="" // Y pressed +ScanCodeToKeyCode[0x16] ="" // U pressed +ScanCodeToKeyCode[0x17] ="" // I pressed +ScanCodeToKeyCode[0x18] ="" // O pressed +ScanCodeToKeyCode[0x19] ="" // P pressed +ScanCodeToKeyCode[0x1A] ="" // [ pressed +ScanCodeToKeyCode[0x1B] ="" // ] pressed +ScanCodeToKeyCode[0x1C] ="" // enter pressed +ScanCodeToKeyCode[0x1D] ="" // left control pressed +ScanCodeToKeyCode[0x1E] ="" // A pressed +ScanCodeToKeyCode[0x1F] ="" // S pressed +ScanCodeToKeyCode[0x20] ="" // D pressed +ScanCodeToKeyCode[0x21] ="" // F pressed +ScanCodeToKeyCode[0x22] ="" // G pressed +ScanCodeToKeyCode[0x23] ="" // H pressed +ScanCodeToKeyCode[0x24] ="" // J pressed +ScanCodeToKeyCode[0x25] ="" // K pressed +ScanCodeToKeyCode[0x26] ="" // L pressed +ScanCodeToKeyCode[0x27] ="" // ; pressed +ScanCodeToKeyCode[0x28] ="" // ' (single quote) pressed +ScanCodeToKeyCode[0x29] ="" // ` (back tick) pressed +ScanCodeToKeyCode[0x2A] ="" // left shift pressed +ScanCodeToKeyCode[0x2B] ="" // \ pressed +ScanCodeToKeyCode[0x2C] ="" // Z pressed +ScanCodeToKeyCode[0x2D] ="" // X pressed +ScanCodeToKeyCode[0x2E] ="" // C pressed +ScanCodeToKeyCode[0x2F] ="" // V pressed +ScanCodeToKeyCode[0x30] ="" // B pressed +ScanCodeToKeyCode[0x31] ="" // N pressed +ScanCodeToKeyCode[0x32] ="" // M pressed +ScanCodeToKeyCode[0x33] ="" // , pressed +ScanCodeToKeyCode[0x34] ="" // . pressed +ScanCodeToKeyCode[0x35] ="" // / pressed +ScanCodeToKeyCode[0x36] ="" // right shift pressed +ScanCodeToKeyCode[0x37] ="" // (keypad) * pressed +ScanCodeToKeyCode[0x38] ="" // left alt pressed +ScanCodeToKeyCode[0x39] ="" // space pressed +ScanCodeToKeyCode[0x3A] ="" // CapsLock pressed +ScanCodeToKeyCode[0x3B] ="" // F1 pressed +ScanCodeToKeyCode[0x3C] ="" // F2 pressed +ScanCodeToKeyCode[0x3D] ="" // F3 pressed +ScanCodeToKeyCode[0x3E] ="" // F4 pressed +ScanCodeToKeyCode[0x3F] ="" // F5 pressed +ScanCodeToKeyCode[0x40] ="" // F6 pressed +ScanCodeToKeyCode[0x41] ="" // F7 pressed +ScanCodeToKeyCode[0x42] ="" // F8 pressed +ScanCodeToKeyCode[0x43] ="" // F9 pressed +ScanCodeToKeyCode[0x44] ="" // F10 pressed +ScanCodeToKeyCode[0x45] ="" // NumberLock pressed +ScanCodeToKeyCode[0x46] ="" // ScrollLock pressed +ScanCodeToKeyCode[0x47] ="" // (keypad) 7 pressed +ScanCodeToKeyCode[0x48] ="" // (keypad) 8 pressed +ScanCodeToKeyCode[0x49] ="" // (keypad) 9 pressed +ScanCodeToKeyCode[0x4A] ="" // (keypad) - pressed +ScanCodeToKeyCode[0x4B] ="" // (keypad) 4 pressed +ScanCodeToKeyCode[0x4C] ="" // (keypad) 5 pressed +ScanCodeToKeyCode[0x4D] ="" // (keypad) 6 pressed +ScanCodeToKeyCode[0x4E] ="" // (keypad) + pressed +ScanCodeToKeyCode[0x4F] ="" // (keypad) 1 pressed +ScanCodeToKeyCode[0x50] ="" // (keypad) 2 pressed +ScanCodeToKeyCode[0x51] ="" // (keypad) 3 pressed +ScanCodeToKeyCode[0x52] ="" // (keypad) 0 pressed +ScanCodeToKeyCode[0x53] ="" // (keypad) . pressed +ScanCodeToKeyCode[0x57] ="" // F11 pressed +ScanCodeToKeyCode[0x58] ="" // F12 pressed + + +/* key released scanCode.""*/ +ScanCodeToKeyCode[0x81] ="" // escape released +ScanCodeToKeyCode[0x82] ="" // 1 released +ScanCodeToKeyCode[0x83] ="" // 2 released +ScanCodeToKeyCode[0x84] ="" // 3 released +ScanCodeToKeyCode[0x85] ="" // 4 released +ScanCodeToKeyCode[0x86] ="" // 5 released +ScanCodeToKeyCode[0x87] ="" // 6 released +ScanCodeToKeyCode[0x88] ="" // 7 released +ScanCodeToKeyCode[0x89] ="" // 8 released +ScanCodeToKeyCode[0x8A] ="" // 9 released +ScanCodeToKeyCode[0x8B] ="" // 0 (zero) released +ScanCodeToKeyCode[0x8C] ="" // - released +ScanCodeToKeyCode[0x8D] ="" // = released +ScanCodeToKeyCode[0x8E] ="" // backspace released +ScanCodeToKeyCode[0x8F] ="" // tab released +ScanCodeToKeyCode[0x90] ="" // Q released +ScanCodeToKeyCode[0x91] ="" // W released +ScanCodeToKeyCode[0x92] ="" // E released +ScanCodeToKeyCode[0x93] ="" // R released +ScanCodeToKeyCode[0x94] ="" // T released +ScanCodeToKeyCode[0x95] ="" // Y released +ScanCodeToKeyCode[0x96] ="" // U released +ScanCodeToKeyCode[0x97] ="" // I released +ScanCodeToKeyCode[0x98] ="" // O released +ScanCodeToKeyCode[0x99] ="" // P released +ScanCodeToKeyCode[0x9A] ="" // [ released +ScanCodeToKeyCode[0x9B] ="" // ] released +ScanCodeToKeyCode[0x9C] ="" // enter released +ScanCodeToKeyCode[0x9D] ="" // left control released +ScanCodeToKeyCode[0x9E] ="" // A released +ScanCodeToKeyCode[0x9F] ="" // S released +ScanCodeToKeyCode[0xA0] ="" // D released +ScanCodeToKeyCode[0xA1] ="" // F released +ScanCodeToKeyCode[0xA2] ="" // G released +ScanCodeToKeyCode[0xA3] ="" // H released +ScanCodeToKeyCode[0xA4] ="" // J released +ScanCodeToKeyCode[0xA5] ="" // K released +ScanCodeToKeyCode[0xA6] ="" // L released +ScanCodeToKeyCode[0xA7] ="" // ; released +ScanCodeToKeyCode[0xA8] ="" // ' (single quote) released +ScanCodeToKeyCode[0xA9] ="" // ` (back tick) released +ScanCodeToKeyCode[0xAA] ="" // left shift released +ScanCodeToKeyCode[0xAB] ="" // \ released +ScanCodeToKeyCode[0xAC] ="" // Z released +ScanCodeToKeyCode[0xAD] ="" // X released +ScanCodeToKeyCode[0xAE] ="" // C released +ScanCodeToKeyCode[0xAF] ="" // V released +ScanCodeToKeyCode[0xB0] ="" // B released +ScanCodeToKeyCode[0xB1] ="" // N released +ScanCodeToKeyCode[0xB2] ="" // M released +ScanCodeToKeyCode[0xB3] ="" // , released +ScanCodeToKeyCode[0xB4] ="" // . released +ScanCodeToKeyCode[0xB5] ="" // / released +ScanCodeToKeyCode[0xB6] ="" // right shift released +ScanCodeToKeyCode[0xB7] ="" // (keypad) * released +ScanCodeToKeyCode[0xB8] ="" // left alt released +ScanCodeToKeyCode[0xB9] ="" // space released +ScanCodeToKeyCode[0xBA] ="" // CapsLock released +ScanCodeToKeyCode[0xBB] ="" // F1 released +ScanCodeToKeyCode[0xBC] ="" // F2 released +ScanCodeToKeyCode[0xBD] ="" // F3 released +ScanCodeToKeyCode[0xBE] ="" // F4 released +ScanCodeToKeyCode[0xBF] ="" // F5 released +ScanCodeToKeyCode[0xC0] ="" // F6 released +ScanCodeToKeyCode[0xC1] ="" // F7 released +ScanCodeToKeyCode[0xC2] ="" // F8 released +ScanCodeToKeyCode[0xC3] ="" // F9 released +ScanCodeToKeyCode[0xC4] ="" // F10 released +ScanCodeToKeyCode[0xC5] ="" // NumberLock released +ScanCodeToKeyCode[0xC6] ="" // ScrollLock released +ScanCodeToKeyCode[0xC7] ="" // (keypad) 7 released +ScanCodeToKeyCode[0xC8] ="" // (keypad) 8 released +ScanCodeToKeyCode[0xC9] ="" // (keypad) 9 released +ScanCodeToKeyCode[0xCA] ="" // (keypad) - released +ScanCodeToKeyCode[0xCB] ="" // (keypad) 4 released +ScanCodeToKeyCode[0xCC] ="" // (keypad) 5 released +ScanCodeToKeyCode[0xCD] ="" // (keypad) 6 released +ScanCodeToKeyCode[0xCE] ="" // (keypad) + released +ScanCodeToKeyCode[0xCF] ="" // (keypad) 1 released +ScanCodeToKeyCode[0xD0] ="" // (keypad) 2 released +ScanCodeToKeyCode[0xD1] ="" // (keypad) 3 released +ScanCodeToKeyCode[0xD2] ="" // (keypad) 0 released +ScanCodeToKeyCode[0xD3] ="" // (keypad) . released +ScanCodeToKeyCode[0xD7] ="" // F11 released +ScanCodeToKeyCode[0xD8] ="" // F12 released \ No newline at end of file