diff --git a/Makefile b/Makefile index ffcb765..34379a1 100644 --- a/Makefile +++ b/Makefile @@ -94,6 +94,7 @@ KernSources = libbuf/buf.c libbuf/bputc.c libbuf/bscroll.c \ kernel/mm/heap.c kernel/mm/malloc.c \ kernel/mm/gdt.c kernel/ps/sched.c \ kernel/init/info.c kernel/init/ssp.c \ + kernel/io/rtc.c kernel/io/keyb.c LibCObj=$(patsubst %.c,$(KOBJDIR)/%.o,$(LibCSources)) @@ -119,7 +120,7 @@ $(KOBJDIR)/libc/atoi.o: $(KALEIDDIR)/libc/atoi.c $(INCLUDEDIR)/*/*.h | $(KOBJDIR @$(KCC) -D_NEED_ATOL $< -o $@.2 @$(KCC) -D_NEED_ATOU $< -o $@.3 @$(KCC) -D_NEED_ATOUL $< -o $@.4 - @$(LD) -r $@.1 $@.2 $@.3 $@.4 -o $@ + @$(LD) $(LDFLAGS) -r $@.1 $@.2 $@.3 $@.4 -o $@ @rm -f $@.1 $@.2 $@.3 $@.4 @echo ${CL2}[$@] ${CL}Compiled.${CL3} @@ -129,7 +130,7 @@ $(KOBJDIR)/libc/itoa.o: $(KALEIDDIR)/libc/itoa.c $(INCLUDEDIR)/*/*.h | $(KOBJDIR @$(KCC) -D_NEED_LTOA $< -o $@.2 @$(KCC) -D_NEED_UTOA $< -o $@.3 @$(KCC) -D_NEED_ULTOA $< -o $@.4 - @$(LD) -r $@.1 $@.2 $@.3 $@.4 -o $@ + @$(LD) $(LDFLAGS) -r $@.1 $@.2 $@.3 $@.4 -o $@ @rm -f $@.1 $@.2 $@.3 $@.4 @echo ${CL2}[$@] ${CL}Compiled.${CL3} @@ -138,6 +139,33 @@ $(KOBJDIR)/libc/mem.o: $(KALEIDDIR)/libc/mem.c $(INCLUDEDIR)/*/*.h | $(KOBJDIR) @$(KCC) -fno-strict-aliasing $< -o $@ @echo ${CL2}[$@] ${CL}Compiled.${CL3} +$(KOBJDIR)/kernel/cpu/idt.o: $(KALEIDDIR)/kernel/cpu/idt.c \ + $(KALEIDDIR)/kernel/cpu/isr.asm $(INCLUDEDIR)/*/*.h | $(KOBJDIR) + @mkdir -p $(shell dirname $@) + @$(ASM) $(ASMFLAGS) $(KALEIDDIR)/kernel/cpu/isr.asm -o $@.1 + @$(KCC) $< -o $@.2 + @$(LD) $(LDFLAGS) -r $@.1 $@.2 -o $@ + @rm -f $@.1 $@.2 + @echo ${CL2}[$@] ${CL}Compiled.${CL3} + +$(KOBJDIR)/kernel/io/keyb.o: $(KALEIDDIR)/kernel/io/keyb.c \ + $(KALEIDDIR)/kernel/io/keyb.asm $(INCLUDEDIR)/*/*.h | $(KOBJDIR) + @mkdir -p $(shell dirname $@) + @$(ASM) $(ASMFLAGS) $(KALEIDDIR)/kernel/io/keyb.asm -o $@.1 + @$(KCC) $< -o $@.2 + @$(LD) $(LDFLAGS) -r $@.1 $@.2 -o $@ + @rm -f $@.1 $@.2 + @echo ${CL2}[$@] ${CL}Compiled.${CL3} + +$(KOBJDIR)/kernel/io/rtc.o: $(KALEIDDIR)/kernel/io/rtc.c \ + $(KALEIDDIR)/kernel/io/rtc.asm $(INCLUDEDIR)/*/*.h | $(KOBJDIR) + @mkdir -p $(shell dirname $@) + @$(ASM) $(ASMFLAGS) $(KALEIDDIR)/kernel/io/rtc.asm -o $@.1 + @$(KCC) $< -o $@.2 + @$(LD) $(LDFLAGS) -r $@.1 $@.2 -o $@ + @rm -f $@.1 $@.2 + @echo ${CL2}[$@] ${CL}Compiled.${CL3} + ## MAIN MAKEFILE ------------------------------------------------------------- # $(KOBJDIR)/%.o: %.c $(INCLUDEDIR)/*/*.h | $(KOBJDIR) @@ -160,7 +188,7 @@ debug: all gdb: all @qemu-system-x86_64 -m 64M -hda $(BUILDDIR)/bin/disk.img -no-reboot \ - -no-shutdown -d cpu_reset,guest_errors,pcall,int -s 2> $(BUILDDIR)/qemu.log & + -no-shutdown -d cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log & @ndisasm $(BINDIR)/kaleid -o 0x00100000 -b 64 > kaleid64_disasm.asm @ndisasm $(BINDIR)/kaleid -o 0x00100000 -b 32 > kaleid32_disasm.asm @gdb \ @@ -169,6 +197,13 @@ gdb: all -ex "symbol-file $(BINDIR)/kaleid" \ -ex "break BtStartKern" \ +ddd: all + @qemu-system-x86_64 -m 64M -hda $(BUILDDIR)/bin/disk.img -no-reboot \ + -no-shutdown -d cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log & + @ndisasm $(BINDIR)/kaleid -o 0x00100000 -b 64 > kaleid64_disasm.asm + @ndisasm $(BINDIR)/kaleid -o 0x00100000 -b 32 > kaleid32_disasm.asm + @ddd + install_mbr: $(BINDIR)/disk.img $(MBRDIR)/grub.cfg @mkdir -p $(BINDIR)/disk @echo ${CL2}[$@] ${NC}Installing MBR on image...${CL3} diff --git a/ProjectTree b/ProjectTree index f8fa114..c992fb1 100644 --- a/ProjectTree +++ b/ProjectTree @@ -132,8 +132,11 @@ │   │   └── prog.c │   ├── kernel │   │   ├── cpu +│   │   │   ├── cpu.asm │   │   │   ├── cpuid.c -│   │   │   └── idt.c +│   │   │   ├── idt.c +│   │   │   ├── isr.asm +│   │   │   └── isr.inc │   │   ├── init │   │   │   ├── info.c │   │   │   ├── init.c @@ -174,4 +177,4 @@ ├── ProjectTree └── README.md -37 directories, 112 files +37 directories, 115 files diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 2b87b3f..001d524 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -172,6 +172,7 @@ _loader64: mov qword [newKernelEnd], KERNEL_STACK mov rdi, [mbInfo] mov rsi, [mbMagic] + mov rdx, GDT64.code call BtStartKern ;; We must never reach this point ------------------------------------------- ;; diff --git a/include/kernel/base.h b/include/kernel/base.h index 3669e93..2fbec68 100644 --- a/include/kernel/base.h +++ b/include/kernel/base.h @@ -43,6 +43,7 @@ typedef struct BootInfo_t BootInfo_t; typedef struct ListHead_t ListHead_t; typedef struct ListNode_t ListNode_t; typedef struct Processor_t Processor_t; +typedef struct IRQList_t IRQList_t; typedef enum ProcState_t ProcState_t; diff --git a/include/kernel/boot.h b/include/kernel/boot.h index f59f332..6be8bef 100644 --- a/include/kernel/boot.h +++ b/include/kernel/boot.h @@ -46,6 +46,7 @@ struct BootInfo_t void *modulesAddr; //mods_addr char *grubName; //boot_loader_name void *kernelAddr; + void *codeSegment; void *kernelEndAddr; } btldr; diff --git a/include/kernel/cpu.h b/include/kernel/cpuid.h similarity index 90% rename from include/kernel/cpu.h rename to include/kernel/cpuid.h index b5f7963..ea63172 100644 --- a/include/kernel/cpu.h +++ b/include/kernel/cpuid.h @@ -1,7 +1,7 @@ //----------------------------------------------------------------------------// // GNU GPL OS/K // // // -// Desc: CPU related functions // +// Desc: CPUID related functions // // // // // // Copyright © 2018-2019 The OS/K Team // @@ -26,8 +26,12 @@ #include #endif -#ifndef _KALKERN_CPU_H -#define _KALKERN_CPU_H +#ifndef _KALKERN_CPUID_H +#define _KALKERN_CPUID_H + +// -------------------------------------------------------------------------- // + +typedef struct Registers_t Registers_t; // -------------------------------------------------------------------------- // @@ -94,11 +98,15 @@ enum { // -------------------------------------------------------------------------- // -typedef struct { - ushort length; - void* base; - } __attribute__((packed)) Idtr_t; +struct Registers_t +{ + ulong ds; + ulong rdi, rsi, rbp, rsp, rbx, rdx, rcx, rax; + ulong intNo, errCode; + ulong rip, cs, eflags, useresp, ss; +} __attribute__((packed)); // -------------------------------------------------------------------------- // + #endif diff --git a/include/kernel/idt.h b/include/kernel/idt.h new file mode 100644 index 0000000..3083a20 --- /dev/null +++ b/include/kernel/idt.h @@ -0,0 +1,130 @@ +#ifndef _KALKERN_BASE_H +#include +#endif + +#ifndef _KALKERN_IDT_H +#define _KALKERN_IDT_H + +typedef struct IdtDescriptor_t IdtDescriptor_t; +typedef struct IdtEntry_t IdtEntry_t; +typedef struct IdtPtr_t IdtPtr_t; +typedef struct IRQList_t IRQList_t; + +// -------------------------------------------------------------------------- // + +#define interrupt(n) asm volatile ("int %0" : : "N" (n) : "cc", "memory") \ + +// -------------------------------------------------------------------------- // + +struct IdtDescriptor_t { + ushort limit; + ulong base; +} __attribute__((packed)) ; + +struct IdtEntry_t +{ + ushort baseLow; + ushort selector; + uchar reservedIst; + uchar flags; + ushort baseMid; + uint baseHigh; + uint reserved; +} __attribute__((packed)); + +struct IdtPtr_t +{ + ushort limit; + void *base; +} __attribute__((packed)); + +struct IRQList_t +{ + uchar n; //number of entries in the list + + struct entry { + void (*isr)(void); + uchar irq; + uchar flags; + } entry[224]; +}; + +static char *IsrExceptions[32] = { + "Divide Error Fault", + "Debug Exception Trap", + "Non-maskable Interrupt", + "Breakpoint Trap", + "Overflow Trap", + "Bound Range Exceeded Fault", + "Invalid Opcode Fault", + "Device Not Available or No Math Coprocessor Fault", + "Double Fault Abort", + "Coprocessor Segment Overrun Fault", + "Invalid TSS Fault", + "Segment Not Present Fault", + "Stack Segment fault", + "General Protection Fault", + "Page Fault", + "Intel Reserved", + "x87 FPU Floating Point or Math Fault", + "Alignment Check Fault", + "Machine Check Abort", + "SIMD Floating Point Fault", + "Virtualization Exception Fault", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved", + "Intel Reserved" +}; + +// -------------------------------------------------------------------------- // + +void IdtRegisterIrq(void (*isr)(void), uchar irq, uchar flags); +void IdtSetup(void); +void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags); +void IdtHandler(ulong intNo); +static void EnablePIC(void); +void SendEOItoPIC(uchar isr); + +extern void IdtInit(); +extern void isr0(); +extern void isr1(); +extern void isr2(); +extern void isr3(); +extern void isr4(); +extern void isr5(); +extern void isr6(); +extern void isr7(); +extern void isr8(); +extern void isr9(); +extern void isr10(); +extern void isr11(); +extern void isr12(); +extern void isr13(); +extern void isr14(); +extern void isr15(); +extern void isr16(); +extern void isr17(); +extern void isr18(); +extern void isr19(); +extern void isr20(); +extern void isr21(); +extern void isr22(); +extern void isr23(); +extern void isr24(); +extern void isr25(); +extern void isr26(); +extern void isr27(); +extern void isr28(); +extern void isr29(); +extern void isr30(); +extern void isr31(); + +#endif diff --git a/kaleid/kernel/cpu/cpuid.c b/kaleid/kernel/cpu/cpuid.c index d1f756b..c6909d2 100644 --- a/kaleid/kernel/cpu/cpuid.c +++ b/kaleid/kernel/cpu/cpuid.c @@ -22,6 +22,7 @@ // along with OS/K. If not, see . // //----------------------------------------------------------------------------// +#include char *KeGetVendorString(void) { return "Null"; diff --git a/kaleid/kernel/cpu/idt.c b/kaleid/kernel/cpu/idt.c index 64c2606..082d60a 100644 --- a/kaleid/kernel/cpu/idt.c +++ b/kaleid/kernel/cpu/idt.c @@ -21,19 +21,175 @@ // You should have received a copy of the GNU General Public License // // along with OS/K. If not, see . // //----------------------------------------------------------------------------// + #include -#include +#include +#include +#include +#include + +IdtEntry_t idt[256] = { 0 }; +IdtPtr_t idtPtr; + +IRQList_t irqList = { 0 }; -extern void lidt(Idtr_t reg); // -// Registers the new idt in the idtr register. +// Registers an isr with his IRQ to handle driver interrupts // -static inline void loadIdt(void* idtAddr, ushort size) +void IdtRegisterIrq(void (*isr)(void), uchar irq, uchar flags) { - // The IDTR register structure that will be sent - Idtr_t IDTR = { size, idtAddr }; + uchar n = irqList.n; - lidt(IDTR); + KalAssert(idt[0].flags==0); // IDT uninitialized + + if ((n == 224)) // IRQs not filled + KeStartPanic("[IdtRegisterIrq] Cannot register IRQ %c function %p !", + irq, + isr + ); + + irqList.entry[n].isr = isr; + irqList.entry[n].irq = irq; + irqList.entry[n].flags = flags; + irqList.n++; } +// +// Installs the IDT in order to activate the interrupts handling +// +void IdtSetup(void) +{ + // XXX detect the APIC with cpuid ! + EnablePIC(); + + ushort codeSeg = (ushort)(ulong)BtLoaderInfo.codeSegment; + + // Set IDT ptr + idtPtr.limit = (sizeof(IdtEntry_t) * 256) - 1; + idtPtr.base = &idt; + + // Set IDT Exception Gates + IdtSetGate(0, (ulong)isr0, codeSeg, 0x8E); + IdtSetGate(1, (ulong)isr1, codeSeg, 0x8E); + IdtSetGate(2, (ulong)isr2, codeSeg, 0x8E); + IdtSetGate(3, (ulong)isr3, codeSeg, 0x8E); + IdtSetGate(4, (ulong)isr4, codeSeg, 0x8E); + IdtSetGate(5, (ulong)isr5, codeSeg, 0x8E); + IdtSetGate(6, (ulong)isr6, codeSeg, 0x8E); + IdtSetGate(7, (ulong)isr7, codeSeg, 0x8E); + IdtSetGate(8, (ulong)isr8, codeSeg, 0x8E); + IdtSetGate(9, (ulong)isr9, codeSeg, 0x8E); + IdtSetGate(10, (ulong)isr10, codeSeg, 0x8E); + IdtSetGate(11, (ulong)isr11, codeSeg, 0x8E); + IdtSetGate(12, (ulong)isr12, codeSeg, 0x8E); + IdtSetGate(13, (ulong)isr13, codeSeg, 0x8E); + IdtSetGate(14, (ulong)isr14, codeSeg, 0x8E); + IdtSetGate(15, (ulong)isr15, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(16, (ulong)isr16, codeSeg, 0x8E); + IdtSetGate(17, (ulong)isr17, codeSeg, 0x8E); + IdtSetGate(18, (ulong)isr18, codeSeg, 0x8E); + IdtSetGate(19, (ulong)isr19, codeSeg, 0x8E); + IdtSetGate(20, (ulong)isr20, codeSeg, 0x8E); + IdtSetGate(21, (ulong)isr21, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(22, (ulong)isr22, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(23, (ulong)isr23, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(24, (ulong)isr24, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(25, (ulong)isr25, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(26, (ulong)isr26, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(27, (ulong)isr27, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(28, (ulong)isr28, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(29, (ulong)isr29, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(30, (ulong)isr30, codeSeg, 0x8E); // INTEL RESERVED + IdtSetGate(31, (ulong)isr31, codeSeg, 0x8E); // INTEL RESERVED + + // Set the IRQ Driver Gates + for (int i = 0 ; i < irqList.n ; i++) { + IdtSetGate( + irqList.entry[i].irq, + (ulong)irqList.entry[i].isr, + codeSeg, + irqList.entry[i].flags + ); + } + + // Load IDT + IdtInit(); + DebugLog("[IdtSetup] Initialized !\n"); +} + +// +// Set an interrupt gate +// +void IdtSetGate(uchar rank, ulong base, ushort selector, uchar flags) +{ + // Set Base Address + idt[rank].baseLow = base & 0xFFFF; + idt[rank].baseMid = (base >> 16) & 0xFFFF; + idt[rank].baseHigh = (base >> 32) & 0xFFFFFFFF; + + // Set Selector + idt[rank].selector = selector; + idt[rank].flags = flags; + + // Set Reserved Areas to Zero + idt[rank].reservedIst = 0; + idt[rank].reserved = 0; +} + +// +// Enable and initializes the PIC to work correctly +// +static void EnablePIC(void) +{ + // Set ICW1 - begin init of the PIC + IoWriteByteOnPort(0x20, 0x11); + IoWriteByteOnPort(0xa0, 0x11); + + // Set ICW2 (IRQ base offsets) + IoWriteByteOnPort(0x21, 0x20); //0x20 is the first free interrupt + IoWriteByteOnPort(0xa1, 0x28); + + // Set ICW3 + IoWriteByteOnPort(0x21, 0x0); + IoWriteByteOnPort(0xa1, 0x0); + + // Set ICW4 + IoWriteByteOnPort(0x21, 0x1); + IoWriteByteOnPort(0xa1, 0x1); + + // Set OCW1 (interrupt masks) + IoWriteByteOnPort(0x21, 0xff); + IoWriteByteOnPort(0xa1, 0xff); +} + +// +// Ends the current interrupt handling +// +void SendEOItoPIC(uchar isr) +{ + if(isr >= 8) + IoWriteByteOnPort(0xa0,0x20); + + IoWriteByteOnPort(0x20,0x20); +} + +// +// The main exception handler +// +void IdtHandler(ulong intNo) +{ + int irrecoverable = 0; + char *exceptionMsg = "Unhandled ISR exception"; + + if (intNo == 0 || intNo == 6 || intNo == 8 || intNo == 13) irrecoverable++; + + if (intNo < 32) exceptionMsg = IsrExceptions[intNo]; + + if (irrecoverable) { + KeStartPanic("[ISR 0x%x] Irrecoverable %s\n", intNo, exceptionMsg); + } else { + bprintf(BStdOut, "[ISR 0x%x] %s\n", intNo, exceptionMsg); + SendEOItoPIC(intNo); + } +} diff --git a/kaleid/kernel/cpu/isr.asm b/kaleid/kernel/cpu/isr.asm new file mode 100644 index 0000000..3491e6f --- /dev/null +++ b/kaleid/kernel/cpu/isr.asm @@ -0,0 +1,143 @@ +;=----------------------------------------------------------------------------=; +; GNU GPL OS/K ; +; ; +; Desc: Interrupt Descriptor Table related functions ; +; ; +; ; +; Copyright © 2018-2019 The OS/K Team ; +; ; +; This file is part of OS/K. ; +; ; +; OS/K is free software: you can redistribute it and/or modify ; +; it under the terms of the GNU General Public License as published by ; +; the Free Software Foundation, either version 3 of the License, or ; +; (at your option) any later version. ; +; ; +; OS/K is distributed in the hope that it will be useful, ; +; but WITHOUT ANY WARRANTY; without even the implied warranty of ; +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; +; GNU General Public License for more details. ; +; ; +; You should have received a copy of the GNU General Public License ; +; along with OS/K. If not, see . ; +;=----------------------------------------------------------------------------=; + +%include "kaleid/kernel/cpu/isr.inc" + +global IdtInit +global divideByZero +extern idtPtr +extern IdtHandler + +;; +;; Loads the IDT +;; +IdtInit: + lidt [idtPtr] + ret + +;; +;; Bug test +;; +divideByZero: + pushAll + mov eax, 17 + mov ebx, 0 + xor edx, edx + div ebx + popAll + ret + +;; +;; ISR handler +;; +isrPreHandler: + pushAll + + xor rax, rax + mov ax, ds + push rax + + call IdtHandler + + pop rax + mov ds, ax + + popAll + sti + iretq + +;; Divide Error Fault +IsrWithoutErrCode 0 + +;; Debug Exception Fault/trap +IsrWithoutErrCode 1 + +;; NMI Interrupt +IsrWithoutErrCode 2 + +;; Breakpoint Trap +IsrWithoutErrCode 3 + +;; Overflow Trap +IsrWithoutErrCode 4 + +;; Bound Range Exceeded Fault +IsrWithoutErrCode 5 + +;; Invalid Opcode Fault +IsrWithoutErrCode 6 + +;; Device Not Available or No Math Coprocessor Fault +IsrWithoutErrCode 7 + +;; Coprocessor Segment Overrun Fault +IsrWithoutErrCode 9 + +;; x87 FPU Floating Point or Math Fault +IsrWithoutErrCode 16 + +;; Alignment Check Fault +IsrWithoutErrCode 17 + +;; Machine Check Abort +IsrWithoutErrCode 18 + +;; SIMD Floating Point Fault +IsrWithoutErrCode 19 + +;; Virtualization Exception Fault +IsrWithoutErrCode 20 + +;; Double Fault Abort +IsrWithErrCode 8 + +;; Invalid TSS Fault +IsrWithErrCode 10 + +;; Segment Not Present Fault +IsrWithErrCode 11 + +;; Stack Segment Fault +IsrWithErrCode 12 + +;; General Protection Fault +IsrWithErrCode 13 + +;; Page Fault +IsrWithErrCode 14 + +;; Reserved +IsrWithoutErrCode 15 +IsrWithoutErrCode 21 +IsrWithoutErrCode 22 +IsrWithoutErrCode 23 +IsrWithoutErrCode 24 +IsrWithoutErrCode 25 +IsrWithoutErrCode 26 +IsrWithoutErrCode 27 +IsrWithoutErrCode 28 +IsrWithoutErrCode 29 +IsrWithoutErrCode 30 +IsrWithoutErrCode 31 + diff --git a/kaleid/kernel/cpu/isr.inc b/kaleid/kernel/cpu/isr.inc new file mode 100644 index 0000000..8f65def --- /dev/null +++ b/kaleid/kernel/cpu/isr.inc @@ -0,0 +1,58 @@ +;=----------------------------------------------------------------------------=; +; GNU GPL OS/K ; +; ; +; Desc: Interrupt Descriptor Table related macros ; +; ; +; ; +; Copyright © 2018-2019 The OS/K Team ; +; ; +; This file is part of OS/K. ; +; ; +; OS/K is free software: you can redistribute it and/or modify ; +; it under the terms of the GNU General Public License as published by ; +; the Free Software Foundation, either version 3 of the License, or ; +; (at your option) any later version. ; +; ; +; OS/K is distributed in the hope that it will be useful, ; +; but WITHOUT ANY WARRANTY; without even the implied warranty of ; +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; +; GNU General Public License for more details. ; +; ; +; You should have received a copy of the GNU General Public License ; +; along with OS/K. If not, see . ; +;=----------------------------------------------------------------------------=; +%macro pushAll 0 + push rax + push rcx + push rdx + push rbx + push rbp + push rsi + push rdi +%endmacro + +%macro popAll 0 + pop rdi + pop rsi + pop rbp + pop rbx + pop rdx + pop rcx + pop rax +%endmacro + +%macro IsrWithoutErrCode 1 + global isr%1 + isr%1: + cli + mov rdi, %1 + jmp isrPreHandler +%endmacro + +%macro IsrWithErrCode 1 + global isr%1 + isr%1: + cli + mov rdi, %1 + jmp isrPreHandler +%endmacro diff --git a/kaleid/kernel/init/info.c b/kaleid/kernel/init/info.c index d12fc5e..861d90f 100644 --- a/kaleid/kernel/init/info.c +++ b/kaleid/kernel/init/info.c @@ -29,7 +29,7 @@ // BootInfo_t initialization. It is necessary because grub will potentially be // wiped since it is below 1MB.... And we must reorganize all that stuff. // -void BtInitBootInfo(multiboot_info_t *mbi) +void BtInitBootInfo(multiboot_info_t *mbi, void *codeSeg) { extern ulong MB_header; extern ulong newKernelEnd; @@ -44,6 +44,7 @@ void BtInitBootInfo(multiboot_info_t *mbi) BtLoaderInfo.grubName = (char*)(ulong)(mbi->boot_loader_name); BtLoaderInfo.kernelAddr = (void*)&MB_header; BtLoaderInfo.kernelEndAddr = (void*)newKernelEnd; + BtLoaderInfo.codeSegment = codeSeg; BtLoaderInfo.valid = 1; } if (BtLoaderInfo.grubFlags & MULTIBOOT_INFO_MODS) { diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index 18f977d..4f03219 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -31,23 +31,42 @@ // info.c extern void BtDoSanityChecks(uint mbMagic); -extern void BtInitBootInfo(multiboot_info_t *mbi); +extern void BtInitBootInfo(multiboot_info_t *mbi, void *codeSeg); // io/vga.c extern error_t IoInitVGABuffer(void); +//io/keyb.c +extern void IoSetupKeyb(void); + +//io/rtc.c +extern void IoSetupRtc(void); +extern void IoEnableRtc(void); +extern ulong IoRtcTicks; + +// cpu/idt.c +extern void IdtSetup(void); + // ps/proc.c test function extern void pstest(void); +// interrupts tests +extern void divideByZero(void); + +void test(void) +{ + asm volatile ("hlt"); +} + // // Entry point of the Kaleid kernel // -noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic) +noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) { KeDisableIRQs(); // Initialize the BootInfo_t structure - BtInitBootInfo(mbInfo); + BtInitBootInfo(mbInfo, codeSeg); // Screen I/O available from this point on IoInitVGABuffer(); @@ -61,12 +80,27 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic) // Memory & scheduler MmInitMemoryMap(); + + // Several inits MmInitHeap(); PsInitSched(); - int i=1; - for(;i<=25;i++)BUGON(KernLog("%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%4d%3d\n",i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i,i)); - KernLog("Cursor test:"); + // Drivers ISR inits + IoSetupRtc(); + // Interrupts launching + IdtSetup(); + KeEnableIRQs(); + // Drivers enabling + IoEnableRtc(); + + while (1) { + asm volatile ("hlt"); + if (IoRtcTicks > 2000) { + KernLog("CC\n"); + break; + } + } + KernLog("\nGoodbye after %d ticks", IoRtcTicks); // End this machine's suffering BFlushBuf(BStdOut); diff --git a/kaleid/kernel/init/table.c b/kaleid/kernel/init/table.c index 0261a15..88a3169 100644 --- a/kaleid/kernel/init/table.c +++ b/kaleid/kernel/init/table.c @@ -31,3 +31,5 @@ volatile BootInfo_t BtBootTab = {0}; volatile bool KeIsPanicking = 0; volatile Processor_t *KeCurCPU = &_KeCPUTable[0]; + + diff --git a/kaleid/kernel/io/keyb.asm b/kaleid/kernel/io/keyb.asm new file mode 100644 index 0000000..5128db4 --- /dev/null +++ b/kaleid/kernel/io/keyb.asm @@ -0,0 +1,69 @@ +;=----------------------------------------------------------------------------=; +; GNU GPL OS/K ; +; ; +; Desc: Basic Read Only Keyboard Driver ; +; (x86_64 architecture only) ; +; ; +; ; +; Copyright © 2018-2019 The OS/K Team ; +; ; +; This file is part of OS/K. ; +; ; +; OS/K is free software: you can redistribute it and/or modify ; +; it under the terms of the GNU General Public License as published by ; +; the Free Software Foundation, either version 3 of the License, or ; +; (at your option) any later version. ; +; ; +; OS/K is distributed in the hope that it will be useful, ; +; but WITHOUT ANY WARRANTY; without even the implied warranty of ; +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; +; GNU General Public License for more details. ; +; ; +; You should have received a copy of the GNU General Public License ; +; along with OS/K. If not, see . ; +;=----------------------------------------------------------------------------=; + +[BITS 64] + +global KeybIsr +extern KeybHandler + +%macro pushAll 0 + push rax + push rcx + push rdx + push rbx + push rbp + push rsi + push rdi +%endmacro + +%macro popAll 0 + pop rdi + pop rsi + pop rbp + pop rbx + pop rdx + pop rcx + pop rax +%endmacro + +;; +;; Keyboard handler +;; +KeybIsr: + cli + pushAll + + xor rax, rax + mov ax, ds + push rax + + call KeybHandler + + pop rax + mov ds, ax + + popAll + sti + iretq diff --git a/kaleid/kernel/io/keyb.c b/kaleid/kernel/io/keyb.c new file mode 100644 index 0000000..6184e16 --- /dev/null +++ b/kaleid/kernel/io/keyb.c @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Basic Read Only Keyboard Driver // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + +#include +#include + +extern void KeybIsr(void); +extern void IdtRegisterIrq(void (*isr)(void), uchar irq, uchar flags); +extern void SendEOItoPIC(void); + +void IoSetupKeyb(void) +{ + IdtRegisterIrq(KeybIsr, 0x21, 0x8E); +} + + +uchar KeybHandler(void) +{ + char status; + char code = 0; + + // write EOI + IoWriteByteOnPort(0x20, 0x20); + + status = IoReadByteFromPort(0x64); + + if (status & 0x01) { + code = IoReadByteFromPort(0x60); + + if(code < 0) code = 0; + } + + return code; +} + diff --git a/kaleid/kernel/io/rtc.asm b/kaleid/kernel/io/rtc.asm new file mode 100644 index 0000000..0457ad4 --- /dev/null +++ b/kaleid/kernel/io/rtc.asm @@ -0,0 +1,69 @@ +;=----------------------------------------------------------------------------=; +; GNU GPL OS/K ; +; ; +; Desc: Basic Read Only Keyboard Driver ; +; (x86_64 architecture only) ; +; ; +; ; +; Copyright © 2018-2019 The OS/K Team ; +; ; +; This file is part of OS/K. ; +; ; +; OS/K is free software: you can redistribute it and/or modify ; +; it under the terms of the GNU General Public License as published by ; +; the Free Software Foundation, either version 3 of the License, or ; +; (at your option) any later version. ; +; ; +; OS/K is distributed in the hope that it will be useful, ; +; but WITHOUT ANY WARRANTY; without even the implied warranty of ; +; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; +; GNU General Public License for more details. ; +; ; +; You should have received a copy of the GNU General Public License ; +; along with OS/K. If not, see . ; +;=----------------------------------------------------------------------------=; + +[BITS 64] + +global RtcIsr +extern RtcHandler + +%macro pushAll 0 + push rax + push rcx + push rdx + push rbx + push rbp + push rsi + push rdi +%endmacro + +%macro popAll 0 + pop rdi + pop rsi + pop rbp + pop rbx + pop rdx + pop rcx + pop rax +%endmacro + +;; +;; Keyboard handler +;; +RtcIsr: + cli + pushAll + + xor rax, rax + mov ax, ds + push rax + + call RtcHandler + + pop rax + mov ds, ax + + popAll + sti + iretq diff --git a/kaleid/kernel/io/rtc.c b/kaleid/kernel/io/rtc.c new file mode 100644 index 0000000..f7d7548 --- /dev/null +++ b/kaleid/kernel/io/rtc.c @@ -0,0 +1,83 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Interrupt related functions // +// // +// // +// Copyright © 2018-2019 The OS/K Team // +// // +// This file is part of OS/K. // +// // +// OS/K is free software: you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation, either version 3 of the License, or // +// any later version. // +// // +// OS/K is distributed in the hope that it will be useful, // +// but WITHOUT ANY WARRANTY//without even the implied warranty of // +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // +// GNU General Public License for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with OS/K. If not, see . // +//----------------------------------------------------------------------------// + +#include +#include +#include + +extern void RtcIsr(void); +extern void SendEOItoPIC(void); +extern void IdtRegisterIrq(void (*isr)(void), uchar irq, uchar flags); + +ulong IoRtcTicks = 0; + +void IoSetupRtc(void) +{ + IdtRegisterIrq(RtcIsr, 0x28, 0x8E); +} + +void IoEnableRtc(void) +{ + ulong flags = KePauseIRQs(); + char readedInterruptConfig; + char readedRegister; + char readedIrqs; + uchar RtcRate; + + // Setting up the register control and interrupt rates + RtcRate = 0x05; + + IoWriteByteOnPort(0x70, 0x8B); + readedRegister = IoReadByteFromPort(0x71); + IoWriteByteOnPort(0x70, 0x8B); // Because reading flushes + IoWriteByteOnPort(0x71, readedRegister | 0x40); + + IoWriteByteOnPort(0x70, 0x8A); + readedInterruptConfig = IoReadByteFromPort(0x71); + IoWriteByteOnPort(0x70, 0x8A); // Because reading flushes + IoWriteByteOnPort(0x71, (readedInterruptConfig & 0xF0) | RtcRate); + IoWriteByteOnPort(0x70, 0x0C); + IoReadByteFromPort(0x71); // Flush + + // Setting up the IRQs + readedIrqs = IoReadByteFromPort(0xA1); + IoWriteByteOnPort(0xA1, 0xFE & readedIrqs); // Enables IRQ on PIC 2 + readedIrqs = IoReadByteFromPort(0x21); + IoWriteByteOnPort(0x21, 0xFB & readedIrqs); // Enables IRQ on PIC 1 + + // clean-up + IoWriteByteOnPort(0x70, 0x0C); // Select status reg C + IoReadByteFromPort(0x71); // Flush + KeRestoreIRQs(flags); +} + +void RtcHandler(void) +{ + //bprintf(BStdOut, " *RTC - "); + IoWriteByteOnPort(0x70, 0x0C); // Selects status reg C + IoReadByteFromPort(0x71); // Flush + IoRtcTicks++; + SendEOItoPIC(); + //bprintf(BStdOut, " - EOI* "); +} diff --git a/kaleid/kernel/mm/gdt.c b/kaleid/kernel/mm/gdt.c index bc41b29..8fcca54 100644 --- a/kaleid/kernel/mm/gdt.c +++ b/kaleid/kernel/mm/gdt.c @@ -50,6 +50,7 @@ void MmInitGdt(void) gdtPtr.limit = (sizeof(GdtEntry_t) * 5) - 1; gdtPtr.base = (uint)(ullong)&gdtEntries; + SetGdtEntry(0,0,0,0,0); /* XXX set TSS register */ diff --git a/kaleid/kernel/mm/map.c b/kaleid/kernel/mm/map.c index a833ccb..c876a50 100644 --- a/kaleid/kernel/mm/map.c +++ b/kaleid/kernel/mm/map.c @@ -68,9 +68,10 @@ static error_t InitMemoryMap(void) // fill the map while (currentEntry < mapEnd) { + // memory zone address - memoryMap.entry[i].addr = (void*)((ulong)currentEntry->addr_low + - (((ulong)currentEntry->addr_high) << 32 )); + memoryMap.entry[i].addr = (void*)((ullong)currentEntry->addr_low + + (((ullong)currentEntry->addr_high) << 32 )); // memory zone size in bytes memoryMap.entry[i].length = (ulong)currentEntry->len_low + (((ulong)currentEntry->len_high) << 32); @@ -100,10 +101,10 @@ static error_t InitMemoryMap(void) if (memoryMap.freeRamSize < MINIMUM_RAM_SIZE) return ENOMEM; - KernLog("[InitMemoryMap] Available Ram Size : %u Mio, Used Ram Size : %u Kio\n", + DebugLog("[InitMemoryMap] Available Ram Size : %u Mio, Used Ram Size : %u Kio\n\n", memoryMap.freeRamSize / MB, memoryMap.nonfreeRamSize / KB); - KernLog("[InitMemoryMap] Physical Ram Size : %d Mio\n\n", - (memoryMap.freeRamSize + memoryMap.nonfreeRamSize) / MB); + /*DebugLog("[InitMemoryMap] Physical Ram Size : %d Mio\n\n", + (memoryMap.freeRamSize + memoryMap.nonfreeRamSize) / MB);*/ return EOK; } @@ -192,7 +193,7 @@ void MmPrintMemoryMap(void) { default:; } - KernLog("Mem zone : %p\t%s\twith length: %d Kio\n", + KernLog("Mem zone : %lp\t%s\twith length: %d Kio\n", memoryMap.entry[i].addr, avStr, memoryMap.entry[i].length / KB