From 592db0ebcf787ac33bf2acb317afa04ef65bfce6 Mon Sep 17 00:00:00 2001 From: Nigel Barink Date: Sun, 16 May 2021 15:53:14 +0100 Subject: [PATCH 01/17] 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 02/17] 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 03/17] 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 04/17] 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 05/17] 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 fa67df4bc074ee8a0ca2c146db44d746e937c73a Mon Sep 17 00:00:00 2001 From: Nigel Date: Wed, 26 May 2021 19:51:35 +0100 Subject: [PATCH 06/17] Added an otter logo! I think its so cute --- .gitattributes | 1 + README.md | 262 +++++++++++++++++++++++++++++ images/BarinkOS.png | 3 + images/BarinkOS_logo(standard).svg | 3 + images/BarinkOS_logo.svg | 3 + 5 files changed, 272 insertions(+) create mode 100644 images/BarinkOS.png create mode 100644 images/BarinkOS_logo(standard).svg create mode 100644 images/BarinkOS_logo.svg diff --git a/.gitattributes b/.gitattributes index e5e75fa..12b0908 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1,3 @@ *.pdf filter=lfs diff=lfs merge=lfs -text *.png filter=lfs diff=lfs merge=lfs -text +*.svg filter=lfs diff=lfs merge=lfs -text diff --git a/README.md b/README.md index cf263a6..a809799 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,268 @@ # Writing an Operating system ## As a learning experience! Inspired by people like Linus Torvalds and Andreas Kling + + + + + + + image/svg+xml + + + + + + + BarinkOS + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ________________________ ### Screenshot(s) diff --git a/images/BarinkOS.png b/images/BarinkOS.png new file mode 100644 index 0000000..3f6e913 --- /dev/null +++ b/images/BarinkOS.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c3415fbc124e9a4f621f7aea377c782b56e42f6271bad434b4a3290437571acb +size 23402 diff --git a/images/BarinkOS_logo(standard).svg b/images/BarinkOS_logo(standard).svg new file mode 100644 index 0000000..700d71b --- /dev/null +++ b/images/BarinkOS_logo(standard).svg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9b64404160b415896faae7f3a2521a386162386f3c743cfed36633eb721ad75 +size 15322 diff --git a/images/BarinkOS_logo.svg b/images/BarinkOS_logo.svg new file mode 100644 index 0000000..7c38c24 --- /dev/null +++ b/images/BarinkOS_logo.svg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fe3bc435da5cd4c8244caa71c57a7cfde01b0953be196e731f84d92942d5863f +size 18412 From 8ea45d381858834a0dea8494083a3293bd4ebf63 Mon Sep 17 00:00:00 2001 From: Nigel Date: Wed, 26 May 2021 19:58:27 +0100 Subject: [PATCH 07/17] Adding logo properly to README, hopefully this way it show up in preview on gitea --- README.md | 263 +----------------------------------------------------- 1 file changed, 2 insertions(+), 261 deletions(-) diff --git a/README.md b/README.md index a809799..62625b5 100644 --- a/README.md +++ b/README.md @@ -2,267 +2,8 @@ ## As a learning experience! Inspired by people like Linus Torvalds and Andreas Kling - - - - - - image/svg+xml - - - - - - - BarinkOS - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +![Logo](images/BarinkOS_logo(standard).svg) + ________________________ ### Screenshot(s) From 7616ad40ee6c522eba7d05a5f547c79780f69584 Mon Sep 17 00:00:00 2001 From: Nigel Date: Wed, 26 May 2021 20:03:53 +0100 Subject: [PATCH 08/17] Moving logo to png format gitea doesn't handle svg format, simplified screenshot inclusion in readme --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 62625b5..5383904 100644 --- a/README.md +++ b/README.md @@ -2,11 +2,11 @@ ## As a learning experience! Inspired by people like Linus Torvalds and Andreas Kling -![Logo](images/BarinkOS_logo(standard).svg) +![Logo](images/BarinkOS.png) ________________________ ### Screenshot(s) - +![Scrolling the terminal](screenshots/Screenshot1.png) \ The first scrolling boot screen. 😲 From 24a855bb3bb84e90975f9eaddec9d1e95835e7aa Mon Sep 17 00:00:00 2001 From: Nigel Date: Fri, 28 May 2021 22:18:50 +0100 Subject: [PATCH 09/17] 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/17] 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/17] 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 From f2c8b8ac5ce8dba7fec923e708f324b7ba7e38eb Mon Sep 17 00:00:00 2001 From: Nigel Date: Thu, 22 Jul 2021 20:02:47 +0100 Subject: [PATCH 12/17] Improved multiboot compliance --- .vscode/c_cpp_properties.json | 16 ++ Makefile | 2 +- src/kernel/MMU.cpp | 12 +- src/kernel/MMU.h | 1 + src/kernel/arch/i386/MMU/SlabAllocator.h | 33 +++ src/kernel/arch/i386/boot.s | 11 + src/kernel/arch/i386/tty/kterm.c | 2 +- src/kernel/kernel.cpp | 139 +++++++++--- src/kernel/kernel.h | 4 + src/kernel/multiboot.h | 274 +++++++++++++++++++++++ 10 files changed, 460 insertions(+), 34 deletions(-) create mode 100644 .vscode/c_cpp_properties.json create mode 100644 src/kernel/arch/i386/MMU/SlabAllocator.h create mode 100644 src/kernel/multiboot.h diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..862aed8 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++14", + "intelliSenseMode": "linux-gcc-x64" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/Makefile b/Makefile index aa43673..90aa8cf 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,7 @@ all: clean build build: build_kernel run run: - $(EMULATOR) -d int -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std + $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std build_kernel: $(OBJ_LINK_LIST) diff --git a/src/kernel/MMU.cpp b/src/kernel/MMU.cpp index 96867f4..dfdd9ab 100644 --- a/src/kernel/MMU.cpp +++ b/src/kernel/MMU.cpp @@ -21,9 +21,9 @@ void MMU::enable(){ //we will fill all 1024 entries in the table, mapping 4 megabytes for(unsigned int i = 0; i < 1024; i++) { - // As the address is page aligned, it will always leave 12 bits zeroed. - // Those bits are used by the attributes ;) - first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present. + // As the address is page aligned, it will always leave 12 bits zeroed. + // Those bits are used by the attributes ;) + first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present. } // attributes: supervisor level, read/write, present @@ -32,4 +32,10 @@ void MMU::enable(){ loadPageDirectory(this->page_directory); enablePaging(); +} + + +uint32_t MMU::readTableEntry(int entry){ + return this->page_directory[entry]; + } \ No newline at end of file diff --git a/src/kernel/MMU.h b/src/kernel/MMU.h index cb3b7f8..df65d38 100644 --- a/src/kernel/MMU.h +++ b/src/kernel/MMU.h @@ -7,6 +7,7 @@ extern "C" void enablePaging(); class MMU { public: void enable (); + uint32_t readTableEntry(int); private: uint32_t page_directory[1024] __attribute__((aligned(4096))); diff --git a/src/kernel/arch/i386/MMU/SlabAllocator.h b/src/kernel/arch/i386/MMU/SlabAllocator.h new file mode 100644 index 0000000..b9f00df --- /dev/null +++ b/src/kernel/arch/i386/MMU/SlabAllocator.h @@ -0,0 +1,33 @@ +#pragma once +/** + * We'll need something to this effect to allocate memory in the kernel + * this will hopefully someday implement a full slab allocator + **/ +enum SlabState { + empty, + partial, + full +}; + +class CacheSlab { + const int SlabSize = 4000; + void* start = 0x0; +}; + + +class Allocator { + + public: + Allocator(); + ~Allocator(); + + void* kmalloc( int size ); + void kfree (void* address); + + private: + CacheSlab** _cache; + + + + +}; \ No newline at end of file diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s index 2de2f8d..777501c 100644 --- a/src/kernel/arch/i386/boot.s +++ b/src/kernel/arch/i386/boot.s @@ -471,6 +471,17 @@ _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 + + /*Reset EFLAGS*/ + pushl $0 + popf + + /* push the pointer to the Multiboot information structure*/ + pushl %ebx + + /* push the magic value */ + pushl %eax + call early_main cli load_gdt: diff --git a/src/kernel/arch/i386/tty/kterm.c b/src/kernel/arch/i386/tty/kterm.c index 7ec9ae1..2f2ce6f 100644 --- a/src/kernel/arch/i386/tty/kterm.c +++ b/src/kernel/arch/i386/tty/kterm.c @@ -88,7 +88,7 @@ void kterm_write(const char* data, size_t size) { } void kterm_writestring(const char* data ){ - AS_KERNEL(); + // AS_KERNEL(); kterm_write(data, strlen(data)); } diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 6764040..5087b0e 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -97,20 +97,115 @@ void test_serial(){ extern "C" { - void early_main(){ - - init_serial(); - print_serial("\033[31;42mEarly main called!\n"); - - } - - void kernel_main (void) { - - print_serial("Kernel main called!\n"); - + void early_main(unsigned long magic, unsigned long addr){ /** initialize terminal interface */ kterm_init(); + + multiboot_info_t *mbi; + + if (magic != MULTIBOOT_BOOTLOADER_MAGIC){ + printf("Invalid magic number: 0x%x\n", (unsigned) magic); + return; + } + + /* Set MBI to the addresss of the multiboot information structure*/ + mbi = (multiboot_info_t *) addr; + + /* Print out the flags */ + printf("flags = 0x%x\n", (unsigned) mbi->flags); + + /* Are mem_* valid? */ + if ( CHECK_FLAG(mbi->flags,0)){ + printf("mem_lower = %uKB, mem_upper = %uKB\n"); + } + + /* is boot device valid ? */ + if (CHECK_FLAG (mbi->flags, 1)){ + printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device); + } + + /* is the command line passed? */ + if (CHECK_FLAG ( mbi->flags,2)){ + printf("cmdline = %s\n", (char *) mbi->cmdline); + } + + /* Are mods_* valid? */ + if(CHECK_FLAG ( mbi->flags, 3)){ + multiboot_module_t *mod; + int i; + + printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr); + + for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){ + printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline); + } + } + + /* Bits 4 and 5 are mutually exclusive! */ + if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)){ + printf("Both bits 4 and 5 are set.\n"); + return; + } + + /* Is the symbol table of a.out valid? */ + if (CHECK_FLAG(mbi->flags, 4)){ + multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym); + + printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n", + (unsigned) multiboot_aout_sym->tabsize, + (unsigned) multiboot_aout_sym->strsize, + (unsigned) multiboot_aout_sym->addr); + + } + + /* Is the section header table of ELF valid? */ + if (CHECK_FLAG(mbi->flags, 5)){ + multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec); + + printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n", + (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size, + (unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx); + + } + + + // AAAAAH memory map, Yes please! + /* Are mmap_* valid? */ + if (CHECK_FLAG(mbi->flags, 6)){ + multiboot_memory_map_t *mmap; + + printf("mmap_addr = 0x%x, mmap_length = 0x%x\n", + (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); + + for (mmap = (multiboot_memory_map_t *) mbi->mmap_addr; + (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; + mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){ + + printf( + "size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n", + (unsigned) mmap->size, + (unsigned) (mmap->addr >> 32), + (unsigned) (mmap->addr & 0xffffffff), + (unsigned) (mmap->len >> 32), + (unsigned) (mmap->len & 0xffffffff), + (unsigned) mmap->type); + + } + + } + + /* Draw diagonal blue line */ + if (CHECK_FLAG (mbi->flags, 12)){ + printf("Can draw!"); + } + } + + void kernel_main (void) { + + + init_serial(); + /** Setup the MMU **/ //kterm_writestring("Starting MMU...\n"); @@ -120,24 +215,10 @@ extern "C" { - - /** Wrtite stuff to the screen to test the terminal**/ - kterm_writestring("Hello world!\n"); - kterm_writestring("We got newline support!\n"); - - /** Test scrolling **/ - for(int i=0; i < 5; i++){ - delay(500); - kterm_writestring("We have implemented terminal scrolling!\n"); - } + + - - /** Test objective cpp **/ - kterm_writestring("Testing C++ object support\n"); - auto testObject = Test(); - testObject.printMe(); - - + /** test interrupt handlers **/ //asm volatile ("int $0x03"); @@ -147,7 +228,7 @@ extern "C" { while (true){ //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); + printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second); delay(1000); } diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index eed09c0..a863a97 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -4,7 +4,11 @@ extern "C" { #include "arch/i386/tty/kterm.h" } +#include "multiboot.h" #include "arch/i386/idt/idt.h" #include "MMU.h" #include "io.h" #include "time.h" + + +#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit))) \ No newline at end of file diff --git a/src/kernel/multiboot.h b/src/kernel/multiboot.h new file mode 100644 index 0000000..269cf9b --- /dev/null +++ b/src/kernel/multiboot.h @@ -0,0 +1,274 @@ +/* multiboot.h - Multiboot header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_HEADER_ALIGN 4 + +/* The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000004 + +/* Flags set in the ’flags’ member of the multiboot header. */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* Flags to be set in the ’flags’ member of the multiboot info structure. */ + +/* is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 + +/* is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 + +#ifndef ASM_FILE + +typedef unsigned char multiboot_uint8_t; +typedef unsigned short multiboot_uint16_t; +typedef unsigned int multiboot_uint32_t; +typedef unsigned long long multiboot_uint64_t; + +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + multiboot_uint32_t magic; + + /* Feature flags. */ + multiboot_uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + multiboot_uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + multiboot_uint32_t header_addr; + multiboot_uint32_t load_addr; + multiboot_uint32_t load_end_addr; + multiboot_uint32_t bss_end_addr; + multiboot_uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + multiboot_uint32_t mode_type; + multiboot_uint32_t width; + multiboot_uint32_t height; + multiboot_uint32_t depth; +}; + +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table +{ + multiboot_uint32_t tabsize; + multiboot_uint32_t strsize; + multiboot_uint32_t addr; + multiboot_uint32_t reserved; +}; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; + +/* The section header table for ELF. */ +struct multiboot_elf_section_header_table +{ + multiboot_uint32_t num; + multiboot_uint32_t size; + multiboot_uint32_t addr; + multiboot_uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; + +struct multiboot_info +{ + /* Multiboot info version number */ + multiboot_uint32_t flags; + + /* Available memory from BIOS */ + multiboot_uint32_t mem_lower; + multiboot_uint32_t mem_upper; + + /* "root" partition */ + multiboot_uint32_t boot_device; + + /* Kernel command line */ + multiboot_uint32_t cmdline; + + /* Boot-Module list */ + multiboot_uint32_t mods_count; + multiboot_uint32_t mods_addr; + + union + { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; + + /* Memory Mapping buffer */ + multiboot_uint32_t mmap_length; + multiboot_uint32_t mmap_addr; + + /* Drive Info buffer */ + multiboot_uint32_t drives_length; + multiboot_uint32_t drives_addr; + + /* ROM configuration table */ + multiboot_uint32_t config_table; + + /* Boot Loader Name */ + multiboot_uint32_t boot_loader_name; + + /* APM table */ + multiboot_uint32_t apm_table; + + /* Video */ + multiboot_uint32_t vbe_control_info; + multiboot_uint32_t vbe_mode_info; + multiboot_uint16_t vbe_mode; + multiboot_uint16_t vbe_interface_seg; + multiboot_uint16_t vbe_interface_off; + multiboot_uint16_t vbe_interface_len; + + multiboot_uint64_t framebuffer_addr; + multiboot_uint32_t framebuffer_pitch; + multiboot_uint32_t framebuffer_width; + multiboot_uint32_t framebuffer_height; + multiboot_uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + multiboot_uint8_t framebuffer_type; + union + { + struct + { + multiboot_uint32_t framebuffer_palette_addr; + multiboot_uint16_t framebuffer_palette_num_colors; + }; + struct + { + multiboot_uint8_t framebuffer_red_field_position; + multiboot_uint8_t framebuffer_red_mask_size; + multiboot_uint8_t framebuffer_green_field_position; + multiboot_uint8_t framebuffer_green_mask_size; + multiboot_uint8_t framebuffer_blue_field_position; + multiboot_uint8_t framebuffer_blue_mask_size; + }; + }; +}; +typedef struct multiboot_info multiboot_info_t; + +struct multiboot_color +{ + multiboot_uint8_t red; + multiboot_uint8_t green; + multiboot_uint8_t blue; +}; + +struct multiboot_mmap_entry +{ + multiboot_uint32_t size; + multiboot_uint64_t addr; + multiboot_uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + multiboot_uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_mod_list +{ + /* the memory used goes from bytes ’mod_start’ to ’mod_end-1’ inclusive */ + multiboot_uint32_t mod_start; + multiboot_uint32_t mod_end; + + /* Module command line */ + multiboot_uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + multiboot_uint32_t pad; +}; +typedef struct multiboot_mod_list multiboot_module_t; + +/* APM BIOS info. */ +struct multiboot_apm_info +{ + multiboot_uint16_t version; + multiboot_uint16_t cseg; + multiboot_uint32_t offset; + multiboot_uint16_t cseg_16; + multiboot_uint16_t dseg; + multiboot_uint16_t flags; + multiboot_uint16_t cseg_len; + multiboot_uint16_t cseg_16_len; + multiboot_uint16_t dseg_len; +}; + +#endif /* ! ASM_FILE */ + +#endif /* ! MULTIBOOT_HEADER */ From 643f2d708b98e4db546b2b215751f500c53227f0 Mon Sep 17 00:00:00 2001 From: Nigel Date: Thu, 22 Jul 2021 22:14:58 +0100 Subject: [PATCH 13/17] Added emulator options, Added header for VBE driver, Added CPUID function, Added demodisk.img as drive --- .gitattributes | 1 + .gitignore | 4 +- .vscode/c_cpp_properties.json | 16 ---- Makefile | 2 +- README.md | 9 +-- screenshots/.blank | 0 screenshots/multiboot.png | 3 + src/kernel/arch/i386/idt/idt.cpp | 3 + src/kernel/arch/i386/tty/kterm.c | 43 +++++++++++ src/kernel/arch/i386/tty/kterm.h | 13 +++- src/kernel/arch/i386/vga/VBE.h | 41 ++++++++++ src/kernel/cpu.h | 16 ++++ src/kernel/kernel.cpp | 129 +++---------------------------- src/kernel/kernel.h | 101 +++++++++++++++++++++++- 14 files changed, 236 insertions(+), 145 deletions(-) delete mode 100644 .vscode/c_cpp_properties.json delete mode 100644 screenshots/.blank create mode 100644 screenshots/multiboot.png create mode 100644 src/kernel/arch/i386/vga/VBE.h create mode 100644 src/kernel/cpu.h diff --git a/.gitattributes b/.gitattributes index 12b0908..b2a7b41 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,3 +1,4 @@ *.pdf filter=lfs diff=lfs merge=lfs -text *.png filter=lfs diff=lfs merge=lfs -text *.svg filter=lfs diff=lfs merge=lfs -text +demodisk.img filter=lfs diff=lfs merge=lfs -text diff --git a/.gitignore b/.gitignore index c795b05..a897a63 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -build \ No newline at end of file +build +CON +.vscode diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index 862aed8..0000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,16 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/**" - ], - "defines": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "gnu17", - "cppStandard": "gnu++14", - "intelliSenseMode": "linux-gcc-x64" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/Makefile b/Makefile index 90aa8cf..56af78b 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 -vga std + $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial file:CON -vga std -monitor stdio -display gtk -m 2G -cpu core2duo -drive file=demodisk.img build_kernel: $(OBJ_LINK_LIST) diff --git a/README.md b/README.md index 6aa56a7..bba2564 100644 --- a/README.md +++ b/README.md @@ -10,18 +10,17 @@ ________________________ The first scrolling boot screen. 😲 - +![Interrupt handeling](screenshots/WIP_interruptHandling.png) \ W.I.P - Working on interrupt handling + +![Multiboot integration](screenshots/multiboot.png) \ +Multiboot information can be read by the kernel. ________________________ ### The goal Writing a hobby operating system to better understand the basic building blocks of any operating system. - - - - ________________________ ### Operating System Technical specs/details The operating system can print strings to the diff --git a/screenshots/.blank b/screenshots/.blank deleted file mode 100644 index e69de29..0000000 diff --git a/screenshots/multiboot.png b/screenshots/multiboot.png new file mode 100644 index 0000000..25cf7ff --- /dev/null +++ b/screenshots/multiboot.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:13bb64394a1c4df50f254a7adfeda213a085b5338c44d6f61bbe2221c32e1929 +size 21530 diff --git a/src/kernel/arch/i386/idt/idt.cpp b/src/kernel/arch/i386/idt/idt.cpp index 4722109..4ab65b2 100644 --- a/src/kernel/arch/i386/idt/idt.cpp +++ b/src/kernel/arch/i386/idt/idt.cpp @@ -23,6 +23,9 @@ void irs_handler (registers regs) { printf(" Error code: %d \n", regs.err_code); } + + + } diff --git a/src/kernel/arch/i386/tty/kterm.c b/src/kernel/arch/i386/tty/kterm.c index 2f2ce6f..c7914ee 100644 --- a/src/kernel/arch/i386/tty/kterm.c +++ b/src/kernel/arch/i386/tty/kterm.c @@ -46,6 +46,48 @@ void kterm_putat (char c, uint8_t color, size_t x, size_t y ) { } +void enable_cursor (uint8_t start_cursor , uint8_t end_cursor ){ + outb(0x3D4, 0x0A); + outb(0x3D5, (inb(0x3D5) & 0xC0) | start_cursor); + + outb(0x3D4, 0x0B); + outb(0x3D5, (inb(0x3D5) & 0xE0) | end_cursor); +} + +void disable_cursor() +{ + outb(0x3D4, 0x0A); + outb(0x3D5, 0x20); +} + + +void update_cursor(int x, int y){ + uint16_t pos = y * VGA_WIDTH + x; + + outb(0x3D4, 0x0F); + outb(0x3D5, (uint8_t) (pos & 0xFF)); + outb(0x3D4, 0x0E); + outb(0x3D5, (uint8_t) ((pos >> 8) & 0xFF)); +} + +uint16_t get_cursor_position(){ + uint16_t pos = 0; + outb(0x3D4, 0x0F); + pos |= inb(0x3D5); + outb(0x3D4, 0x0E); + pos |= ((uint16_t) inb(0x3D5)) << 8; + return pos; +} + +int get_cursor_x (uint16_t cursor_pos) { + return cursor_pos % VGA_WIDTH; +} + +int get_cursor_y (uint16_t cursor_pos ) { + return cursor_pos / VGA_WIDTH; +} + + /** * With the help from: @@ -63,6 +105,7 @@ void kterm_scrollup(){ void kterm_put (char c) { if(++kterm_column == VGA_WIDTH || c == '\n' ) { + update_cursor(kterm_column , kterm_row); kterm_column = 0; if(kterm_row == VGA_HEIGHT-1 ) { kterm_scrollup(); diff --git a/src/kernel/arch/i386/tty/kterm.h b/src/kernel/arch/i386/tty/kterm.h index d9f704f..9986b51 100644 --- a/src/kernel/arch/i386/tty/kterm.h +++ b/src/kernel/arch/i386/tty/kterm.h @@ -5,12 +5,14 @@ #include #include "../vga/colors.h" - +#include "../../../io.h" void kterm_init(); +/* Kernel terminal - Colour functions*/ void kterm_resetcolor(); void kterm_setcolor(uint8_t); +/* Kernel terminal - Printing function */ void kterm_putat(char, uint8_t, size_t, size_t); void kterm_put(char); void kterm_write(const char*, size_t); @@ -18,6 +20,15 @@ void kterm_writestring(const char*); void kterm_scrollup(); +/* Kernel terminal - Cursor functions */ +void enable_cursor (uint8_t start_cursor , uint8_t end_cursor ); +void disable_cursor(); +void update_cursor(int x, int y); +uint16_t get_cursor_position(); +int get_cursor_x (uint16_t cursor_pos); +int get_cursor_y (uint16_t cursor_pos); + + void printf ( const char *format, ...); static void itoa (char *buf, int base, int d); diff --git a/src/kernel/arch/i386/vga/VBE.h b/src/kernel/arch/i386/vga/VBE.h new file mode 100644 index 0000000..8b63cd4 --- /dev/null +++ b/src/kernel/arch/i386/vga/VBE.h @@ -0,0 +1,41 @@ + +#define VBE_DISPI_IOPORT_INDEX 0x01CE +#define VBE_DISPI_IOPORT_DATA 0x01CF + +/* VBE index values*/ +#define VBE_DISPI_INDEX_ID 0x0 +#define VBE_DISPI_INDEX_XRES 0x1 +#define VBE_DISPI_INDEX_YRES 0x2 +#define VBE_DISPI_INDEX_BPP 0x3 +#define VBE_DISPI_INDEX_ENABLE 0x4 +#define VBE_DISPI_INDEX_BANK 0x5 +#define VBE_DISPI_INDEX_VIRT_WIDTH 0x6 +#define VBE_DISPI_INDEX_VIRT_HEIGHT 0x7 +#define VBE_DISPI_INDEX_X_OFFSET 0x8 +#define VBE_DISPI_INDEX_Y_OFFSET 0x9 + +/* BGA Version */ +#define VBE_DISPI_ID5 0xB0C5 +#define VBE_DISPI_ID4 0xB0C3 +#define VBE_DISPI_ID3 0xB0C2 +#define VBE_DISPI_ID2 0xB0C1 +#define VBE_DISPI_ID1 0xB0C0 + + +/* BGA BIT DEPTH */ +#define VBE_DISPI_BPP_4 0x04 +#define VBE_DISPI_BPP_8 0x08 +#define VBE_DISPI_BPP_15 0x0F +#define VBE_DISPI_BPP_16 0x10 +#define VBE_DISPI_BPP_24 0x18 +#define VBE_DISPI_BPP_32 0x20 + + + /*unsigned short BGAReadRegister(unsigned short IndexValue){ + // outpw(VBE_DISPI_IOPORT_INDEX, IndexValue); + // return inpw (VBE_DISPI_IOPORT_DATA); + } + + int BGAIsAvailable (){ + return (BGAReadRegister(VBE_DISPI_INDEX_ID) == VBE_DISPI_ID5); + }*/ diff --git a/src/kernel/cpu.h b/src/kernel/cpu.h new file mode 100644 index 0000000..4b90a9e --- /dev/null +++ b/src/kernel/cpu.h @@ -0,0 +1,16 @@ +#include // NOTE: Only available in GCC + + static int get_model(){ + int ebx, unused; + __cpuid(0, unused, ebx, unused, unused); + return ebx; + } + + enum { + CPUID_FEAT_EDX_APIC = 1 << 9 + }; + static int check_apic (){ + unsigned int eax, unused, edx; + __get_cpuid(1, &eax, &unused, &unused, &edx); + return edx & CPUID_FEAT_EDX_APIC; + } diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 5087b0e..df18683 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -1,108 +1,14 @@ #include "kernel.h" -/** - * simple delay function - **/ -void delay(int t){ - volatile int i,j; - for(i=0;iflags, 12)){ printf("Can draw!"); } + + int cpu_model = get_model(); + int local_apic = check_apic(); + printf( "CPU Model: %x, Local APIC: %D\n", cpu_model, local_apic); + } void kernel_main (void) { - init_serial(); - /** Setup the MMU **/ - //kterm_writestring("Starting MMU...\n"); - //auto mmu = MMU(); - //mmu.enable(); - //kterm_writestring("MMU enabled!\n"); - - - - - - - /** test interrupt handlers **/ - //asm volatile ("int $0x03"); - - //asm volatile ("int $0x04"); while (true){ //Read time indefinetely @@ -232,14 +127,8 @@ extern "C" { 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 - // some situational awareness - //Serial serialbus = Serial::init(); - - + + } } diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index a863a97..b9b22bf 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -9,6 +9,105 @@ extern "C" { #include "MMU.h" #include "io.h" #include "time.h" +#include "cpu.h" +#include "arch/i386/vga/VBE.h" +#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit))) -#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit))) \ No newline at end of file + +/* This needs to be moved! */ +/** + * simple delay function + **/ +void delay(int t){ + volatile int i,j; + for(i=0;i Date: Sat, 23 Oct 2021 12:26:15 +0100 Subject: [PATCH 14/17] Added option to create an iso --- .gitignore | 5 +++ Makefile | 23 +++++++++--- src/grub.cfg | 3 ++ src/kernel/bootcheck.h | 73 +++++++++++++++++++++++++++++++++++++ src/kernel/kernel.cpp | 81 ++++++------------------------------------ src/kernel/kernel.h | 3 ++ 6 files changed, 114 insertions(+), 74 deletions(-) create mode 100644 src/grub.cfg create mode 100644 src/kernel/bootcheck.h diff --git a/.gitignore b/.gitignore index a897a63..3ac905f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,8 @@ build CON .vscode +isodir/ +root/ +*.iso +*.img + diff --git a/Makefile b/Makefile index 56af78b..79558ac 100644 --- a/Makefile +++ b/Makefile @@ -19,12 +19,27 @@ OBJ_LINK_LIST = $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(OFILES) $(CRTEND_OBJ) $(CRTN_OBJ) INTERNAL_OBJS = $(CRTI_OBJ) $(OFILES) $(CRTN_OBJ) -all: clean build +all: clean build clean_up -build: build_kernel run +build: build_kernel -run: - $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial file:CON -vga std -monitor stdio -display gtk -m 2G -cpu core2duo -drive file=demodisk.img + + +clean_iso: + if [[ -a isodir/* ]] ; then rm isodir/* -d ; fi + if [ -f barinkOS.iso ] ; then rm barinkOS.iso ; fi + +iso: clean_iso build + mkdir -p isodir/boot/grub + cp build/myos.bin isodir/boot/myos.bin + cp src/grub.cfg isodir/boot/grub/grub.cfg + grub-mkrescue -o barinkOS.iso isodir + +clean_up: + rm build/*.o + +test: + $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial file:CON -vga std -monitor stdio -display gtk -m 2G -cpu core2duo build_kernel: $(OBJ_LINK_LIST) diff --git a/src/grub.cfg b/src/grub.cfg new file mode 100644 index 0000000..40431b9 --- /dev/null +++ b/src/grub.cfg @@ -0,0 +1,3 @@ +menuentry "BarinkOS"{ + multiboot /boot/myos.bin +} diff --git a/src/kernel/bootcheck.h b/src/kernel/bootcheck.h new file mode 100644 index 0000000..21268c0 --- /dev/null +++ b/src/kernel/bootcheck.h @@ -0,0 +1,73 @@ +#pragma once +#include "multiboot.h" +#define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit))) + +extern "C" { + #include "arch/i386/tty/kterm.h" +} + + + +void CheckMBT ( multiboot_info_t* mbt ){ + /* Set MBI to the addresss of the multiboot information structure*/ + multiboot_info_t * mbi = (multiboot_info_t *) mbt; + + /* Print out the flags */ + printf("flags = 0x%x\n", (unsigned) mbi->flags); + + /* Are mem_* valid? */ + if ( CHECK_FLAG(mbi->flags,0)){ + printf("mem_lower = %uKB, mem_upper = %uKB\n"); + } + + /* is boot device valid ? */ + if (CHECK_FLAG (mbi->flags, 1)){ + printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device); + } + + /* is the command line passed? */ + if (CHECK_FLAG ( mbi->flags,2)){ + printf("cmdline = %s\n", (char *) mbi->cmdline); + } + + /* Are mods_* valid? */ + if(CHECK_FLAG ( mbi->flags, 3)){ + multiboot_module_t *mod; + int i; + + printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr); + + for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){ + printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline); + } + } + + /* Bits 4 and 5 are mutually exclusive! */ + if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)){ + printf("Both bits 4 and 5 are set.\n"); + return; + } + + /* Is the symbol table of a.out valid? */ + if (CHECK_FLAG(mbi->flags, 4)){ + multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym); + + printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n", + (unsigned) multiboot_aout_sym->tabsize, + (unsigned) multiboot_aout_sym->strsize, + (unsigned) multiboot_aout_sym->addr); + + } + + /* Is the section header table of ELF valid? */ + if (CHECK_FLAG(mbi->flags, 5)){ + multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec); + + printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n", + (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size, + (unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx); + + } + + +} \ No newline at end of file diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index df18683..6fee847 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -1,92 +1,33 @@ #include "kernel.h" - +#include "arch/i386/gdt/gdtc.h" extern "C" { - multiboot_info_t *mbi; void early_main(unsigned long magic, unsigned long addr){ - /** initialize terminal interface */ kterm_init(); - - - + if (magic != MULTIBOOT_BOOTLOADER_MAGIC){ - printf("Invalid magic number: 0x%x\n", (unsigned) magic); + printf("Invalid magic number: 0x%x\n", magic); return; } - /* Set MBI to the addresss of the multiboot information structure*/ - mbi = (multiboot_info_t *) addr; + CheckMBT( (multiboot_info_t *) addr); - /* Print out the flags */ - printf("flags = 0x%x\n", (unsigned) mbi->flags); - /* Are mem_* valid? */ - if ( CHECK_FLAG(mbi->flags,0)){ - printf("mem_lower = %uKB, mem_upper = %uKB\n"); - } - - /* is boot device valid ? */ - if (CHECK_FLAG (mbi->flags, 1)){ - printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device); - } - - /* is the command line passed? */ - if (CHECK_FLAG ( mbi->flags,2)){ - printf("cmdline = %s\n", (char *) mbi->cmdline); - } - - /* Are mods_* valid? */ - if(CHECK_FLAG ( mbi->flags, 3)){ - multiboot_module_t *mod; - int i; - - printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr); - - for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){ - printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline); - } - } - - /* Bits 4 and 5 are mutually exclusive! */ - if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)){ - printf("Both bits 4 and 5 are set.\n"); - return; - } - - /* Is the symbol table of a.out valid? */ - if (CHECK_FLAG(mbi->flags, 4)){ - multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym); - - printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n", - (unsigned) multiboot_aout_sym->tabsize, - (unsigned) multiboot_aout_sym->strsize, - (unsigned) multiboot_aout_sym->addr); - - } - - /* Is the section header table of ELF valid? */ - if (CHECK_FLAG(mbi->flags, 5)){ - multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec); - - printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n", - (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size, - (unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx); - - } + multiboot_info_t* mbt = (multiboot_info_t*) addr; + // Map the kernel + //initPhysicalMemoryManager(); // AAAAAH memory map, Yes please! /* Are mmap_* valid? */ - if (CHECK_FLAG(mbi->flags, 6)){ - multiboot_memory_map_t *mmap; + if (CHECK_FLAG(mbt->flags, 6)){ + multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr; printf("mmap_addr = 0x%x, mmap_length = 0x%x\n", - (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); + (unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length); - for (mmap = (multiboot_memory_map_t *) mbi->mmap_addr; - (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; - mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){ + for (mmap; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){ printf( "size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n", diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index b9b22bf..51fcb9a 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -2,10 +2,13 @@ extern "C" { #include "../libc/include/string.h" #include "arch/i386/tty/kterm.h" + #include "pmm.h" } #include "multiboot.h" +#include "bootcheck.h" #include "arch/i386/idt/idt.h" + #include "MMU.h" #include "io.h" #include "time.h" From b4b615ae97207c9d672eac399d18dc377f46e4f7 Mon Sep 17 00:00:00 2001 From: Nigel Date: Sat, 23 Oct 2021 12:27:13 +0100 Subject: [PATCH 15/17] Checked off some todo's --- TODO.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/TODO.md b/TODO.md index 662bad3..5f9d63f 100644 --- a/TODO.md +++ b/TODO.md @@ -3,14 +3,14 @@ Setup Cross-Compiler \ Multiboot to kernel \ Printing string to the screen \ - Printing values/numbers to the screen (a.k.k itoa) \ - Extend Multiboot implementation \ + Printing values/numbers to the screen (a.k.k itoa) \ + Extend Multiboot implementation \ Output to serial port \ - Move to protected mode \ - Enabel CMOS clock \ + Move to protected mode \ + Enabel CMOS clock \ Time measurement (PIC &| PIT) \ Detect CPU speed \ - Interrupt / exception system (API) \ + Interrupt / exception system (API) \ Plan your memory map (virtual, and physical) : decide where you want the data to be. \ The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \ @@ -37,4 +37,4 @@ Basic Window server/client \ ## Support for more filesystems if I like the challenge in writing these ... FAT Filesystem \ - EXT2 Filesystem \ \ No newline at end of file + EXT2 Filesystem \ From c9b789ed7b5383b0343df12b07e2694fa1781d11 Mon Sep 17 00:00:00 2001 From: Nigel Date: Tue, 2 Nov 2021 21:03:11 +0100 Subject: [PATCH 16/17] Added a bunch of new stuff no time to figure out what's what, No longer any compiler warnings --- Makefile | 5 +- src/kernel/MMU.cpp | 16 ++-- src/kernel/MMU.h | 19 ++++- src/kernel/arch/i386/boot.s | 6 +- src/kernel/arch/i386/gdt/gdtc.cpp | 6 +- src/kernel/arch/i386/gdt/gdtc.h | 2 +- src/kernel/arch/i386/idt/idt.cpp | 2 +- src/kernel/arch/i386/idt/idt.h | 1 - src/kernel/arch/i386/linker.ld | 8 +- src/kernel/arch/i386/pic/pic.h | 2 +- src/kernel/arch/i386/tty/kterm.c | 5 +- src/kernel/arch/i386/tty/kterm.h | 6 +- src/kernel/bootcheck.h | 2 +- src/kernel/cpu.h | 5 +- src/kernel/disk.h | 17 ++++ src/kernel/io.cpp | 15 ++-- src/kernel/kernel.cpp | 48 ++++++++---- src/kernel/kernel.h | 3 +- src/kernel/pci.cpp | 108 ++++++++++++++++++++++++++ src/kernel/pci.h | 58 ++++++++++++++ src/kernel/pmm.cpp | 1 + src/kernel/pmm.h | 125 ++++++++++++++++++++++++++++++ src/kernel/time.h | 4 +- src/libc/include/string.c | 9 +++ src/libc/include/string.h | 9 +-- 25 files changed, 427 insertions(+), 55 deletions(-) create mode 100644 src/kernel/disk.h create mode 100644 src/kernel/pci.cpp create mode 100644 src/kernel/pci.h create mode 100644 src/kernel/pmm.cpp create mode 100644 src/kernel/pmm.h create mode 100644 src/libc/include/string.c diff --git a/Makefile b/Makefile index 79558ac..1969454 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 $(BUILD_DIR)/pic.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 $(BUILD_DIR)/string.o SRC_DIR = src BUILD_DIR = build @@ -79,3 +79,6 @@ $(BUILD_DIR)/idt.o: $(BUILD_DIR)/pic.o: $(CPP) -c $(SRC_DIR)/kernel/arch/i386/pic/pic.cpp -o $(BUILD_DIR)/pic.o $(CFLAGS) -fno-exceptions -fno-rtti + +$(BUILD_DIR)/string.o: + $(CC) -c $(SRC_DIR)/libc/include/string.c -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99 diff --git a/src/kernel/MMU.cpp b/src/kernel/MMU.cpp index dfdd9ab..58b3023 100644 --- a/src/kernel/MMU.cpp +++ b/src/kernel/MMU.cpp @@ -1,4 +1,5 @@ #include "MMU.h" +#include @@ -34,8 +35,13 @@ void MMU::enable(){ enablePaging(); } - -uint32_t MMU::readTableEntry(int entry){ - return this->page_directory[entry]; - -} \ No newline at end of file +/* +void IdentityPaging(uint32_t *first_pte, vaddr from, int size) +{ + from = from & 0xFFFFF000; // Discard the bits we don't want + for (; size > 0; from += 4096, first_pte++) + { + *first_pte = from | 1; // makr page present. + } +} +*/ diff --git a/src/kernel/MMU.h b/src/kernel/MMU.h index df65d38..69be7a3 100644 --- a/src/kernel/MMU.h +++ b/src/kernel/MMU.h @@ -1,14 +1,27 @@ #pragma once #include -extern "C" void loadPageDirectory (long unsigned int* addr ); +extern "C" void loadPageDirectory (uint32_t* addr ); extern "C" void enablePaging(); +typedef uintptr_t address_t; + + +#define KB 1024 + +static const int MAX_PAGES = 1024 * KB; // 4GB , 4kB/page +static volatile address_t pmem_stack[MAX_PAGES]; +static volatile address_t pmem_stack_top = MAX_PAGES; // top down allocation + + +struct page_directory_entry {}; +struct page_table_entry{}; + + class MMU { public: void enable (); - uint32_t readTableEntry(int); - + private: uint32_t page_directory[1024] __attribute__((aligned(4096))); uint32_t first_page_table[1024] __attribute__((aligned(4096))); diff --git a/src/kernel/arch/i386/boot.s b/src/kernel/arch/i386/boot.s index 777501c..096450a 100644 --- a/src/kernel/arch/i386/boot.s +++ b/src/kernel/arch/i386/boot.s @@ -21,7 +21,6 @@ stack_bottom: stack_top: .section .text - /* * Interupt handlers */ @@ -469,7 +468,7 @@ loadPageDirectory: .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*/ + /* I believe its a high address growing down to lower adress for the stack on x86*/ mov $stack_top, %esp /*Reset EFLAGS*/ @@ -484,6 +483,7 @@ _start: call early_main cli + load_gdt: lgdt gdt @@ -563,4 +563,4 @@ gdt_kdata: .byte 0b10010010 # 1st flags | type flags .byte 0b11001111 # 2nd flags | limit .byte 0x0 # base -gdt_end: \ No newline at end of file +gdt_end: diff --git a/src/kernel/arch/i386/gdt/gdtc.cpp b/src/kernel/arch/i386/gdt/gdtc.cpp index f21e80f..69611c2 100644 --- a/src/kernel/arch/i386/gdt/gdtc.cpp +++ b/src/kernel/arch/i386/gdt/gdtc.cpp @@ -1,5 +1,5 @@ #include "gdtc.h" - +#include "../tty/kterm.h" gdtEntry_t gdt[3]; @@ -18,8 +18,10 @@ void gdtSetGate(int num, uint64_t base, uint64_t limit, uint8_t access, } void setupGdt(){ + + printf("setupGdt is called!"); gdtPointer.limit = (sizeof(gdtEntry_t) * 3) - 1; - gdtPointer.base = &gdt; + gdtPointer.base = &gdt; gdtSetGate(0, 0, 0, 0, 0); gdtSetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); diff --git a/src/kernel/arch/i386/gdt/gdtc.h b/src/kernel/arch/i386/gdt/gdtc.h index 2b34997..4e8140f 100644 --- a/src/kernel/arch/i386/gdt/gdtc.h +++ b/src/kernel/arch/i386/gdt/gdtc.h @@ -1,5 +1,5 @@ #include -extern "c"{ +extern "C"{ typedef struct { uint16_t lLimit; diff --git a/src/kernel/arch/i386/idt/idt.cpp b/src/kernel/arch/i386/idt/idt.cpp index 4ab65b2..3334a3b 100644 --- a/src/kernel/arch/i386/idt/idt.cpp +++ b/src/kernel/arch/i386/idt/idt.cpp @@ -44,7 +44,7 @@ void irq_handler (registers regs) { // Keyboard interrupt !! int scan; - register int i; + /*register*/int i; // Read scancode diff --git a/src/kernel/arch/i386/idt/idt.h b/src/kernel/arch/i386/idt/idt.h index b616b85..cedb1ff 100644 --- a/src/kernel/arch/i386/idt/idt.h +++ b/src/kernel/arch/i386/idt/idt.h @@ -8,7 +8,6 @@ extern "C"{ #include "../tty/kterm.h" } -#define AS_KERNEL() ( kterm_writestring("[KERNEL]:")) extern "C" { diff --git a/src/kernel/arch/i386/linker.ld b/src/kernel/arch/i386/linker.ld index 7292df5..eb1aae8 100644 --- a/src/kernel/arch/i386/linker.ld +++ b/src/kernel/arch/i386/linker.ld @@ -6,10 +6,11 @@ ENTRY(_start) kernel image. */ SECTIONS { + /* Begin putting sections at 1 MiB, a conventional place for kernels to be loaded at by the bootloader. */ . = 1M; - + kernel_begin = .; /* First put the multiboot header, as it is required to be put very early early in the image or the bootloader won't recognize the file format. Next we'll put the .text section. */ @@ -40,4 +41,7 @@ SECTIONS /* The compiler may produce other sections, by default it will put them in a segment with the same name. Simply add stuff here as needed. */ -} \ No newline at end of file + + kernel_end = .; +} + diff --git a/src/kernel/arch/i386/pic/pic.h b/src/kernel/arch/i386/pic/pic.h index 5358f5a..3248187 100644 --- a/src/kernel/arch/i386/pic/pic.h +++ b/src/kernel/arch/i386/pic/pic.h @@ -49,7 +49,7 @@ void PIC_sendEOI (unsigned char irq); } -static uint16_t __pic_get_irq_reg(int ocw3); +//static uint16_t __pic_get_irq_reg(int ocw3); uint16_t pic_get_irr(void); uint16_t pic_get_isr(void); diff --git a/src/kernel/arch/i386/tty/kterm.c b/src/kernel/arch/i386/tty/kterm.c index c7914ee..f4bc957 100644 --- a/src/kernel/arch/i386/tty/kterm.c +++ b/src/kernel/arch/i386/tty/kterm.c @@ -1,4 +1,5 @@ #include "kterm.h" + static const size_t VGA_WIDTH = 80; static const size_t VGA_HEIGHT = 25; @@ -201,8 +202,10 @@ void printf ( const char *format, ...) { switch (c) { case 'd': - + kterm_writestring("Not implemented!!"); + break; case 'u': + break; case 'x': itoa(buf, c, *((int *) arg++)); diff --git a/src/kernel/arch/i386/tty/kterm.h b/src/kernel/arch/i386/tty/kterm.h index 9986b51..b43faa9 100644 --- a/src/kernel/arch/i386/tty/kterm.h +++ b/src/kernel/arch/i386/tty/kterm.h @@ -6,6 +6,10 @@ #include "../vga/colors.h" #include "../../../io.h" + + +#include "./../../../../libc/include/string.h" + void kterm_init(); /* Kernel terminal - Colour functions*/ @@ -31,7 +35,7 @@ int get_cursor_y (uint16_t cursor_pos); void printf ( const char *format, ...); -static void itoa (char *buf, int base, int d); +//static void itoa (char *buf, int base, int d); #define KernelTag "[Kernel]: " #define AS_KERNEL() ( kterm_setcolor(VGA_COLOR_LIGHT_BLUE),\ diff --git a/src/kernel/bootcheck.h b/src/kernel/bootcheck.h index 21268c0..3aef2ed 100644 --- a/src/kernel/bootcheck.h +++ b/src/kernel/bootcheck.h @@ -33,7 +33,7 @@ void CheckMBT ( multiboot_info_t* mbt ){ /* Are mods_* valid? */ if(CHECK_FLAG ( mbi->flags, 3)){ multiboot_module_t *mod; - int i; + uint32_t i; printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr); diff --git a/src/kernel/cpu.h b/src/kernel/cpu.h index 4b90a9e..6e9f95a 100644 --- a/src/kernel/cpu.h +++ b/src/kernel/cpu.h @@ -1,6 +1,6 @@ #include // NOTE: Only available in GCC - - static int get_model(){ +// NOT currently usefull! +/* static int get_model(){ int ebx, unused; __cpuid(0, unused, ebx, unused, unused); return ebx; @@ -14,3 +14,4 @@ __get_cpuid(1, &eax, &unused, &unused, &edx); return edx & CPUID_FEAT_EDX_APIC; } +*/ \ No newline at end of file diff --git a/src/kernel/disk.h b/src/kernel/disk.h new file mode 100644 index 0000000..7ba3925 --- /dev/null +++ b/src/kernel/disk.h @@ -0,0 +1,17 @@ +#pragma once + +// Let's write an ATA PIO | ATA driver for now. Mostly to show that I can in theory interact with a +// storage device + +// PRIMARY_ATA_BUS +// 0x1F0 through 0x1F7 + +// SECONDARY_ATA_BUS +// 0x170 through 0x177 + +#define DEVICE_CONTROL_REGISTER 0x3F6 +#define DEVICE_CONTROL_ALTERNATE 0x376 + + +// IRQ14 Primary bus interrupt +// IRQ15 Secondary bus interrupt diff --git a/src/kernel/io.cpp b/src/kernel/io.cpp index f9ed07d..8a0861c 100644 --- a/src/kernel/io.cpp +++ b/src/kernel/io.cpp @@ -1,19 +1,24 @@ #include "io.h" unsigned char inb_p(unsigned short ){ - + // TODO: implement me! + return 0; } unsigned short inw(unsigned short ){ - +// TODO: implement me! + return 0; } unsigned short inw_p(unsigned short ){ - +// TODO: implement me! + return 0; } unsigned int inl(unsigned short ){ - +// TODO: implement me! + return 0; } unsigned int inl_p(unsigned short ){ - +// TODO: implement me! + return 0; } diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 6fee847..a04f977 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -23,12 +23,21 @@ extern "C" { /* Are mmap_* valid? */ if (CHECK_FLAG(mbt->flags, 6)){ multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr; - + uint32_t memorySizeInBytes = 0; + uint32_t reservedMemoryInBytes = 0; + + printf("mmap_addr = 0x%x, mmap_length = 0x%x\n", (unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length); - for (mmap; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){ - + for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){ + if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){ + memorySizeInBytes += mmap->len; + } else { + reservedMemoryInBytes += mmap->len; + } + + printf( "size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n", (unsigned) mmap->size, @@ -39,37 +48,44 @@ extern "C" { (unsigned) mmap->type); } - + uint32_t memorySizeInGiB = memorySizeInBytes / 1073741824; + + printf("Available Memory: 0x%x bytes, 0x%x GiB\n", memorySizeInBytes, memorySizeInGiB ); + printf("Reserved Memory: 0x%x bytes\n", reservedMemoryInBytes ); } + + + + //int cpu_model = get_model(); + //int local_apic = check_apic(); + //printf( "CPU Model: %x, Local APIC: %D\n", cpu_model, local_apic); + + + /* Setup Paging and memory Managment*/ + //MMU MemoryManagementUnit = MMU(); + //MemoryManagementUnit.enable(); // Warning: Causes triple page fault + //printf("Pages available: %9d\n", pmm_available()); /* Draw diagonal blue line */ - if (CHECK_FLAG (mbi->flags, 12)){ + if (CHECK_FLAG (mbt->flags, 12)){ printf("Can draw!"); } - int cpu_model = get_model(); - int local_apic = check_apic(); - printf( "CPU Model: %x, Local APIC: %D\n", cpu_model, local_apic); + //setupGdt(); + } void kernel_main (void) { init_serial(); - - - - - while (true){ + while (false){ //Read time indefinetely read_rtc(); printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second); delay(1000); } - - - } } diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 51fcb9a..1c968f1 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -1,10 +1,11 @@ #pragma once extern "C" { - #include "../libc/include/string.h" + #include "arch/i386/tty/kterm.h" #include "pmm.h" } +#include "../libc/include/string.h" #include "multiboot.h" #include "bootcheck.h" #include "arch/i386/idt/idt.h" diff --git a/src/kernel/pci.cpp b/src/kernel/pci.cpp new file mode 100644 index 0000000..3f81c29 --- /dev/null +++ b/src/kernel/pci.cpp @@ -0,0 +1,108 @@ +#include "pci.h" + +uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset){ + uint32_t address; + uint32_t lbus = (uint32_t) bus; + uint32_t lslot = (uint32_t) slot; + uint32_t lfunc = (uint32_t) func; + uint16_t tmp = 0; + + /* Create configuration address as per Figure 1 */ + address = (uint32_t) ((lbus << 16) | (lslot << 11) | (lfunc << 8) | (offset & 0xFC) |((uint32_t) 0x80000000) ); + /*write out the address */ + outl(CONFIG_ADDRESS, address); + /* read in the data */ + /* (offset & 2 ) * 8 ) = o will choosse the first word of the 32 bits register*/ + tmp = (uint16_t)((inl(CONFIG_DATA)) >> ((offset & 2) * 8) & 0xFFFF); + return (tmp); +} + +uint16_t CheckVendor (uint8_t bus, uint8_t slot) { + uint16_t vendor, device; + /* + Try and read the first configuration register. Since there ar no + vendors that == 0xFFFF, it must be a non-existent device. + */ + if((vendor = ConfigReadWord(bus, slot, 0,0)) != 0xFFFF) { + device = ConfigReadWord(bus, slot, 0,2); + // Possible read more config values ... + } return (vendor); +} + +void checkDevice (uint8_t bus, uint8_t device ) { + uint8_t function = 0; + + uint16_t vendorID = CheckVendor(bus, device); + if (vendorID == 0xFFFF) { + return; + } + + checkFunction (bus, device, function ); + headerType = getHeaderType(bus, device, function ); + if( (headerType & 0x80) != 0) { + /* It is a multi-function device, so check remaining functions */ + for (function = 1; function < 8; function++){ + if (CheckVendor(bus, device)!= 0xFFFF){ + checkFunction(bus, device, function ); + } + } + } + +} + + +void checkFunction (uint8_t bus, uint8_t device, uint8_t function ){ + uint8_t baseClass; + uint8_t subClass; + uint8_t secondaryBus; + + baseClass = getBaseClass(bus, device, function); + subClass = getSubClass (bus, device, function ); + if ( (baseClass == 0x06) && (subClass == 0x04)){ + secondaryBus = getSecondaryBus(bus,device, function); + checkBus(secondaryBus); + } +} + + +// Brute-force scan +void checkAllBuses (){ + uint16_t bus; + uint8_t device; + + for(bus = 0; bus < 256; bus++){ + for(device = 0; device < 32; device++){ + checkDevice(bus,device); + } + } +} + +// Recursive scan +void checkBus (uint8_t bus){ + uint8_t device; + + for(device = 0; device < 32; device ++){ + checkDevice(bus,device); + } +} + +void checkAllBuses(){ + uint8_t function; + uint8_t bus; + + headerType = getHeaderType(0,0,0); + if ( (headerType & 0x80) == 0 ){ + /* Single PCI host controller */ + checkBus(0); + } else{ + /* Multiple PCI host controllers */ + for (function = 0; function < 8; function++){ + if( CheckVendor(0,0) != 0xFFFF) { + break; + } + bus = function; + checkBus(bus); + } + } + +} \ No newline at end of file diff --git a/src/kernel/pci.h b/src/kernel/pci.h new file mode 100644 index 0000000..93b15ce --- /dev/null +++ b/src/kernel/pci.h @@ -0,0 +1,58 @@ +#pragma once +#include +#include "io.h" +// Configuration Space Access Mechanism #1 +#define CONFIG_ADDRESS 0xCF8 // Configuration adress that is to be accessed +#define CONFIG_DATA 0xCFC // Will do the actual configuration operation + +/* +CONFIG_ADDRESS + +32 bit register + +bit 31 Enable bit (Should CONFIG_DATA be translatedc to configuration cycles) +bit 30 - 24 Reserved +bit 23 - 16 Bus Number (Choose a specific PCI BUS) +bit 15 - 11 Device Number (Selects specific device one the pci bus) +bit 10 - 8 Function Number (Selects a specific function in a device) +bit 7 - 0 Register Offset (Offset in the configuration space of 256 Bytes ) NOTE: lowest two bits will always be zero + +*/ + + +/* +PCI Device structure + +Register offset bits 31-24 bits 23-16 bits 15-8 bits 7-0 +00 00 Device ID <---- Vendor ID <------- +01 04 Status <---- Command <------- +02 08 Class code Sub class Prog IF Revision ID +03 0C BIST Header Type Ltncy Timer Cache line Size +04 10 Base address #0 (BAR0) +05 14 Base address #1 (BAR1) +06 18 Base address #2 (BAR2) +07 1C Base address #3 (BAR3) +08 20 Base address #4 (BAR4) +09 24 Base address #5 (BAR5) +0A 28 Cardbus CIS Pointer +0B 2C Subsystem ID <------ Subsystem Vendor ID <------- +0C 30 Expansion ROM base address +0D 34 Reserved <------- Capabilities Pointer <------ +0E 38 Reserved <------- <-------- <-------- +0F 3C Max ltncy Min Grant Interrupt PIN Interrupt Line + +*/ + + +/* +The idea for now is to support the minimal things necessary to find ATA supported drives + */ + + +// Lets write some boiler plate configuration code + +uint16_t ConfigReadWord (uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset); + +uint16_t CheckVendor (uint8_t bus, uint8_t slot); + +void checkDevice (uint8_t bus, uint8_t device ); \ No newline at end of file diff --git a/src/kernel/pmm.cpp b/src/kernel/pmm.cpp new file mode 100644 index 0000000..4b9d66f --- /dev/null +++ b/src/kernel/pmm.cpp @@ -0,0 +1 @@ +#include "pmm.h" diff --git a/src/kernel/pmm.h b/src/kernel/pmm.h new file mode 100644 index 0000000..7f3265c --- /dev/null +++ b/src/kernel/pmm.h @@ -0,0 +1,125 @@ +#pragma once +#include +// Lets assume we have 2 gigabytes of memory +// NOTE: We should really detect how much memory we have +#define KiloByte 1024 // bytes +#define MegaByte 1048576 // bytes +#define GigaByte 1073741824 // bytes +#define MemorySize 2147483648 // bytes + +const uint32_t bitmapSize = MemorySize / 8; + +extern void *kernel_begin; +extern void *kernel_end; +struct __attribute__((packed)) PMSegment { + void* address; + uint32_t size; + PMSegment* Next; +}; + + +static PMSegment pmStart; +static uint32_t AvailablePhysicalMemory; +static uint32_t AllocatedMemorySize; + +void initPhysicalMemoryManager(){ + AvailablePhysicalMemory = MemorySize; + AllocatedMemorySize = 0; + + // Map the kernel + PMSegment KernelSegment = PMSegment(); + printf("end of kernel: 0x%x\n", &kernel_end); + printf("start of kernel: 0x%x\n", &kernel_begin); + printf("pointer to kernel: 0x%x\n", &KernelSegment); + + pmStart = KernelSegment; + KernelSegment.address = kernel_begin; + KernelSegment.size = &kernel_end - &kernel_begin; + AllocatedMemorySize += KernelSegment.size; + KernelSegment.Next = 0; + + // make sure We allocate space for ourselves + /*PMSegment start = PMSegment(); + start.address = KernelSegment.address + KernelSegment.size ; + start.size = (MemorySize / sizeof(PMSegment) ) + sizeof (uint32_t) * 2; + */ + + //KernelSegment.Next = &start; + //AllocatedMemorySize += start.size; +} + +void printMemorySegments() +{ + printf("Memory Segments:\n"); + printf( "Start Segment: [addr: 0x%x, size: 0x%x, Next: 0x%x]\n" ,pmStart.address, pmStart.size, pmStart.Next); + printf("----------------------------\n"); +} + + +void pmem_free (void* address){ + + PMSegment* before = 0; + PMSegment* current = &pmStart; + + printf("Address of pmStart : 0x%x\n", pmStart); + printf("Looking for segment with address: 0x%x \n", address ); + printf("Address of pmStart(a.k.a current) : 0x%x \n", current); + while( current ) + { + //printf("address of current segment 0x%x\n", current->address ); + if ( current->address == address ) { + // this is the address we want to free + printf("Segment found!! Segment address: 0x%x \n", current->address); + if ( current->Next && before ){ + before->Next = current->Next; + }else{ + before->Next = 0; + } + // TODO: Clean memory [ Something like memset to zeroes] + printf("Removing segment of size: 0x%x\n", current->size); + AllocatedMemorySize -= current->size; + break; + } + + before = current; + current = current->Next; + + } + +} + +void* pmem_alloc ( uint32_t size ){ + // Get the last segment + PMSegment* lastSegment = &pmStart; + + while (lastSegment ) { + if( lastSegment->Next == 0){ + break; + } + lastSegment = lastSegment->Next; + } + + printf("LastSegment is for address: 0x%x\n", lastSegment->address); + + + // So now we have the last segment available + PMSegment newSegment = PMSegment(); + newSegment.address = (PMSegment*)((uint32_t)lastSegment->address + lastSegment->size +1); + + printf("NewSegment for Address: 0x%x\n", newSegment.address); + + newSegment.size = size; + + lastSegment->Next = &newSegment; + + if ( AllocatedMemorySize + newSegment.size > AvailablePhysicalMemory){ + // No segment available of this size + /// ERROR!! + return 0; + } + AllocatedMemorySize += newSegment.size; + + return newSegment.address; + + +} \ No newline at end of file diff --git a/src/kernel/time.h b/src/kernel/time.h index 6a098b7..c301bc8 100644 --- a/src/kernel/time.h +++ b/src/kernel/time.h @@ -49,6 +49,8 @@ void read_rtc() { year = get_RTC_register(0x09); if(century_register != 0) { century = get_RTC_register(century_register); + } else { + century = 21; } do { @@ -141,7 +143,7 @@ void WriteTOCMOS(unsigned char array[]) 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 + // 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 diff --git a/src/libc/include/string.c b/src/libc/include/string.c new file mode 100644 index 0000000..60b96b8 --- /dev/null +++ b/src/libc/include/string.c @@ -0,0 +1,9 @@ +#include "string.h" + +size_t strlen(const char* str) { + size_t len = 0; + while(str[len]){ + len++; + } + return len; +} \ No newline at end of file diff --git a/src/libc/include/string.h b/src/libc/include/string.h index 579c72a..90329e9 100644 --- a/src/libc/include/string.h +++ b/src/libc/include/string.h @@ -1,8 +1,3 @@ +#pragma once #include -size_t strlen(const char* str){ - size_t len = 0; - while(str[len]){ - len++; - } - return len; -} \ No newline at end of file +size_t strlen(const char* str); From bdcf9e66f82945c9d0bd9f1bcbd78bc0d1eb016b Mon Sep 17 00:00:00 2001 From: Nigel Date: Tue, 2 Nov 2021 21:15:00 +0100 Subject: [PATCH 17/17] Small adjustment in directory structure of memory and bootloader files in kernel --- Makefile | 6 +- src/kernel/bootcheck.h | 2 +- src/kernel/{ => bootloader}/multiboot.h | 0 src/kernel/kernel.h | 5 +- .../{MMU.cpp => memory/PageDirectory.cpp} | 4 +- src/kernel/{MMU.h => memory/PageDirectory.h} | 2 +- src/kernel/memory/PageFramAllocator.cpp | 1 + src/kernel/memory/PageFrameAllocator.h | 8 ++ .../{arch/i386/MMU => memory}/SlabAllocator.h | 0 src/kernel/pmm.cpp | 1 - src/kernel/pmm.h | 125 ------------------ 11 files changed, 17 insertions(+), 137 deletions(-) rename src/kernel/{ => bootloader}/multiboot.h (100%) rename src/kernel/{MMU.cpp => memory/PageDirectory.cpp} (95%) rename src/kernel/{MMU.h => memory/PageDirectory.h} (96%) create mode 100644 src/kernel/memory/PageFramAllocator.cpp create mode 100644 src/kernel/memory/PageFrameAllocator.h rename src/kernel/{arch/i386/MMU => memory}/SlabAllocator.h (100%) delete mode 100644 src/kernel/pmm.cpp delete mode 100644 src/kernel/pmm.h diff --git a/Makefile b/Makefile index 1969454..da1419f 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 $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o +OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/io.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o SRC_DIR = src BUILD_DIR = build @@ -71,8 +71,8 @@ $(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)/PageDirectory.o: + $(CPP) -c $(SRC_DIR)/kernel/memory/PageDirectory.cpp -o $(BUILD_DIR)/PageDirectory.o $(CFLAGS) -fno-exceptions -fno-rtti $(BUILD_DIR)/idt.o: $(CPP) -c $(SRC_DIR)/kernel/arch/i386/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti diff --git a/src/kernel/bootcheck.h b/src/kernel/bootcheck.h index 3aef2ed..890c4f8 100644 --- a/src/kernel/bootcheck.h +++ b/src/kernel/bootcheck.h @@ -1,5 +1,5 @@ #pragma once -#include "multiboot.h" +#include "bootloader/multiboot.h" #define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit))) extern "C" { diff --git a/src/kernel/multiboot.h b/src/kernel/bootloader/multiboot.h similarity index 100% rename from src/kernel/multiboot.h rename to src/kernel/bootloader/multiboot.h diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 1c968f1..445e8fa 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -1,16 +1,13 @@ #pragma once extern "C" { - #include "arch/i386/tty/kterm.h" - #include "pmm.h" } #include "../libc/include/string.h" -#include "multiboot.h" +#include "./bootloader/multiboot.h" #include "bootcheck.h" #include "arch/i386/idt/idt.h" -#include "MMU.h" #include "io.h" #include "time.h" #include "cpu.h" diff --git a/src/kernel/MMU.cpp b/src/kernel/memory/PageDirectory.cpp similarity index 95% rename from src/kernel/MMU.cpp rename to src/kernel/memory/PageDirectory.cpp index 58b3023..ca7a6d5 100644 --- a/src/kernel/MMU.cpp +++ b/src/kernel/memory/PageDirectory.cpp @@ -1,9 +1,9 @@ -#include "MMU.h" +#include "PageDirectory.h" #include -void MMU::enable(){ +void PageDirectory::enable(){ //set each entry to not present int i; diff --git a/src/kernel/MMU.h b/src/kernel/memory/PageDirectory.h similarity index 96% rename from src/kernel/MMU.h rename to src/kernel/memory/PageDirectory.h index 69be7a3..a2863d3 100644 --- a/src/kernel/MMU.h +++ b/src/kernel/memory/PageDirectory.h @@ -18,7 +18,7 @@ struct page_table_entry{}; -class MMU { +class PageDirectory { public: void enable (); diff --git a/src/kernel/memory/PageFramAllocator.cpp b/src/kernel/memory/PageFramAllocator.cpp new file mode 100644 index 0000000..b690689 --- /dev/null +++ b/src/kernel/memory/PageFramAllocator.cpp @@ -0,0 +1 @@ +#include "PageFrameAllocator.h" diff --git a/src/kernel/memory/PageFrameAllocator.h b/src/kernel/memory/PageFrameAllocator.h new file mode 100644 index 0000000..56d4871 --- /dev/null +++ b/src/kernel/memory/PageFrameAllocator.h @@ -0,0 +1,8 @@ +#pragma once +#include + + + +extern void *kernel_begin; +extern void *kernel_end; + diff --git a/src/kernel/arch/i386/MMU/SlabAllocator.h b/src/kernel/memory/SlabAllocator.h similarity index 100% rename from src/kernel/arch/i386/MMU/SlabAllocator.h rename to src/kernel/memory/SlabAllocator.h diff --git a/src/kernel/pmm.cpp b/src/kernel/pmm.cpp deleted file mode 100644 index 4b9d66f..0000000 --- a/src/kernel/pmm.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "pmm.h" diff --git a/src/kernel/pmm.h b/src/kernel/pmm.h deleted file mode 100644 index 7f3265c..0000000 --- a/src/kernel/pmm.h +++ /dev/null @@ -1,125 +0,0 @@ -#pragma once -#include -// Lets assume we have 2 gigabytes of memory -// NOTE: We should really detect how much memory we have -#define KiloByte 1024 // bytes -#define MegaByte 1048576 // bytes -#define GigaByte 1073741824 // bytes -#define MemorySize 2147483648 // bytes - -const uint32_t bitmapSize = MemorySize / 8; - -extern void *kernel_begin; -extern void *kernel_end; -struct __attribute__((packed)) PMSegment { - void* address; - uint32_t size; - PMSegment* Next; -}; - - -static PMSegment pmStart; -static uint32_t AvailablePhysicalMemory; -static uint32_t AllocatedMemorySize; - -void initPhysicalMemoryManager(){ - AvailablePhysicalMemory = MemorySize; - AllocatedMemorySize = 0; - - // Map the kernel - PMSegment KernelSegment = PMSegment(); - printf("end of kernel: 0x%x\n", &kernel_end); - printf("start of kernel: 0x%x\n", &kernel_begin); - printf("pointer to kernel: 0x%x\n", &KernelSegment); - - pmStart = KernelSegment; - KernelSegment.address = kernel_begin; - KernelSegment.size = &kernel_end - &kernel_begin; - AllocatedMemorySize += KernelSegment.size; - KernelSegment.Next = 0; - - // make sure We allocate space for ourselves - /*PMSegment start = PMSegment(); - start.address = KernelSegment.address + KernelSegment.size ; - start.size = (MemorySize / sizeof(PMSegment) ) + sizeof (uint32_t) * 2; - */ - - //KernelSegment.Next = &start; - //AllocatedMemorySize += start.size; -} - -void printMemorySegments() -{ - printf("Memory Segments:\n"); - printf( "Start Segment: [addr: 0x%x, size: 0x%x, Next: 0x%x]\n" ,pmStart.address, pmStart.size, pmStart.Next); - printf("----------------------------\n"); -} - - -void pmem_free (void* address){ - - PMSegment* before = 0; - PMSegment* current = &pmStart; - - printf("Address of pmStart : 0x%x\n", pmStart); - printf("Looking for segment with address: 0x%x \n", address ); - printf("Address of pmStart(a.k.a current) : 0x%x \n", current); - while( current ) - { - //printf("address of current segment 0x%x\n", current->address ); - if ( current->address == address ) { - // this is the address we want to free - printf("Segment found!! Segment address: 0x%x \n", current->address); - if ( current->Next && before ){ - before->Next = current->Next; - }else{ - before->Next = 0; - } - // TODO: Clean memory [ Something like memset to zeroes] - printf("Removing segment of size: 0x%x\n", current->size); - AllocatedMemorySize -= current->size; - break; - } - - before = current; - current = current->Next; - - } - -} - -void* pmem_alloc ( uint32_t size ){ - // Get the last segment - PMSegment* lastSegment = &pmStart; - - while (lastSegment ) { - if( lastSegment->Next == 0){ - break; - } - lastSegment = lastSegment->Next; - } - - printf("LastSegment is for address: 0x%x\n", lastSegment->address); - - - // So now we have the last segment available - PMSegment newSegment = PMSegment(); - newSegment.address = (PMSegment*)((uint32_t)lastSegment->address + lastSegment->size +1); - - printf("NewSegment for Address: 0x%x\n", newSegment.address); - - newSegment.size = size; - - lastSegment->Next = &newSegment; - - if ( AllocatedMemorySize + newSegment.size > AvailablePhysicalMemory){ - // No segment available of this size - /// ERROR!! - return 0; - } - AllocatedMemorySize += newSegment.size; - - return newSegment.address; - - -} \ No newline at end of file