diff --git a/Makefile b/Makefile index 86a11ad..7e44091 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ # Debug mode ?= debug +ram ?= 8G # Programs ASM=nasm @@ -91,8 +92,8 @@ LibCDep=$(patsubst %.c,$(KOBJDIR)/%.d,$(LibCSources)) LibCObj += $(KOBJDIR)/libc/atoi.o $(KOBJDIR)/libc/itoa.o # Kernel sources -KernSources = kernel/ke/cpuid.c \ - kernel/ke/idt.c kernel/init/init.c \ +KernSources = kernel/ke/cpuid.c kernel/mm/paging.c \ + kernel/ke/idt.c kernel/init/init.c \ kernel/init/table.c kernel/io/cursor.c \ kernel/ke/log.c kernel/io/vga.c \ kernel/ke/panic.c kernel/mm/map.c \ @@ -161,6 +162,15 @@ $(KOBJDIR)/kernel/ke/idt.o: $(KALEIDDIR)/kernel/ke/idt.c \ @rm -f $@.1 $@.2 @echo ${CL2}[$@] ${CL}Compiled.${CL3} +$(KOBJDIR)/kernel/mm/paging.o: $(KALEIDDIR)/kernel/mm/paging.c \ + $(KALEIDDIR)/kernel/mm/paging.asm | $(KOBJDIR) + @mkdir -p $(shell dirname $@) + @$(ASM) $(ASMFLAGS) $(KALEIDDIR)/kernel/mm/paging.asm -o $@.1 + @$(KCC) $< -o $@.2 + @$(LD) $(LDFLAGS) -r $@.1 $@.2 -o $@ + @rm -f $@.1 $@.2 + @echo ${CL2}[$@] ${CL}Compiled.${CL3} + $(KOBJDIR)/kernel/mm/gdt.o: $(KALEIDDIR)/kernel/mm/gdt.c \ $(KALEIDDIR)/kernel/mm/gdt.asm | $(KOBJDIR) @mkdir -p $(shell dirname $@) @@ -193,23 +203,17 @@ $(KOBJDIR)/%.o: %.c | $(KOBJDIR) @echo ${CL2}[$@] ${CL}Compiled.${CL3} test: all - @qemu-system-x86_64 -cpu core2duo -soundhw pcspk -rtc base=localtime -m 4G -hda $(BUILDDIR)/bin/disk.img \ - -d cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log & + @qemu-system-x86_64 -cpu core2duo -soundhw pcspk -rtc base=localtime -m $(ram) -hda $(BUILDDIR)/bin/disk.img \ + -d cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log & test32: all - @qemu-system-i386 -hda $(BUILDDIR)/bin/disk.img -d cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log & - -debug: all - @qemu-system-x86_64 -soundhw pcspk -rtc base=localtime -m 64M -hda $(BUILDDIR)/bin/disk.img -no-reboot \ - -no-shutdown -d cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log & - @ndisasm $(BINDIR)/kaleid -o 0x00100000 -b 64 > $(BUILDDIR)/kaleid64_disasm.asm - @ndisasm $(BINDIR)/kaleid -o 0x00100000 -b 32 > $(BUILDDIR)/kaleid32_disasm.asm + @qemu-system-i386 -m $(ram) -hda $(BUILDDIR)/bin/disk.img -d \ + cpu_reset,guest_errors,pcall,int 2> $(BUILDDIR)/qemu.log & gdb: all - @qemu-system-x86_64 -m 64M -soundhw pcspk -rtc base=localtime -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 + @setsid qemu-system-x86_64 -m $(ram) -soundhw pcspk -rtc base=localtime \ + -hda $(BUILDDIR)/bin/disk.img -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" \ @@ -217,10 +221,8 @@ gdb: all -ex "break BtStartKern" \ ddd: all - @qemu-system-x86_64 -m 64M -hda $(BUILDDIR)/bin/disk.img -no-reboot -soundhw pcspk \ + @setsid qemu-system-x86_64 -m $(ram) -hda $(BUILDDIR)/bin/disk.img -no-reboot -soundhw pcspk \ -no-shutdown -d cpu_reset,guest_errors,pcall,int -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 diff --git a/boot/loader/mem/management.inc b/boot/loader/mem/management.inc index e29a2b1..f3ae8d6 100644 --- a/boot/loader/mem/management.inc +++ b/boot/loader/mem/management.inc @@ -48,11 +48,11 @@ Setup_paging: cmp ecx, MAX_MEMORY ; PDP table is mapped if MAX_MEMORY jne .map_pdp_table ; else map the next entry - ;; Map each PD entry to a 'huge' 2MiB page + ;; Map each PD entry to a 'huge' 4MiB page mov ecx, 0x0 ; counter variable .map_pd_table: - ;; map ecx-th PD entry to a huge page that starts at address 2MiB*ecx + ;; map ecx-th PD entry to a huge page that starts at address 4MiB*ecx mov eax, 0x200000 mul ecx ; start address of ecx-th page or eax, 1 << 7 | 1 << 1 | 1 << 0 ; present + writable + huge @@ -60,6 +60,7 @@ Setup_paging: inc ecx cmp ecx, 512 * MAX_MEMORY ; PD table is mapped if 512 jne .map_pd_table ; else map the next entry + ret ; ---------------------------------------------------------------------------- ; ; Enable long mode and paging ; @@ -79,6 +80,8 @@ Go64: mov ecx, 0xC0000080 ; Address of MSR rdmsr ; Read MSR or eax, 1 << 8 ; LME = 1. (Long Mode Enable) + or eax, 1 << 11 ; NXE = 1 (No execute bit) + wrmsr ; Write MSR ;; Enable paging @@ -128,16 +131,16 @@ InitStack: push rdi ;; Begin address to fill and length - mov qword [newStackEnd], KERNEL_STACK - mov qword [newKernelEnd], kernelEnd + mov rdi, kernelEnd - mov qword [kernelEnd], qword 0xbad0bad - mov rdi, kernelEnd + 16 - mov rcx, (KERNEL_STACK - (kernelEnd + 16)) ; The Stack can begin at - ; kernelEnd + 16 in order to not overwrite the - ; kernel by pushing values (grows downward) + ;; Alignes it to 4096o / FUTURE PAGE FRAME + shr rdi, 12 + shl rdi, 12 + add rdi, 0x1000 - ;; XXX : align the stack to 16bytes + ;; Passing info to kernel + mov qword [newKernelEnd], rdi + mov rcx, KERNEL_STACK ; counter ;; If bit 0 is on, fill one byte sar rcx, 1 ; Shift bit 0 into CY @@ -150,12 +153,16 @@ InitStack: stosw ;; We are dword aligned and if bit 2 was on fill another dword - sar rcx, 1 ; Shift bit 2 into CY - jnc $ + 3 + sar rcx, 1 ; Shift bit 2 into CY + jnc $ + 3 stosd ;; RCX now equals the number of qwords to fill - repnz stosq ; Finish by writing RCX qwords. + repnz stosq ; Finish by writing RCX qwords. + + ;; New info for the kernel + mov qword [newStackEnd], rdi + mov rsp, rdi pop rdi pop rcx diff --git a/boot/loader/mem/structures.inc b/boot/loader/mem/structures.inc index 397cb4a..e538bea 100644 --- a/boot/loader/mem/structures.inc +++ b/boot/loader/mem/structures.inc @@ -30,7 +30,7 @@ global newKernelEnd global newStackEnd [section .text] -KERNEL_STACK equ (kernelEnd + 16) + 16 * 1024 ; 16KB of stack +KERNEL_STACK equ 16 * 1024 ; 16KB of stack newKernelEnd dq 0x0 newStackEnd dq 0x0 diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index 3d775d2..15f3333 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -24,6 +24,8 @@ #include "init.h" +void MmInitPaging(void); + // // Entry point of the Kaleid kernel // @@ -46,14 +48,13 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg) // Memory MmInitMemoryMap(); + MmInitHeap(); + MmInitPaging(); // Interrupts launching KeSetupIDT(); KeEnableIRQs(); - // Several inits - MmInitHeap(); - // Start drivers KeEnableRTC(); IoEnableKeyb(); diff --git a/kaleid/kernel/mm/map.c b/kaleid/kernel/mm/map.c index 3145126..edf5352 100644 --- a/kaleid/kernel/mm/map.c +++ b/kaleid/kernel/mm/map.c @@ -137,8 +137,8 @@ void *MmGetFirstAvailZone(void *start) { void *current = 0; // Because the kernel is the kernel - if ((ulong)start < (ulong)BtLoaderInfo.stackEndAddr+16) { - return MmGetFirstAvailZone(BtLoaderInfo.stackEndAddr+16); + if ((ulong)start < (ulong)BtLoaderInfo.stackEndAddr+4096) { + return MmGetFirstAvailZone(BtLoaderInfo.stackEndAddr+4096); } // Search the zone where the start address is diff --git a/kaleid/kernel/mm/paging.asm b/kaleid/kernel/mm/paging.asm new file mode 100644 index 0000000..8b57010 --- /dev/null +++ b/kaleid/kernel/mm/paging.asm @@ -0,0 +1,27 @@ + +global MmEnableWriteProtect +global MmDisableWriteProtect +global MmLoadPML4 + +MmEnableWriteProtect: + push rax + mov rax, cr0 + or rax, 1<<16 + mov cr0, rax + pop rax + ret + +MmDisableWriteProtect: + push rax + mov rax, cr0 + and rax, ~(1<<16) + mov cr0, rax + pop rax + ret + +MmLoadPML4: + push rax + mov rax, rdi + mov cr3, rax + pop rax + ret diff --git a/kaleid/kernel/mm/paging.c b/kaleid/kernel/mm/paging.c new file mode 100644 index 0000000..10ddbe0 --- /dev/null +++ b/kaleid/kernel/mm/paging.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include + +#define PAGESIZE (4 * KB) + + +// Page directory pointer offset +typedef ulong pdpe_t; + +// Page directory offset +typedef ulong pde_t; + +// Page table entry +typedef ulong pte_t; + +// paging.asm +void MmLoadPML4(void *); +void MmEnableWriteProtect(void); +void MmDisableWriteProtect(void); + +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 16 +#define NB_4K 150 + // * 2 MB + +//----------- + +volatile pdpe_t MmPML4[512] __attribute__((__aligned__(4096))); + +volatile pde_t MmPDP[512] __attribute__((__aligned__(4096))); + +volatile pde_t MmPD[512 * RAM_MAX] __attribute__((__aligned__(4096)));; + +volatile pte_t MmPT[512 * NB_4K] __attribute__((__aligned__(4096)));; + +volatile ulong MmStackGuards[2] = { 0 }; + +// +// Creates our new page table structure and loads it +void MmInitPaging(void) +{ + extern MemoryMap_t memoryMap; + uint 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)); + + for (int i = 0; i < 512 * NB_4K; i++) { + // STACK GUARD PAGE + if ((ulong)i*4096 == (ulong)BtLoaderInfo.stackEndAddr) { + MmPT[i] = ((ulong)i * 4096); + MmStackGuards[0] = i; + continue; + } + + // ENOMEM like + if ((ulong)i*4096 > (ulong)phRamSize) { + MmPT[i] = ((ulong)i * 4096) | MF_READWRITE;// | MF_NX; + continue; + } + + // STACK GARD PAGE + if ((ulong)i*4096 == (ulong)BtLoaderInfo.kernelEndAddr) { + MmPT[i] = ((ulong)i * 4096); + MmStackGuards[1] = i; + continue; + } + + MmPT[i] = ((ulong)i * 4096) | MF_PRESENT | MF_READWRITE; + } + + for (int i = 0; i < NB_4K; i++) { + MmPD[i] = (ulong)(&MmPT[i*512])| MF_PRESENT | MF_READWRITE; + } + + for (int i = NB_4K; i < 512 * RAM_MAX; i++) { + // ENOMEM like + if ((ulong)i* 2048 * 1024 > (ulong)phRamSize) { + MmPD[i] = ((ulong)i * 2048 * 1024) | MF_READWRITE;// | MF_NX; + continue; + } + + MmPD[i] = ((ulong)i * 2048 * 1024) | MF_PRESENT | MF_READWRITE | MF_HUGE; + } + + for (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); +} diff --git a/kaleid/kernel/sh/shcmds.c b/kaleid/kernel/sh/shcmds.c index 3098467..eaed746 100644 --- a/kaleid/kernel/sh/shcmds.c +++ b/kaleid/kernel/sh/shcmds.c @@ -146,7 +146,7 @@ error_t CmdMemUsage(int argc, char **argv, char *cmdline) KernLog("Kernel stack\n"); KernLog("\tstarts at:\t\t%p (%4luMB + %4luKB + %4luB)\n", - BtLoaderInfo.kernelEndAddr, + BtLoaderInfo.stackEndAddr, _ADDR_TO_MB((size_t)BtLoaderInfo.stackEndAddr), _ADDR_TO_KB((size_t)BtLoaderInfo.stackEndAddr), _ADDR_TO_B((size_t)BtLoaderInfo.stackEndAddr)); @@ -224,14 +224,20 @@ error_t CmdDie(int argc, char **argv, char *cmdline) error_t CmdPF(int argc, char **argv, char *cmdline) { - *((char*)0xDEADBEEF0) = 1; + if (argc != 2) + return EINVAL; + + ulong address = atoul(argv[1]); + KernLog("print: %s, %d\n", argv[1], address); + + *((char*)address) += 1; return EOK; } extern void KeStartShell(void); -error_t CmdShell(int argc, char **argv, char *cmdline) +error_t CmdStackOverflow(int argc, char **argv, char *cmdline) { - KeStartShell(); + CmdStackOverflow(0, 0, 0); return EOK; } @@ -239,20 +245,20 @@ error_t CmdShell(int argc, char **argv, char *cmdline) Command_t cmdtable[] = { - { "beep", CmdBeep, "Make a beep" }, - { "cls", CmdClear, "Clears standard output" }, - { "date", CmdDate, "Print date" }, - { "die", CmdDie, "Die painfully" }, - { "exit", CmdQuit, "Initiate shutdown" }, - { "help", CmdHelp, "Show this message" }, - { "march", CmdStarWars, "Play the Imperial March"}, - { "mmap", CmdMemMap, "Show memory map" }, - { "musage", CmdMemUsage, "Show memory statistics" }, - { "pfault", CmdPF, "Provokes a PF" }, - { "pstest", CmdPsTest, "Scheduler test routine" }, - { "quit", CmdQuit, "Alias for 'exit'" }, - { "shell", CmdShell, "New shell instance" }, - { "time", CmdTime, "Print time" }, + { "beep", CmdBeep, "Make a beep" }, + { "cls", CmdClear, "Clears standard output" }, + { "date", CmdDate, "Print date" }, + { "die", CmdDie, "Die painfully" }, + { "exit", CmdQuit, "Initiate shutdown" }, + { "help", CmdHelp, "Show this message" }, + { "march", CmdStarWars, "Play the Imperial March"}, + { "mmap", CmdMemMap, "Show memory map" }, + { "musage", CmdMemUsage, "Show memory statistics" }, + { "pfault", CmdPF, "Provoke a PF. Usage : pfault
" }, + { "pstest", CmdPsTest, "Scheduler test routine" }, + { "quit", CmdQuit, "Alias for 'exit'" }, + { "so", CmdStackOverflow, "Provoke a stack overflow" }, + { "time", CmdTime, "Print time" }, { NULL, NULL, NULL } }; diff --git a/kaleid/libc/mem.c b/kaleid/libc/mem.c index ae8f2d5..7107bd0 100644 --- a/kaleid/libc/mem.c +++ b/kaleid/libc/mem.c @@ -36,7 +36,11 @@ void *malloc(size_t n) void *ptr; error_t rc; +#ifndef _KALEID_KERNEL rc = KalAllocMemory(&ptr, n); +#else + rc = KalAllocMemoryEx(&ptr, n, M_ZEROED, 0); +#endif if (rc > 0) seterrno(rc); return ptr;