KraKern

C++ Kernel
Log | Files | Refs | README | LICENSE | git clone https://git.ne02ptzero.me/git/KraKern

commit 9d464fb8961febe352c44cf741ac10d43c61105d
parent dc7f9fa1c342b799782bca1d04750e45de8af5b4
Author: Ne02ptzero <louis@ne02ptzero.me>
Date:   Thu, 14 Jan 2016 20:28:08 +0100

Fix(IDT): Now working with a keyboard.

Diffstat:
Mboot/x86/GDT.cpp | 14++++++++++++--
Mboot/x86/IDT.cpp | 34++++++++++++++++++++++++++--------
Mboot/x86/x86.asm | 65++++++++++++++++++++++++++++++++---------------------------------
Mincludes/boot/x86.hpp | 29+++++++++++++++++++++++++++++
Mincludes/core/Kernel.hpp | 2++
Aincludes/core/Keyboard.hpp | 147+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mkern.img | 0
Mkernel/Kernel.cpp | 4++++
Akernel/Keyboard.cpp | 45+++++++++++++++++++++++++++++++++++++++++++++
Mkernel/Makefile | 2+-
Mqemu.sh | 2+-
11 files changed, 299 insertions(+), 45 deletions(-)

diff --git a/boot/x86/GDT.cpp b/boot/x86/GDT.cpp @@ -9,9 +9,19 @@ void GDT::init(void) { __kern.io.loading("Global Descriptor Table ..."); this->_init_gdt(); __kern.io.done(); + asm(" movw $0x18, %ax \n \ + movw %ax, %ss \n \ + movl $0x20000, %esp"); + } void GDT::_init_gdt(void) { + struct tss t_default; + + t_default.debug_flag = 0x00; + t_default.io_map = 0x00; + t_default.esp0 = 0x1FFF0; + t_default.ss0 = 0x18; this->_init_gdt_desc(0x0, 0x0, 0x0, 0x0, &this->_gdtdesc[0]); this->_init_gdt_desc(0x0, 0xFFFFF, 0x9B, 0x0D, &this->_gdtdesc[1]); /* code */ this->_init_gdt_desc(0x0, 0xFFFFF, 0x93, 0x0D, &this->_gdtdesc[2]); /* data */ @@ -19,10 +29,10 @@ void GDT::_init_gdt(void) { this->_init_gdt_desc(0x0, 0xFFFFF, 0xFF, 0x0D, &this->_gdtdesc[4]); /* ucode */ this->_init_gdt_desc(0x0, 0xFFFFF, 0xF3, 0x0D, &this->_gdtdesc[5]); /* udata */ this->_init_gdt_desc(0x0, 0x0, 0xF7, 0x0D, &this->_gdtdesc[6]); /* ustack */ - + this->_init_gdt_desc((u32)&t_default, 0x67, 0xE9, 0x00, &this->_gdtdesc[7]); this->_gdtr.limite = GDT_MAX * 8; this->_gdtr.base = GDT_BASE; - memcpy((char *)GDT_BASE, (char *)this->_gdtdesc, this->_gdtr.limite); + memcpy((char *)this->_gdtr.base, (char *)this->_gdtdesc, this->_gdtr.limite); gdtr = this->_gdtr; asm("lgdtl (gdtr)"); asm(" movw $0x10, %ax \n \ diff --git a/boot/x86/IDT.cpp b/boot/x86/IDT.cpp @@ -4,12 +4,30 @@ struct idtr idtr; // Empty functions ATM -extern void _asm_int_0(void) {}; -extern void _asm_int_1(void) {}; -extern void _asm_syscalls(void) {}; -extern void _asm_exc_GP(void) {}; -extern void _asm_exc_PF(void) {}; -extern void _asm_schedule(void) {}; +extern "C" { + + void isr_default_int(int id) { + if (id == 1) + __kern.keyboard.get(); + } + + void do_syscalls(int n) { + (void)n; + //__kern.io.puts("Here !"); + } + + void isr_schedule_int(void) { + //__kern.io.puts("Tick!\n"); + } + + void isr_GP_exc(void) { + __kern.io.panic("Global Panic Fault !"); + } + + void isr_PF_exc(void) { + __kern.io.panic("No authorized memory access !"); + } +}; IDT __idt; @@ -20,10 +38,10 @@ void IDT::init(void) { __kern.io.loading("Programmable Interrupts Controller ..."); this->_init_pic(); __kern.io.done(); + asm("sti"); } void IDT::_init_idt(void) { - // Useless atm. for (int i = 0; i < IDT_SIZE; i++) this->_init_idt_desc(0x08, (u32)_asm_schedule, INT_GATE, &this->_idtdesc[i]); this->_init_idt_desc(0x08, (u32)_asm_exc_GP, INT_GATE, &this->_idtdesc[13]); @@ -34,7 +52,7 @@ void IDT::_init_idt(void) { this->_init_idt_desc(0x08, (u32)_asm_syscalls, TRAP_GATE, &this->_idtdesc[128]); this->_idtr.limite = IDT_SIZE * 8; this->_idtr.base = IDT_BASE; - memcpy((char *)IDT_BASE, (char *)this->_idtdesc, this->_idtr.limite); + memcpy((char *)this->_idtr.base, (char *)this->_idtdesc, this->_idtr.limite); idtr = this->_idtr; asm("lidtl (idtr)"); } diff --git a/boot/x86/x86.asm b/boot/x86/x86.asm @@ -24,51 +24,50 @@ extern isr_default_int, do_syscalls, isr_schedule_int %macro INTERRUPT 1 global _asm_int_%1 _asm_int_%1: - ; SAVE_REGS - ;push %1 - ;call isr_default_int - ;pop eax - ;mov al,0x20 - ;out 0x20,al - ;RESTORE_REGS - ;iret + SAVE_REGS + push %1 + call isr_default_int + pop eax + mov al,0x20 + out 0x20,al + RESTORE_REGS + iret %endmacro extern isr_GP_exc, isr_PF_exc global _asm_syscalls, _asm_exc_GP, _asm_exc_PF _asm_syscalls: - ; SAVE_REGS - ;push eax - ;call do_syscalls - ;pop eax - ;cli - ;sti - ;RESTORE_REGS - ;iret - + SAVE_REGS + push eax + call do_syscalls + pop eax + cli + sti + RESTORE_REGS + iret _asm_exc_GP: - ; SAVE_REGS - ;call isr_GP_exc - ;RESTORE_REGS - ;add esp,4 - ;iret + SAVE_REGS + call isr_GP_exc + RESTORE_REGS + add esp,4 + iret _asm_exc_PF: - ; SAVE_REGS - ;call isr_PF_exc - ;RESTORE_REGS - ;add esp,4 - ;iret + SAVE_REGS + call isr_PF_exc + RESTORE_REGS + add esp,4 + iret global _asm_schedule _asm_schedule: - ; SAVE_REGS - ;call isr_schedule_int - ;mov al,0x20 - ;out 0x20,al - ;RESTORE_REGS - ;iret + SAVE_REGS + call isr_schedule_int + mov al,0x20 + out 0x20,al + RESTORE_REGS + iret INTERRUPT 1 INTERRUPT 2 diff --git a/includes/boot/x86.hpp b/includes/boot/x86.hpp @@ -4,6 +4,15 @@ // ASM functions (x86.asm) +extern "C" { + void _asm_int_0(void); + void _asm_int_1(void); + void _asm_syscalls(void); + void _asm_exc_GP(void); + void _asm_exc_PF(void); + void _asm_schedule(void); +}; + # define INT_GATE 0x8E00 # define TRAP_GATE 0xEF00 @@ -29,6 +38,26 @@ struct gdtdesc { u8 base24_31; } __attribute__ ((packed)); +struct tss { + u16 previous_task, __previous_task_unused; + u32 esp0; + u16 ss0, __ss0_unused; + u32 esp1; + u16 ss1, __ss1_unused; + u32 esp2; + u16 ss2, __ss2_unused; + u32 cr3; + u32 eip, eflags, eax, ecx, edx, ebx, esp, ebp, esi, edi; + u16 es, __es_unused; + u16 cs, __cs_unused; + u16 ss, __ss_unused; + u16 ds, __ds_unused; + u16 fs, __fs_unused; + u16 gs, __gs_unused; + u16 ldt_selector, __ldt_sel_unused; + u16 debug_flag, io_map; +} __attribute__ ((packed)); + class GDT { public: diff --git a/includes/core/Kernel.hpp b/includes/core/Kernel.hpp @@ -6,6 +6,7 @@ # include <x86.hpp> # include <Io.hpp> # include <Memory.hpp> +# include <Keyboard.hpp> class Kernel { public: @@ -18,6 +19,7 @@ class Kernel { GDT gdt; IDT idt; Memory mem; + Keyboard keyboard; }; #endif diff --git a/includes/core/Keyboard.hpp b/includes/core/Keyboard.hpp @@ -0,0 +1,147 @@ +#ifndef __KEYBOARD__ +# define __KEYBOARD__ +# include <os.h> + +class Keyboard { + public: + void init(void); + void get(void); + + private: + u8 _lshift; + u8 _rshift; + u8 _alt; + u8 _ctrl; + char *_map; +}; + +// The following table is all the key. No interest in it. + +extern "C" { + enum { + KEY_TAB = 7, + KEY_BACKSPACE = 8, + KEY_ENTER = 10, + KEY_ESCAPE = 27, + KEY_F1 = 255, + KEY_F2 = 254, + KEY_F3 = 253, + KEY_F4 = 252, + KEY_F5 = 251, + KEY_F6 = 250, + KEY_F7 = 249, + KEY_F8 = 248, + KEY_F9 = 247, + KEY_F10 = 246, + KEY_F11 = 245, + KEY_F12 = 244 + }; +}; + +# ifndef __KERNEL__ + +char kbdmap_default[] = { + KEY_ESCAPE, KEY_ESCAPE, KEY_ESCAPE, KEY_ESCAPE, /* esc (0x01) */ + '1', '!', '1', '1', + '2', '@', '2', '2', + '3', '#', '3', '3', + '4', '$', '4', '4', + '5', '%', '5', '5', + '6', ':', '6', '6', + '7', '&', '7', '7', + '8', '*', '8', '8', + '9', '(', '9', '9', + '0', ')', '0', '0', + '-', '_', '-', '-', + '=', '+', '=', '=', + 0x08, 0x08, 0x7F, 0x08, /* backspace */ + 0x09, 0x09, 0x09, 0x09, /* tab */ + 'a', 'A', 'a', 'a', + 'z', 'Z', 'z', 'z', + 'e', 'E', 'e', 'e', + 'r', 'R', 'r', 'r', + 't', 'T', 't', 't', + 'y', 'Y', 'y', 'y', + 'u', 'U', 'u', 'u', + 'i', 'I', 'i', 'i', + 'o', 'O', 'o', 'o', + 'p', 'P', 'p', 'p', + '^', '"', '^', '^', + '$', '£', ' ', '$', + 0x0A, 0x0A, 0x0A, 0x0A, /* enter */ + 0xFF, 0xFF, 0xFF, 0xFF, /* ctrl */ + 'q', 'Q', 'q', 'q', + 's', 'S', 's', 's', + 'd', 'D', 'd', 'd', + 'f', 'F', 'f', 'f', + 'g', 'G', 'g', 'g', + 'h', 'H', 'h', 'h', + 'j', 'J', 'j', 'j', + 'k', 'K', 'k', 'k', + 'l', 'L', 'l', 'l', + 'm', 'M', 'm', 'm', + 0x27, 0x22, 0x27, 0x27, /* '" */ + '*', '~', '`', '`', /* `~ */ + 0xFF, 0xFF, 0xFF, 0xFF, /* Lshift (0x2a) */ + '<', '>', '\\', '\\', + 'w', 'W', 'w', 'w', + 'x', 'X', 'x', 'x', + 'c', 'C', 'c', 'c', + 'v', 'V', 'v', 'v', + 'b', 'B', 'b', 'b', + 'n', 'N', 'n', 'n', + ',', '?', ',', ',', + 0x2C, 0x3C, 0x2C, 0x2C, /* ,< */ + 0x2E, 0x3E, 0x2E, 0x2E, /* .> */ + 0x2F, 0x3F, 0x2F, 0x2F, /* /? */ + 0xFF, 0xFF, 0xFF, 0xFF, /* Rshift (0x36) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x37) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x38) */ + ' ', ' ', ' ', ' ', /* space */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x3a) */ + KEY_F1, 0xFF, 0xFF, 0xFF, /* (0x3b) */ + KEY_F2, 0xFF, 0xFF, 0xFF, /* (0x3c) */ + KEY_F3, 0xFF, 0xFF, 0xFF, /* (0x3d) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x3e) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x3f) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x40) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x41) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x42) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x43) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x44) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x45) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x46) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x47) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x48) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x49) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x4a) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x4b) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x4c) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x4d) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x4e) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x4f) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x50) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x51) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x52) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x53) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x54) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x55) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x56) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x57) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x58) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x59) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x5a) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x5b) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x5c) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x5d) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x5e) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x5f) */ + 0xFF, 0xFF, 0xFF, 0xFF, /* (0x60) */ + 0xFF, 0xFF, 0xFF, 0xFF /* (0x61) */ +}; + +# endif + +# include <Kernel.hpp> + +#endif diff --git a/kern.img b/kern.img Binary files differ. diff --git a/kernel/Kernel.cpp b/kernel/Kernel.cpp @@ -4,6 +4,7 @@ extern Io __io; extern GDT __gdt; extern IDT __idt; extern Memory __mem; +extern Keyboard __keyboard; Kernel __kern; Kernel::Kernel(void) { @@ -14,12 +15,15 @@ void Kernel::init(multiboot_info *mbi) { this->gdt = __gdt; this->idt = __idt; this->mem = __mem; + this->keyboard = __keyboard; this->io.init(); this->welcome(); this->gdt.init(); this->idt.init(); this->mem.init(mbi->high_mem); + this->keyboard.init(); + while (1); } void Kernel::welcome(void) { diff --git a/kernel/Keyboard.cpp b/kernel/Keyboard.cpp @@ -0,0 +1,45 @@ +# include <Keyboard.hpp> + +Keyboard __keyboard; + +void Keyboard::init(void) { + __kern.io.loading("Keyboard ..."); + this->_lshift = 0; + this->_rshift = 0; + this->_alt = 0; + this->_ctrl = 0; + this->_map = kbdmap_default; + __kern.io.done(); +} + +void Keyboard::get(void) { + u8 i; + + while ((__kern.io.ibyte(0x64) & 0x01) == 0); + i = __kern.io.ibyte(0x60) - 1; + if (i < 0x80) { + switch (i) { + case 0x29: this->_lshift = 1; break; + case 0x35: this->_rshift = 1; break; + case 0x1C: this->_ctrl = 1; break; + case 0x37: this->_alt = 1; break; + default: + if (this->_alt) { + __kern.io.putc(this->_map[i * 4 + 2]); + } else if (this->_rshift || this->_lshift) { + __kern.io.putc(this->_map[i * 4 + 1]); + } else { + __kern.io.putc(this->_map[i * 4]); + } + break; + } + } else { + i -= 0x80; + switch (i) { + case 0x29: this->_lshift = 0; break; + case 0x35: this->_rshift = 0; break; + case 0x1C: this->_ctrl = 0; break; + case 0x37: this->_alt = 0; break; + } + } +} diff --git a/kernel/Makefile b/kernel/Makefile @@ -1 +1 @@ -OBJS += kernel/main.o kernel/Io.o kernel/Kernel.o kernel/Memory.o +OBJS += kernel/main.o kernel/Io.o kernel/Kernel.o kernel/Memory.o kernel/Keyboard.o diff --git a/qemu.sh b/qemu.sh @@ -1,2 +1,2 @@ #!/bin/bash -kvm -m 1024 -s -hda ./kern.img -serial /dev/tty -redir tcp:2323::23 +kvm -m 1024 -s -hda ./kern.img -serial /dev/tty -redir tcp:2323::23 #-curses