diff --git a/Makefile b/Makefile index 0d11f9b..05c091e 100644 --- a/Makefile +++ b/Makefile @@ -22,7 +22,7 @@ # along with OS/K. If not, see . # #=----------------------------------------------------------------------------=# -.PHONY: all test testnokvm testnosnd test32 debug gdb installonimage dust clean OS/K run +.PHONY: all test testnokvm testnosnd test32 debug gdb ddd gdbnokvm dddnokvm installonimage dust clean OS/K run .DELETE_ON_ERROR: $(BINDIR)/kaleid .DEFAULT_GOAL := all @@ -41,7 +41,7 @@ CCNAME=x86_64-elf-gcc ASMFLAGS=-f elf64 LDFLAGS=-melf_x86_64 COPTIM=-O2 -CWARNS=-Wall -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough -Werror=implicit-function-declaration -Werror=return-type +CWARNS=-Wall -Wextra -Wno-unused-parameter -Wno-implicit-fallthrough -Werror=implicit-function-declaration -Werror=return-type #-Wpadded CINCLUDES=-Iinclude CFLAGS1=-nostdlib -ffreestanding -mcmodel=large -std=gnu11 -fstack-protector-all -fdump-rtl-expand CFLAGS2= -c -mno-red-zone -mno-mmx -mno-sse -mno-sse2 @@ -292,7 +292,7 @@ test32: all installonimage cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log & gdb: all installonimage - @setsid qemu-system-x86_64 -m $(ram) -soundhw pcspk -rtc base=localtime \ + @setsid qemu-system-x86_64 -m $(ram) -enable-kvm -rtc base=localtime \ -hda $(installdisk) -no-reboot -no-shutdown -d \ cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log & @gdb \ @@ -302,9 +302,26 @@ gdb: all installonimage -ex "break BtStartKern" \ ddd: all installonimage - @setsid qemu-system-x86_64 -m $(ram) -hda $(installdisk) -no-reboot -soundhw pcspk \ - -no-shutdown -d cpu_reset,guest_errors,pcall,int -s 2> $(BUILDDIR)/qemu.log & - @ddd + @setsid qemu-system-x86_64 -m $(ram) -enable-kvm -rtc base=localtime \ + -hda $(installdisk) -no-reboot -no-shutdown -d \ + cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log & + @ddd -n + +gdbnokvm: all installonimage + @setsid qemu-system-x86_64 -m $(ram) -rtc base=localtime \ + -hda $(installdisk) -no-reboot -no-shutdown -d \ + cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log & + @gdb \ + -ex "set arch i386:x86-64:intel" \ + -ex "target remote localhost:1234" \ + -ex "symbol-file $(BINDIR)/kaleid" \ + -ex "break BtStartKern" \ + +dddnokvm: all installonimage + @setsid qemu-system-x86_64 -m $(ram) -rtc base=localtime \ + -hda $(installdisk) -no-reboot -no-shutdown -d \ + cpu_reset,guest_errors,pcall,int -s -S 2> $(BUILDDIR)/qemu.log & + @ddd -n ## HD IMAGE RELATED ---------------------------------------------------------- # diff --git a/README.md b/README.md index 7d3b06a..93be98b 100644 --- a/README.md +++ b/README.md @@ -42,3 +42,8 @@ To compile and install, simply use at the root of this project, with XXX the ima make install installdisk=XXX ``` +#### Screenshot +![OS/K Started](https://www.os-k.eu/images/screen3.png) + + + diff --git a/build/kernel.ld b/build/kernel.ld index 0840bf2..7604bd8 100644 --- a/build/kernel.ld +++ b/build/kernel.ld @@ -38,13 +38,16 @@ SECTIONS { .text ALIGN (0x1000) : { + _text = .; *(.text) + _text_end = .; } .data ALIGN (0x1000) : { _data = .; *(.data) + _data_end = .; } .eh_frame ALIGN (0x1000) : @@ -55,7 +58,9 @@ SECTIONS { .rodata ALIGN (0x1000) : { + _rodata = .; *(.rodata) + _rodata_end = .; } .bss ALIGN (0x1000) : @@ -71,4 +76,3 @@ SECTIONS { kernelEnd = .; } - diff --git a/include/asm.h b/include/asm.h index 4694222..936ae50 100644 --- a/include/asm.h +++ b/include/asm.h @@ -136,6 +136,11 @@ static inline ulong KeReadStsc(void) { return ((ulong)edx << 32) + eax; } +static inline void KeFlushTlbSingle(ulong addr) +{ + asm volatile("invlpg (%0)" ::"r" (addr) : "memory"); +} + //------------------------------------------// // Misc. I/O // //------------------------------------------// diff --git a/include/init/boot.h b/include/init/boot.h index 61cfa19..5594870 100644 --- a/include/init/boot.h +++ b/include/init/boot.h @@ -44,24 +44,24 @@ struct BootInfo_t { // The Bootloader infos struct { - ushort valid; - uint grubFlags; //flags - uint modulesCount; //mods_count void *modulesAddr; //mods_addr - char *grubName; //boot_loader_name void *kernelAddr; void *codeSegment; void *kernelEndAddr; void *stackEndAddr; // stack begins 16B after kernelEndAddr + uint grubFlags; //flags + uint modulesCount; //mods_count + ushort valid; + char *grubName; //boot_loader_name } btldr; // Informations about drives struct { - ushort drvValid; - ushort bufferValid; + void *bufferAddr; //drives_addr uint bootDrv; //boot_device uint bufferLength; //drives_length - void *bufferAddr; //drives_addr + ushort drvValid; + ushort bufferValid; } drives; // Informations about memory @@ -74,36 +74,36 @@ struct BootInfo_t uint upMemory; //mem_upper //GRUB provided memory map - uint mapLength; //mmap_length void *mapAddr; //mmap_addr + uint mapLength; //mmap_length uint ramSize; //The ram (init by map.c) } memory; // Informations about the video drive struct { - ushort vbeValid; - ushort fbuValid; void *vbeControl; //vbe_control_info void *vbeModeInfo; //vbe_mode_info - ushort vbeMode; //vbe_mode - ushort vbeInterfaceSeg; //vbe_interface_seg - ushort vbeInterfaceOff; //vbe_interface_off - ushort vbeInterfaceLen; //vbe_interface_len void *framebufferAddr; //framebuffer_addr uint framebufferPitch; //framebuffer_pitch uint framebufferWidth; //framebuffer_width uint framebufferHeight; //framebuffer_height + ushort vbeValid; + ushort fbuValid; + ushort vbeMode; //vbe_mode + ushort vbeInterfaceSeg; //vbe_interface_seg + ushort vbeInterfaceOff; //vbe_interface_off + ushort vbeInterfaceLen; //vbe_interface_len uchar framebufferBpp; //framebuffer_bpp uchar framebufferType; //framebuffer_type } video; // Informations about the microcode firmware (BIOS/EFI) struct { - ushort apmValid; - ushort romValid; uint apmTable; //apm_table uint romTable; //config_table + ushort apmValid; + ushort romValid; } firmware; }; diff --git a/include/io/spkr.h b/include/io/spkr.h index 760928a..be9eea5 100644 --- a/include/io/spkr.h +++ b/include/io/spkr.h @@ -31,13 +31,19 @@ //----------------------------------------------------------------------------// -void IoStartSpeaker(int); +void IoStartSpeaker(ulong); void IoDoBeep(void); -void IoDoTone(uint tone, uint time); +void IoDoTone(ulong tone, ulong time); void IoDoBeepNoIdt(void); void IoDoStarWars(void); +struct Note +{ + ulong tone; + ulong time; +}; + //----------------------------------------------------------------------------// #endif diff --git a/include/io/vga.h b/include/io/vga.h index 319c790..11d7c50 100644 --- a/include/io/vga.h +++ b/include/io/vga.h @@ -59,6 +59,7 @@ extern const char *RtlColorNames[VGA_COLOR_WHITE+1]; #define RtlCharToColor(c) ((c) - 130) uint IoGetScroll(void); +void IoSetScroll(uint); void IoScrollUp(void); void IoScrollDown(void); diff --git a/include/mm/mm.h b/include/mm/mm.h index 8bd9238..50657f1 100644 --- a/include/mm/mm.h +++ b/include/mm/mm.h @@ -41,7 +41,7 @@ #define BADRAM_ZONE 5 // Invalid zone because material problem... #define MAX_ENTRIES 2048 // Max number of memory map entries #define KPAGESIZE (4 * KB) -#define UPAGESIZE (2 * MB) +#define UPAGESIZE (4 * KB) //----------------------------------------------------------------------------// @@ -108,7 +108,7 @@ struct Tss_t ushort iomap_base; uchar iomap[IOMAP_SIZE]; -} __attribute__ ((packed)); +} __attribute__ ((packed)) __attribute__((aligned(8))); @@ -158,10 +158,11 @@ extern void MmLoadGdt(GdtPtr_t *gdtPtr, ushort tssOffset); // extern void MmStoreGdt(void); +// +// Paging misc +// void MmInitPaging(void); -void MmReloadPaging(void); - void MmActivatePageHandler(void); // @@ -170,24 +171,39 @@ void MmActivatePageHandler(void); void *MmGetStackGuards(char rank); // -// Translate a virtual address into physical address +// Translate a virtual address into physical address and the opposite // -void *MmTranslateKPageToAddr(void *rank); +void *MmTransVirtToPhyAddr(void*); +void *MmTransPhyToVirtAddr(void* virtualAddr); -// Page directory pointer offset -typedef ulong pdpe_t; +// +// Set flags to a page +// +void MmSetPage(void* virtualAddr, ulong flags); +void MmUnSetPage(void* virtualAddr, ulong flags); -// Page directory offset -typedef ulong pde_t; +// +// Map a page +// +void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags); +void MmUnmapPage(void* virtualAddr); // Page table entry typedef ulong pte_t; +// Page directory offset +typedef pte_t* pde_t; + +// Page directory pointer offset +typedef pde_t* pdpe_t; + +// Page directory L4 pointer offset +typedef pdpe_t* pml4_t; + // paging.asm void MmLoadPML4(void *); void MmEnableWriteProtect(void); void MmDisableWriteProtect(void); -void *MmGetStackGuards(char rank); //----------------------------------------------------------------------------// diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index ceda825..12d3792 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -62,21 +62,21 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) // Memory MmInitMemoryMap(); - MmInitPaging(); - MmInitHeap(); + MmInitGdt(); - // Basics for interrupts + // Interrupts KeSetupIDT(); KeEnableIRQs(); + + // Memory (2) + MmInitHeap(); + MmInitPaging(); + + // Interrupt handlers + MmActivatePageHandler(); KeEnableRTC(); KeEnablePIT(); KeGetCpuInfos(); - - // Memory (2) - MmInitGdt(); - MmActivatePageHandler(); - - // Drivers IoEnableKeyb(); // Command line (kernel mode) diff --git a/kaleid/kernel/io/spkr.c b/kaleid/kernel/io/spkr.c index dff5d21..66a7f5c 100644 --- a/kaleid/kernel/io/spkr.c +++ b/kaleid/kernel/io/spkr.c @@ -28,10 +28,21 @@ extern bool KeIdtIsInitialized; -void IoStartSpeaker(int freq) +struct Note score[40] = { {440, 200}, {110, 200}, {440, 200}, {110, 200}, + {440, 200}, {110, 200}, {349, 140}, {87, 100}, + {523, 60}, {87, 100}, {440, 200}, {110, 200}, + {349, 140}, {87, 100}, {523, 60}, {87, 100}, + {440, 200}, {110, 200}, {440, 200}, {110, 200}, + {659, 200}, {110, 200}, {659, 200}, {110, 200}, + {659, 200}, {87, 200}, {698, 140}, {87, 100}, + {523, 60}, {87, 100}, {415, 200}, {87, 200}, + {349, 140}, {87, 100}, {523, 60}, {87, 100}, + {440, 200}, {110, 200}, {110, 200}, {110, 200} }; + +void IoStartSpeaker(ulong freq) { uchar temp; - uint pitf = 1193180 / freq; + ulong pitf = 1193180 / freq; ulong flags = KePauseIRQs(); IoWriteByteOnPort(0x43, 0xB6); @@ -52,13 +63,13 @@ static inline void IoQuietSpeaker(void) KeRestoreIRQs(flags); } -void IoDoTone(uint tone, uint time) +void IoDoTone(ulong tone, ulong time) { IoStartSpeaker(tone); KeSleep(time); } -static void IoDoToneNoIdt(uint tone, uint time) +static void IoDoToneNoIdt(ulong tone, ulong time) { extern void temporize(void); IoStartSpeaker(tone); @@ -81,29 +92,8 @@ void IoDoBeepNoIdt(void) void IoDoStarWars(void) { - struct Note { - uint tone; - uint time; - }; - - struct Note score[] = { {440, 200}, {110, 200}, {440, 200}, {110, 200}, - {440, 200}, {110, 200}, {349, 140}, {87, 100}, - {523, 60}, {87, 100}, {440, 200}, {110, 200}, - {349, 140}, {87, 100}, {523, 60}, {87, 100}, - {440, 200}, {110, 200}, {440, 200}, {110, 200}, - {659, 200}, {110, 200}, {659, 200}, {110, 200}, - {659, 200}, {87, 200}, {698, 140}, {87, 100}, - {523, 60}, {87, 100}, {415, 200}, {87, 200}, - {349, 140}, {87, 100}, {523, 60}, {87, 100}, - {440, 200}, {110, 200}, {110, 200}, {110, 200} - }; - - //bprintf(BStdOut, "\n"); - - for (uint i = 0; i < sizeof(score)/sizeof(struct Note); i++) { + for (uint i = 0; i < 40; i++) { IoDoTone(score[i].tone, score[i].time); - //bprintf(BStdOut, "%d ", i); - //BStdOut->flusher(BStdOut); } IoQuietSpeaker(); diff --git a/kaleid/kernel/io/vga.c b/kaleid/kernel/io/vga.c index e02041d..80d6842 100644 --- a/kaleid/kernel/io/vga.c +++ b/kaleid/kernel/io/vga.c @@ -113,6 +113,11 @@ uint IoGetScroll(void) return bscroll; } +void IoSetScroll(uint value) +{ + bscroll = 0; +} + void IoScrollDown(void) { BLockBuf(BStdOut); diff --git a/kaleid/kernel/ke/idt.c b/kaleid/kernel/ke/idt.c index d5dc7e2..d6fc0fc 100644 --- a/kaleid/kernel/ke/idt.c +++ b/kaleid/kernel/ke/idt.c @@ -26,7 +26,6 @@ #include #include #include -#include #include IdtEntry_t idt[256] = { 0 }; @@ -120,56 +119,56 @@ void KeSetupIDT(void) _KeIdtPtr.base = &idt; // Set IDT Exception Gates - KeSetIDTGate(0x00, (ulong)isr0, codeSeg, 0x8E, 0); - KeSetIDTGate(0x01, (ulong)isr1, codeSeg, 0x8E, 0); - KeSetIDTGate(0x02, (ulong)isr2, codeSeg, 0x8E, 0); - KeSetIDTGate(0x03, (ulong)isr3, codeSeg, 0x8E, 0); - KeSetIDTGate(0x04, (ulong)isr4, codeSeg, 0x8E, 0); - KeSetIDTGate(0x05, (ulong)isr5, codeSeg, 0x8E, 0); - KeSetIDTGate(0x06, (ulong)isr6, codeSeg, 0x8E, 0); - KeSetIDTGate(0x07, (ulong)isr7, codeSeg, 0x8E, 0); - KeSetIDTGate(0x08, (ulong)isr8, codeSeg, 0x8E, 1); - KeSetIDTGate(0x09, (ulong)isr9, codeSeg, 0x8E, 0); - KeSetIDTGate(0x0A, (ulong)isr10, codeSeg, 0x8E, 0); - KeSetIDTGate(0x0B, (ulong)isr11, codeSeg, 0x8E, 0); - KeSetIDTGate(0x0C, (ulong)isr12, codeSeg, 0x8E, 1); - KeSetIDTGate(0x0D, (ulong)isr13, codeSeg, 0x8E, 0); - KeSetIDTGate(0x0E, (ulong)isr14, codeSeg, 0x8E, 0); - KeSetIDTGate(0x0F, (ulong)isr15, codeSeg, 0x8E, 0); // INTEL RESERVED - KeSetIDTGate(0x10, (ulong)isr16, codeSeg, 0x8E, 0); - KeSetIDTGate(0x11, (ulong)isr17, codeSeg, 0x8E, 0); - KeSetIDTGate(0x12, (ulong)isr18, codeSeg, 0x8E, 0); - KeSetIDTGate(0x13, (ulong)isr19, codeSeg, 0x8E, 0); - KeSetIDTGate(0x14, (ulong)isr20, codeSeg, 0x8E, 0); - KeSetIDTGate(0x15, (ulong)isr21, codeSeg, 0x8E, 0); // INTEL RESERVED - KeSetIDTGate(0x16, (ulong)isr22, codeSeg, 0x8E, 0); // INTEL RESERVED - KeSetIDTGate(0x17, (ulong)isr23, codeSeg, 0x8E, 0); // INTEL RESERVED - KeSetIDTGate(0x18, (ulong)isr24, codeSeg, 0x8E, 0); // INTEL RESERVED - KeSetIDTGate(0x19, (ulong)isr25, codeSeg, 0x8E, 0); // INTEL RESERVED - KeSetIDTGate(0x1A, (ulong)isr26, codeSeg, 0x8E, 0); // INTEL RESERVED - KeSetIDTGate(0x1B, (ulong)isr27, codeSeg, 0x8E, 0); // INTEL RESERVED - KeSetIDTGate(0x1C, (ulong)isr28, codeSeg, 0x8E, 0); // INTEL RESERVED - KeSetIDTGate(0x1D, (ulong)isr29, codeSeg, 0x8E, 0); // INTEL RESERVED - KeSetIDTGate(0x1E, (ulong)isr30, codeSeg, 0x8E, 0); - KeSetIDTGate(0x1F, (ulong)isr31, codeSeg, 0x8E, 0); // INTEL RESERVED + KeSetIDTGate(0x00, (ulong)isr0, codeSeg, 0x8E, 2); + KeSetIDTGate(0x01, (ulong)isr1, codeSeg, 0x8E, 2); + KeSetIDTGate(0x02, (ulong)isr2, codeSeg, 0x8E, 2); + KeSetIDTGate(0x03, (ulong)isr3, codeSeg, 0x8E, 2); + KeSetIDTGate(0x04, (ulong)isr4, codeSeg, 0x8E, 2); + KeSetIDTGate(0x05, (ulong)isr5, codeSeg, 0x8E, 2); + KeSetIDTGate(0x06, (ulong)isr6, codeSeg, 0x8E, 2); + KeSetIDTGate(0x07, (ulong)isr7, codeSeg, 0x8E, 2); // XXX device not available, useful for FPU save/restore when multitasking + KeSetIDTGate(0x08, (ulong)isr8, codeSeg, 0x8E, 1); // DOUBLE FAULT + KeSetIDTGate(0x09, (ulong)isr9, codeSeg, 0x8E, 2); + KeSetIDTGate(0x0A, (ulong)isr10, codeSeg, 0x8E, 0); // INVALID TSS + KeSetIDTGate(0x0B, (ulong)isr11, codeSeg, 0x8E, 2); + KeSetIDTGate(0x0C, (ulong)isr12, codeSeg, 0x8E, 1); // STACK SEGMENT FAULT + KeSetIDTGate(0x0D, (ulong)isr13, codeSeg, 0x8E, 2); + KeSetIDTGate(0x0E, (ulong)isr14, codeSeg, 0x8E, 2); + KeSetIDTGate(0x0F, (ulong)isr15, codeSeg, 0x8E, 2); // INTEL RESERVED + KeSetIDTGate(0x10, (ulong)isr16, codeSeg, 0x8E, 2); + KeSetIDTGate(0x11, (ulong)isr17, codeSeg, 0x8E, 2); + KeSetIDTGate(0x12, (ulong)isr18, codeSeg, 0x8E, 2); + KeSetIDTGate(0x13, (ulong)isr19, codeSeg, 0x8E, 2); + KeSetIDTGate(0x14, (ulong)isr20, codeSeg, 0x8E, 2); + KeSetIDTGate(0x15, (ulong)isr21, codeSeg, 0x8E, 2); // INTEL RESERVED + KeSetIDTGate(0x16, (ulong)isr22, codeSeg, 0x8E, 2); // INTEL RESERVED + KeSetIDTGate(0x17, (ulong)isr23, codeSeg, 0x8E, 2); // INTEL RESERVED + KeSetIDTGate(0x18, (ulong)isr24, codeSeg, 0x8E, 2); // INTEL RESERVED + KeSetIDTGate(0x19, (ulong)isr25, codeSeg, 0x8E, 2); // INTEL RESERVED + KeSetIDTGate(0x1A, (ulong)isr26, codeSeg, 0x8E, 2); // INTEL RESERVED + KeSetIDTGate(0x1B, (ulong)isr27, codeSeg, 0x8E, 2); // INTEL RESERVED + KeSetIDTGate(0x1C, (ulong)isr28, codeSeg, 0x8E, 2); // INTEL RESERVED + KeSetIDTGate(0x1D, (ulong)isr29, codeSeg, 0x8E, 2); // INTEL RESERVED + KeSetIDTGate(0x1E, (ulong)isr30, codeSeg, 0x8E, 2); + KeSetIDTGate(0x1F, (ulong)isr31, codeSeg, 0x8E, 2); // INTEL RESERVED // Set IDT IRQs Gates - KeSetIDTGate(0x20, (ulong)isr32, codeSeg, 0x8E, 0); - KeSetIDTGate(0x21, (ulong)isr33, codeSeg, 0x8E, 0); - KeSetIDTGate(0x22, (ulong)isr34, codeSeg, 0x8E, 0); - KeSetIDTGate(0x23, (ulong)isr35, codeSeg, 0x8E, 0); - KeSetIDTGate(0x24, (ulong)isr36, codeSeg, 0x8E, 0); - KeSetIDTGate(0x25, (ulong)isr37, codeSeg, 0x8E, 0); - KeSetIDTGate(0x26, (ulong)isr38, codeSeg, 0x8E, 0); - KeSetIDTGate(0x27, (ulong)isr39, codeSeg, 0x8E, 0); - KeSetIDTGate(0x28, (ulong)isr40, codeSeg, 0x8E, 0); - KeSetIDTGate(0x29, (ulong)isr41, codeSeg, 0x8E, 0); - KeSetIDTGate(0x2A, (ulong)isr42, codeSeg, 0x8E, 0); - KeSetIDTGate(0x2B, (ulong)isr43, codeSeg, 0x8E, 0); - KeSetIDTGate(0x2C, (ulong)isr44, codeSeg, 0x8E, 0); - KeSetIDTGate(0x2D, (ulong)isr45, codeSeg, 0x8E, 0); - KeSetIDTGate(0x2E, (ulong)isr46, codeSeg, 0x8E, 0); - KeSetIDTGate(0x2F, (ulong)isr47, codeSeg, 0x8E, 0); + KeSetIDTGate(0x20, (ulong)isr32, codeSeg, 0x8E, 3); + KeSetIDTGate(0x21, (ulong)isr33, codeSeg, 0x8E, 3); + KeSetIDTGate(0x22, (ulong)isr34, codeSeg, 0x8E, 3); + KeSetIDTGate(0x23, (ulong)isr35, codeSeg, 0x8E, 3); + KeSetIDTGate(0x24, (ulong)isr36, codeSeg, 0x8E, 3); + KeSetIDTGate(0x25, (ulong)isr37, codeSeg, 0x8E, 3); + KeSetIDTGate(0x26, (ulong)isr38, codeSeg, 0x8E, 3); + KeSetIDTGate(0x27, (ulong)isr39, codeSeg, 0x8E, 3); + KeSetIDTGate(0x28, (ulong)isr40, codeSeg, 0x8E, 3); + KeSetIDTGate(0x29, (ulong)isr41, codeSeg, 0x8E, 3); + KeSetIDTGate(0x2A, (ulong)isr42, codeSeg, 0x8E, 3); + KeSetIDTGate(0x2B, (ulong)isr43, codeSeg, 0x8E, 3); + KeSetIDTGate(0x2C, (ulong)isr44, codeSeg, 0x8E, 3); + KeSetIDTGate(0x2D, (ulong)isr45, codeSeg, 0x8E, 3); + KeSetIDTGate(0x2E, (ulong)isr46, codeSeg, 0x8E, 3); + KeSetIDTGate(0x2F, (ulong)isr47, codeSeg, 0x8E, 3); KeIdtIsInitialized++; @@ -293,8 +292,8 @@ void KeDisableNMI(void) // void _KeHandleISR(ISRFrame_t *regs) { - if ((!regs) || (!regs->rip)) - KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n"); + /* if ((!regs) || (!regs->rip)) */ + /* KeStartPanic("[ISR ?] Unknown ISR Exception Abort\n"); */ if ((regs->intNo >= 0x15) && (regs->intNo <= 0x1D)) return; // INTEL RESERVED @@ -341,21 +340,7 @@ static void EarlyExceptionHandler(ISRFrame_t *regs) // static void DoubleFaultHandler(ISRFrame_t *regs) { - ulong StackGuardTwo = (ulong)MmGetStackGuards(1); - - if (regs->rsp <= StackGuardTwo + 4*KB && (regs->rsp - 4*KB <= regs->cr2)) { - bprintf(BStdOut, - "\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Stack Overflow\n\n" - " Double Fault Error code : %#x (%b)\n" - " Stack Guard bypassed : %#x", - - VGA_COLOR_LIGHT_RED, - regs->ErrorCode, - regs->ErrorCode, - StackGuardTwo - ); - } else { - bprintf(BStdOut, + bprintf(BStdOut, "\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Double Fault Abort\n\n" " Error code : 0x%x (%b)", @@ -364,8 +349,6 @@ static void DoubleFaultHandler(ISRFrame_t *regs) regs->ErrorCode ); - } - KeBrkDumpRegisters(regs); BStdOut->flusher(BStdOut); diff --git a/kaleid/kernel/ke/isr.asm b/kaleid/kernel/ke/isr.asm index 8a92419..7c07e6f 100644 --- a/kaleid/kernel/ke/isr.asm +++ b/kaleid/kernel/ke/isr.asm @@ -95,6 +95,10 @@ isrPreHandler: iretq +Die: + hlt + jmp Die + ;; Divide Error Fault IsrWithoutErrCode 0 diff --git a/kaleid/kernel/ke/pit.c b/kaleid/kernel/ke/pit.c index db3bfda..a9d961c 100644 --- a/kaleid/kernel/ke/pit.c +++ b/kaleid/kernel/ke/pit.c @@ -37,6 +37,9 @@ static char TimeFmtBuf[22] = { 0 }; // // ISR handler for the Programmable Interval Timer // + +#pragma GCC push_options +#pragma GCC optimize ("O0") static void HandlePIT(ISRFrame_t *regs) { Ticks++; @@ -52,6 +55,7 @@ static void HandlePIT(ISRFrame_t *regs) KeSendEOItoPIC(0x28); } } +#pragma GCC pop_options static Timer_t* KeFindTimerBlock(void) { @@ -63,6 +67,8 @@ static Timer_t* KeFindTimerBlock(void) return NULL; } +#pragma GCC push_options +#pragma GCC optimize ("O0") void KeSleep(uint delay) { Timer_t *timerBlock; @@ -77,7 +83,10 @@ void KeSleep(uint delay) } timerBlock->sema = 0; } +#pragma GCC pop_options +#pragma GCC push_options +#pragma GCC optimize ("O0") Timer_t *KeSetTimer(uint delay) { Timer_t *timerBlock; @@ -89,6 +98,7 @@ Timer_t *KeSetTimer(uint delay) return timerBlock; } +#pragma GCC pop_options int KeGetTimer(Timer_t *timerBlock) { diff --git a/kaleid/kernel/mm/gdt.c b/kaleid/kernel/mm/gdt.c index eb3c4e3..8bd426a 100644 --- a/kaleid/kernel/mm/gdt.c +++ b/kaleid/kernel/mm/gdt.c @@ -45,6 +45,10 @@ void MmInitGdt(void) gdt[1].access = 0x98; gdt[1].flags = 0x20; + gdt[2].lowLimit = 0xFFFF; + gdt[2].access = 0x98; + gdt[2].flags = 0x20; + tssDesc.access = 0x89; tssDesc.flags = 0x40; tssDesc.lowBase = (ulong)&tss & 0xFFFF; @@ -53,7 +57,9 @@ void MmInitGdt(void) tssDesc.veryHighBase = ((ulong)&tss >> 32) & 0xFFFFFFFF; tssDesc.lowLimit = sizeof(tss); - tss.ist1 = 0x0007FFFF; // RESCUE STACK, GARANTIED FREE FOR USE BY OSDEV.ORG + tss.ist1 = (ulong)0x0007FFFF; // ISR RESCUE STACK, GARANTIED FREE FOR USE BY OSDEV.ORG + tss.ist2 = (ulong)0x00EFFFFF; // ISR STACK, GARANTIED FREE FOR USE BY OSDEV.ORG + tss.ist3 = (ulong)0x00EF0000; // ISR STACK, GARANTIED FREE FOR USE BY OSDEV.ORG tss.iomap_base = sizeof(tss); memmove(&gdt[2], &tssDesc, sizeof(TssDescriptor_t)); diff --git a/kaleid/kernel/mm/paging.c b/kaleid/kernel/mm/paging.c index 7b9a93c..5a7e77e 100644 --- a/kaleid/kernel/mm/paging.c +++ b/kaleid/kernel/mm/paging.c @@ -1,39 +1,43 @@ #include #include #include +#include #include #include #include #include -enum -{ - MF_PRESENT = 1 << 0, - MF_READWRITE = 1 << 1, - MF_USERMODE = 1 << 2, - MF_WRITETHR = 1 << 3, - MF_CACHEDIS = 1 << 4, - MF_ACCESSED = 1 << 5, - MF_DIRTY = 1 << 6, - MF_HUGE = 1 << 7, - MF_NX = 1 << 31 -}; - -#define RAM_MAX 32 -#define NB_4K 150 - // * 2 MB +#define USERSPACE 0x80000000 //----------- -volatile pdpe_t MmPML4[512] __attribute__((__aligned__(KPAGESIZE))); +pml4_t MmPageMapLevel4[512] __attribute__((__aligned__(KPAGESIZE))); +ulong *MmPhysicalPageTable; -volatile pde_t MmPDP[512] __attribute__((__aligned__(KPAGESIZE))); - -volatile pde_t MmPD[512 * RAM_MAX] __attribute__((__aligned__(KPAGESIZE)));; - -volatile pte_t MmPT[512 * NB_4K] __attribute__((__aligned__(KPAGESIZE)));; +extern ulong _text; +extern ulong _text_end; +extern ulong _rodata; +extern ulong _rodata_end; +extern ulong _data; +extern ulong _data_end; ulong MmStackGuards[2] = { 0 }; +ulong MmVirtLastAddress = 0; + +enum +{ + PRESENT = 1 << 0, + READWRITE = 1 << 1, + USERMODE = 1 << 2, + WRITETHR = 1 << 3, + CACHEDIS = 1 << 4, + ACCESSED = 1 << 5, + DIRTY = 1 << 6, + HUGE = 1 << 7, + NX = 1UL << 63 +}; + +//----------- // // Creates our new page table structure and loads it @@ -41,140 +45,294 @@ ulong MmStackGuards[2] = { 0 }; void MmInitPaging(void) { extern MemoryMap_t memoryMap; + pdpe_t *MmPDP = NULL; + pde_t *MmPD = NULL; + pte_t *MmPT = NULL; + ulong index, xedni; + ulong firstDirectoryAddr = 0; + ulong lastDirectoryAddr = 0; + ulong phDirSize = 0; + + // Maximum PHYSICAL address in memory ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize; - memzero((void *)&MmPML4[0], sizeof(MmPML4)); - memzero((void *)&MmPDP[0], sizeof(MmPDP)); - memzero((void *)&MmPD[0], sizeof(MmPD)); - memzero((void *)&MmPT[0], sizeof(MmPT)); + // Difference between the end of kernel and the begin of userspace + ulong lastKernelAddr = (ulong)(_heap_start + _heap_max); + ulong diffKernUsr = (ulong)USERSPACE - lastKernelAddr - KPAGESIZE; - for (volatile ulong i = 0; i < 512 * NB_4K; i++) { - // STACK GUARD PAGE - if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.stackEndAddr) { - MmPT[i] = ((ulong)(i*KPAGESIZE)); - MmStackGuards[0] = ((ulong)(i*KPAGESIZE)); - continue; - } + // Maximum VIRTUAL address in memory + MmVirtLastAddress = phRamSize + diffKernUsr; - // ENOMEM like - if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) { - break; - } + //DebugLog("\tPaging gap : %u MB (%p)\n\tLast virtual address %p\n", diffKernUsr / MB, diffKernUsr, MmVirtLastAddress); - // STACK GARD PAGE - if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) { - MmPT[i] = ((ulong)(i*KPAGESIZE)); - MmStackGuards[1] = ((ulong)(i*KPAGESIZE)); - continue; - } + memzero((void *)&MmPageMapLevel4[0], sizeof(MmPageMapLevel4)); + phDirSize = ((phRamSize / KPAGESIZE)*sizeof(ulong) + KPAGESIZE) & ( ~(KPAGESIZE - 1)); - MmPT[i] = ((ulong)(i*KPAGESIZE)) | MF_PRESENT | MF_READWRITE; + MmPhysicalPageTable = (ulong*)malloc(phDirSize); + //DebugLog("\t\tRam %u MB, pagesize %u KB, size %u MB\n", phRamSize / MB, KPAGESIZE / KB, phDirSize / MB); + + for (ulong curAddrPML4 = 0; + curAddrPML4 < MmVirtLastAddress; + curAddrPML4 += ((ulong)KPAGESIZE * 0x8000000)) { + // Create an entry in PML4 each 512GB + // 0x8000000 = 512 ^ 3 + + MmPDP = (pdpe_t *)malloc(512*sizeof(pde_t)); + + if (!firstDirectoryAddr) { + firstDirectoryAddr = (ulong)MmPDP; + } + + index = (curAddrPML4 / ((ulong)KPAGESIZE * 0x8000000)) % 512; + + //DebugLog("\t\t\t\tPDP %d : %p\n", index, MmPDP); + MmPageMapLevel4[index] = (pdpe_t *)((ulong)MmPDP | PRESENT | READWRITE); + + for (ulong curAddrPDP = curAddrPML4; + curAddrPDP < (curAddrPML4 + ((ulong)KPAGESIZE * 0x8000000)) && + curAddrPDP < MmVirtLastAddress; + curAddrPDP += ((ulong)KPAGESIZE * 0x40000)) { + // Create an intry in PDP each 1GB + // 0x40000 = 512 ^ 2 + + MmPD = (pde_t *)malloc(512*sizeof(pde_t)); + + index = (curAddrPDP / ((ulong)KPAGESIZE * 0x40000)) % 512; + + //DebugLog("\t\t\t\tPD %d : %p\n", index, MmPD); + MmPDP[index] = (pde_t *)((ulong)MmPD | PRESENT | READWRITE); + + for (ulong curAddrPD = curAddrPDP; + curAddrPD < (curAddrPDP + ((ulong)KPAGESIZE * 0x40000)) && + curAddrPD < MmVirtLastAddress; + curAddrPD += ((ulong)KPAGESIZE * 0x200)) { + // Create an intry in PD each 2MB + // 0x200 = 512 + + MmPT = (pte_t *)malloc(512*sizeof(pte_t)); + + index = (curAddrPD / ((ulong)KPAGESIZE * 0x200)) % 512; + + //DebugLog("\t\t\t\tPT %d : %p\n", index, MmPT); + MmPD[index] = (pte_t *)((ulong)MmPT | PRESENT | READWRITE); + + for (ulong curAddrPT = curAddrPD; + curAddrPT < (curAddrPD + ((ulong)KPAGESIZE * 0x200)) && + curAddrPT < MmVirtLastAddress; + curAddrPT += (ulong)KPAGESIZE) { + // Create an entry in PT each page of 4KB + + index = (curAddrPT / ((ulong)KPAGESIZE)) % 512; + xedni = (curAddrPT / ((ulong)KPAGESIZE)); + + //DebugLog("\t\t\t\tPage %d : %p\n", index, curAddrPT); + + // STACK GUARD PAGE */ + if ((ulong)curAddrPT == (ulong)BtLoaderInfo.stackEndAddr) { + MmPT[index] = (ulong)curAddrPT | PRESENT; + MmPhysicalPageTable[xedni] = (ulong)curAddrPT; + MmStackGuards[0] = (ulong)curAddrPT; + DebugLog("\tStack Guard at %p\n", curAddrPT); + } + else if ((ulong)curAddrPT == (ulong)BtLoaderInfo.kernelEndAddr) { + MmPT[index] = (ulong)curAddrPT | PRESENT; + MmPhysicalPageTable[xedni] = (ulong)curAddrPT; + MmStackGuards[1] = (ulong)curAddrPT; + DebugLog("\tStack Guard at %p\n", curAddrPT); + } + // SECTION .TEXT PROTECTION + else if ((ulong)curAddrPT >= (ulong)&_text && (ulong)curAddrPT <= (ulong)&_text_end) { + MmPT[index] = (ulong)curAddrPT | PRESENT; + MmPhysicalPageTable[xedni] = (ulong)curAddrPT; + //DebugLog("\tSection .text at %p\n", curAddrPT); + } + // SECTION .DATA PROTECTION + else if ((ulong)curAddrPT >= (ulong)&_data && (ulong)curAddrPT <= (ulong)&_data_end) { + MmPT[index] = (ulong)curAddrPT | PRESENT | WRITETHR | READWRITE | NX; + MmPhysicalPageTable[xedni] = (ulong)curAddrPT; + //DebugLog("\tSection .data at %p\n", curAddrPT); + } + // SECTION .RODATA PROTECTION + else if ((ulong)curAddrPT >= (ulong)&_rodata && (ulong)curAddrPT <= (ulong)&_rodata_end) { + MmPT[index] = (ulong)curAddrPT | PRESENT | WRITETHR | NX; + MmPhysicalPageTable[xedni] = (ulong)curAddrPT; + //DebugLog("\tSection .rodata at %p\n", curAddrPT); + } + // While we're inside the kernel pages + else if ((ulong)curAddrPT <= lastKernelAddr) { + MmPT[index] = (ulong)curAddrPT | PRESENT | READWRITE; + MmPhysicalPageTable[xedni] = (ulong)curAddrPT; + + if ((ulong)curAddrPT == lastKernelAddr) { + //DebugLog("\tLast page of kernel at %p\n", curAddrPT); + } + } + // While we're inside the userspace pages + else if ((ulong)curAddrPT >= USERSPACE) { + MmPT[index] = ((ulong)curAddrPT - diffKernUsr) | PRESENT; // Not present for instance + xedni = (((ulong)curAddrPT - diffKernUsr) / ((ulong)KPAGESIZE)); + MmPhysicalPageTable[xedni] = (ulong)curAddrPT; + + if ((ulong)curAddrPT == USERSPACE) { + DebugLog("\tUserspace at %p:%p\n", curAddrPT, curAddrPT - diffKernUsr); + } + } + else { + MmPT[index] = 0; + } + + KeFlushTlbSingle(curAddrPT); + } + } + } } + lastDirectoryAddr = (ulong)MmPT; - for (volatile ulong i = 0; i < NB_4K; i++) { - MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE; - } + MmLoadPML4((void *)MmPageMapLevel4); + //MmEnableWriteProtect(); - for (volatile ulong i = NB_4K; i < 512 * RAM_MAX; i++) { - // ENOMEM like - if ((ulong)(i* UPAGESIZE) > (ulong)phRamSize) { - break; - } - - MmPD[i] = 0; - MmPD[i] = ((ulong)(i* UPAGESIZE)) | MF_PRESENT | MF_READWRITE | MF_HUGE; - } - - for (volatile int i = 0; i < RAM_MAX; i++) { - MmPDP[i] = (ulong)(&MmPD[i*512])| MF_PRESENT | MF_READWRITE; - } - - MmPML4[0] = (ulong)(&MmPDP[0])| MF_PRESENT | MF_READWRITE; - - MmLoadPML4((void *)MmPML4); - //DebugLog("\tPaging tables initialized at %p, %p\n", &MmPD, &MmPT); - //DebugLog("\tStack Guards at %p, %p\n", MmStackGuards[0], MmStackGuards[1]); + DebugLog("\tPage table size : %u MB\n", (lastDirectoryAddr - firstDirectoryAddr + phDirSize)/MB); } // -// Reloads the page tables +// Get a page from an address // -void MmReloadPaging(void) +static pte_t *MmGetPageDescriptorFromVirtual(void *virtualAddr) { - extern MemoryMap_t memoryMap; - ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize; + ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1)); - - for (volatile ulong i = 0; i < 512 * NB_4K; i++) { - // STACK GUARD PAGE - if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.stackEndAddr) { - MmPT[i] = ((ulong)(i*KPAGESIZE)); - MmStackGuards[0] = ((ulong)(i*KPAGESIZE)); - continue; - } - - // ENOMEM like - if ((ulong)(i*KPAGESIZE) > (ulong)phRamSize) { - break; - } - - // STACK GARD PAGE - if ((ulong)(i*KPAGESIZE) == (ulong)BtLoaderInfo.kernelEndAddr) { - MmPT[i] = ((ulong)(i*KPAGESIZE)); - MmStackGuards[1] = ((ulong)(i*KPAGESIZE)); - continue; - } - - MmPT[i] = ((ulong)(i*KPAGESIZE)) | MF_PRESENT | MF_READWRITE; + if (virtAddrPage > MmVirtLastAddress) { + KeStartPanic("MmSetPage() Out of bound of the address space !"); } - for (volatile ulong i = 0; i < NB_4K; i++) { - MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE; - } + pdpe_t *pdp = (pdpe_t*)((ulong)MmPageMapLevel4[(virtAddrPage / ((ulong)KPAGESIZE * 0x8000000)) % 512] & ~(KPAGESIZE - 1)); + //DebugLog("pdp\t: %p\n", pdp); + pde_t *pd = (pde_t*)( (ulong)pdp[(virtAddrPage / ((ulong)KPAGESIZE * 0x40000)) % 512] & ~(KPAGESIZE - 1)); + //DebugLog("pd\t: %p\n", pd); + pte_t *pt = (pte_t*)( (ulong)pd[(virtAddrPage / ((ulong)KPAGESIZE * 0x200)) % 512] & ~(KPAGESIZE - 1)); + //DebugLog("pt\t: %p\n", pt); - for (volatile ulong i = NB_4K; i < 512 * RAM_MAX; i++) { - // ENOMEM like - if ((ulong)(i* UPAGESIZE) > (ulong)phRamSize) { - break; - } + pte_t *page = &pt[(virtAddrPage / ((ulong)KPAGESIZE)) % 512]; + //DebugLog("page (with flags): %p\n", page); - MmPD[i] = 0; - MmPD[i] = ((ulong)(i* UPAGESIZE)) | MF_PRESENT | MF_READWRITE | MF_HUGE; - } - - for (volatile int i = 0; i < RAM_MAX; i++) { - MmPDP[i] = (ulong)(&MmPD[i*512])| MF_PRESENT | MF_READWRITE; - } - - MmPML4[0] = (ulong)(&MmPDP[0])| MF_PRESENT | MF_READWRITE; - - MmLoadPML4((void *)MmPML4); - DebugLog("\tPaging tables initialized at %p, %p\n", &MmPD, &MmPT); - DebugLog("\tStack Guards at %p, %p\n", MmStackGuards[0], MmStackGuards[1]); + return page; } + +// +// Translates a virtual address to its physical equivalent +// +void *MmTransVirtToPhyAddr(void* virtualAddr) +{ + ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1)); + pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr); + + if (*page == (*page & ~(KPAGESIZE - 1))) { + return NULL; + } + + return (void*)((*page & ~(KPAGESIZE - 1))+ ((ulong)virtualAddr - (ulong)virtAddrPage)); +} + +void *MmTransPhyToVirtAddr(void* physicalAddr) +{ + ulong phyAddrPage = (ulong)physicalAddr & ( ~(KPAGESIZE - 1)); + return (void*)( MmPhysicalPageTable[(ulong)physicalAddr + / ((ulong)KPAGESIZE) + + ((ulong)physicalAddr - phyAddrPage) ] ); +} + +// +// Add flags to a page +// +void MmSetPage(void* virtualAddr, ulong flags) +{ + pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr); + + *page |= flags; + + KeFlushTlbSingle(*page); +} + +// +// Remove flags of a page +// +void MmUnsetPage(void* virtualAddr, ulong flags) +{ + pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr); + + *page &= (~flags); + + KeFlushTlbSingle(*page); +} + +// +// Map a page in memory +// +void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags) +{ + pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr); + + *page = ((ulong)physicalAddr & ~(KPAGESIZE - 1)) | flags; + + KeFlushTlbSingle(*page); +} + +// +// Unmap a page in memory +// +void MmUnmapPage(void* virtualAddr) +{ + pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr); + + *page = 0; + + KeFlushTlbSingle(*page); +} + +// +// Kernel Page allocator +// +void *MmKAllocPageBlock(void *start) { + pte_t *startPage = MmGetPageDescriptorFromVirtual(start); + + //for (ulong curPage = 0; curPage < ) + + return NULL; +} + +// +// User page allocator +// +void *MmUAllocPageBlock(void *start) { + pte_t *startPage = MmGetPageDescriptorFromVirtual(start); + + //for (ulong curPage = 0; curPage < ) + + return NULL; +} + +//----------- + +// // Returns the rank of the Stack Guards +// void *MmGetStackGuards(char rank) { return (void *)MmStackGuards[(int)rank]; } -// Returns an address corresponding to the PT rank -void *MmTranslateKPageToAddr(void *rank) -{ - return (void *)MmPT[(ulong)rank]; -} - // // Page fault handler // static void PagingHandler(ISRFrame_t *regs) { ulong StackGuardOne = (ulong)MmGetStackGuards(0); - if (regs->cr2 >= StackGuardOne && (regs->rsp + 4*KB >= regs->cr2)) { + ulong StackGuardTwo = (ulong)MmGetStackGuards(1); + if ((regs->cr2 >= StackGuardOne) && (regs->cr2 <= StackGuardOne + KPAGESIZE) && (regs->rsp <= regs->cr2)) { bprintf(BStdOut, "\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Stack Underflow\n\n" - " Double Fault Error code : %#x (%b)\n" + " Page Fault Error code : %#x (%b)\n" " Stack Guard bypassed : %#x", VGA_COLOR_LIGHT_RED, @@ -182,19 +340,68 @@ static void PagingHandler(ISRFrame_t *regs) regs->ErrorCode, StackGuardOne ); - } else { - //XXX page fault - bprintf(BStdOut, "\n\n%CPANIC\n[ISR 0x%x] Irrecoverable Kernel Page Fault at %p\n\n" - " Error code : 0x%x (%b)", + } else if ((regs->cr2 >= StackGuardTwo) && (regs->cr2 <= StackGuardTwo + KPAGESIZE) && (regs->rsp >= regs->cr2)) { + bprintf(BStdOut, + "\n\n%CPANIC\n[ISR 0x8] Irrecoverable Kernel Stack Overflow\n\n" + " Page Fault Error code : %#x (%b)\n" + " Stack Guard bypassed : %#x", + + VGA_COLOR_LIGHT_RED, + regs->ErrorCode, + regs->ErrorCode, + StackGuardTwo + ); + } else if (regs->cr2 == 0) { + bprintf(BStdOut, + "\n\n%CPANIC\n[ISR 0x8] Null vector exception !\n\n" + " Page Fault Error code : %#x (%b)\n", VGA_COLOR_LIGHT_RED, regs->intNo, + regs->ErrorCode, + regs->ErrorCode + ); + } else if (regs->cr2 >= MmVirtLastAddress || regs->cr2 <= 0) { + bprintf(BStdOut, + "\n\n%CPANIC\n[ISR 0x8] Out of bound of the address space at %p !\n\n" + " End of the address space : %p\n" + " Page Fault Error code : %#x (%b)\n", + + VGA_COLOR_LIGHT_RED, + regs->cr2, + MmVirtLastAddress, + regs->ErrorCode, + regs->ErrorCode + ); + } else { + //XXX page fault + bprintf(BStdOut, "\n\n%CPANIC\n[ISR 0x8] Irrecoverable Page Fault at %p\n\n" + " Error code : 0x%x (%b)", + + VGA_COLOR_LIGHT_RED, regs->cr2, regs->ErrorCode, regs->ErrorCode ); } + bprintf(BStdOut, "\n Description : "); + + if (regs->ErrorCode & PRESENT) { + bprintf(BStdOut, "Page-protection violation "); + } else { + bprintf(BStdOut, "Non present page "); + } + if (regs->ErrorCode & READWRITE) { + bprintf(BStdOut, "during write access "); + } else { + bprintf(BStdOut, "during read access "); + } + if (regs->ErrorCode & (1 << 3)) + bprintf(BStdOut, "from userspace "); + if (regs->ErrorCode & (1 << 4)) + bprintf(BStdOut, "after instruction fetching "); + KeBrkDumpRegisters(regs); BStdOut->flusher(BStdOut); diff --git a/kaleid/kernel/sh/shell.c b/kaleid/kernel/sh/shell.c index 99fde03..c9d16ce 100644 --- a/kaleid/kernel/sh/shell.c +++ b/kaleid/kernel/sh/shell.c @@ -126,9 +126,8 @@ void ShStartShell(void) default: - while (IoGetScroll() > 0) { - IoScrollDown(); - } + IoSetScroll(1); + IoScrollDown(); *bufptr++ = (char)ch; diff --git a/kaleid/kernel/sh/testcmds.c b/kaleid/kernel/sh/testcmds.c index 50661fc..f528b71 100644 --- a/kaleid/kernel/sh/testcmds.c +++ b/kaleid/kernel/sh/testcmds.c @@ -55,6 +55,19 @@ error_t CmdArgs(int argc, char **argv, char *cmdline) return EOK; } +error_t CmdAtoi(int argc, char **argv, char *cmdline) +{ + int i; + + KernLog("cmdline: '%s'\nargc: %d\n", cmdline, argc); + + for (i = 0; i < argc; i++) { + KernLog("argv[%d]: '%u'\n", i, atoi(argv[i])); + } + + return EOK; +} + error_t CmdDumpATASect(int argc, char **argv, char *cmdline) { char sector[512] = {0}; @@ -96,6 +109,42 @@ error_t CmdDumpATASect(int argc, char **argv, char *cmdline) return EOK; } +error_t CmdDumpMem(int argc, char **argv, char *cmdline) +{ + char sector[1024] = {0}; + char *address = (char*)strtoul(argv[1], NULL, 16); + int nb = 1; //atoi(argv[2]); + int x = 0; + int step = 16; + + KernLog("Address begin: %p\n", address); + + for (int i = 0; i < 1024*nb; i++) { + sector[i] = *address++; + } + + while(x < 1024*nb) { + KernLog("%C", shcol); + for (int i = 0; i < step; i++) { + KernLog("%02x ", (uchar)sector[i+x]); + } + KernLog(" %C ", VGA_COLOR_LIGHT_BLUE); + for (int i = 0; i < step; i++) { + if (isprint(sector[i+x])) + KernLog("%c", + sector[i+x] + ); + else + KernLog("%c", 0); + } + KernLog("\n"); + x += step; + } + + KernLog("\n\n"); + return EOK; +} + error_t CmdFloatDiv(int argc, char **argv, char *cmdline) { double a = (double)atoi(argv[1]); @@ -140,22 +189,79 @@ error_t CmdHelpTest(int argc, char **argv, char *cmdline) return EOK; } -error_t CmdPF(int argc, char **argv, char *cmdline) +error_t CmdPageTranslateVirtToPhy(int argc, char **argv, char *cmdline) { - char *address = (void*)(ulong)atoi(argv[1]); + void *address = (void*)atoul(argv[1]); - KernLog("Provoking Page Fault at %#x\n", address); + if (!(void*)strtoul(argv[1], NULL, 16)) { + KernLog("No argument : translating the userspace address\n"); + address = (void *)0x80000000; + } - *address = 1; + void *translation = MmTransVirtToPhyAddr(address); - KernLog("No page fault : address was valid/present\n"); + KernLog("Translation of %p is %p\n", address, translation); + return EOK; +} + +enum +{ + PRESENT = 1 << 0, + READWRITE = 1 << 1, + USERMODE = 1 << 2, + WRITETHR = 1 << 3, + CACHEDIS = 1 << 4, + ACCESSED = 1 << 5, + DIRTY = 1 << 6, + HUGE = 1 << 7, + NX = 1UL << 63 +}; + +error_t CmdPageMap(int argc, char **argv, char *cmdline) +{ + void *virtual = (void*)strtoul(argv[1], NULL, 16); + void *physical = (void*)strtoul(argv[2], NULL, 16); + + MmMapPage(virtual, physical, PRESENT | READWRITE); return EOK; } -error_t CmdReloadPage(int argc, char **argv, char *cmdline) +error_t CmdPageUnmap(int argc, char **argv, char *cmdline) { - MmReloadPaging(); + void *virtual = (void*)strtoul(argv[1], NULL, 16); + + MmUnmapPage(virtual); + + return EOK; +} + +error_t CmdPageTranslatePhyToVirt(int argc, char **argv, char *cmdline) +{ + void *address = (void*)strtoul(argv[1], NULL, 16); + + /* if (!(void*)atoul(argv[1])) { */ + /* address = (ulong *)0x80000000; */ + /* } */ + + void *translation = MmTransPhyToVirtAddr(address); + + KernLog("Translation of %p is %p\n", address, translation); + return EOK; +} + +error_t CmdPF(int argc, char **argv, char *cmdline) +{ + ulong *address = (ulong*)(ulong)strtoul(argv[1], NULL, 16); + + KernLog("Provoking Page Fault at %#x\n", address); + + KernLog("It contained %#x\n", *address); + *address = 1; + KernLog("Now it contains %#x\n", *address); + + KernLog("No page fault : address was valid/present\n"); + return EOK; } @@ -199,11 +305,18 @@ error_t CmdTimerTest(int argc, char **argv, char *cmdline) static Command_t testcmdtable[] = { { "args", CmdArgs, "Print command line" }, + { "atoi", CmdAtoi, "Print command line atoised" }, { "dmpsec", CmdDumpATASect, "Dump an ATA sector on screen" }, + { "dmp", CmdDumpMem, "Dump 1MB of memory starting from addr"}, { "help", CmdHelpTest, "Show this message" }, { "div", CmdFloatDiv, "Float div. Usage : div a b. Returns a/b"}, + { "transvtp", CmdPageTranslateVirtToPhy, "Translate a virtual to" + " physical address (paging)"}, + { "transptv", CmdPageTranslatePhyToVirt, "Translate a physical to" + " virtual address (paging)"}, + { "pmap", CmdPageMap, "Map a page to given physical addr" }, + { "punmap", CmdPageUnmap, "Unmap a page" }, { "pf", CmdPF, "Provoke a PF. Usage: pfault
"}, - { "rpag", CmdReloadPage, "Reload the pages directory" }, { "shell", CmdShell, "Start a new shell (nested)", }, { "stkov", CmdStackOverflow, "Provoke a stack overflow" }, { "stkun", CmdStackUnderflow, "Provoke a stack underflow" },