From 4caefd028a419a19ce9dfa84083df270b6e43055 Mon Sep 17 00:00:00 2001 From: Adrien Bourmault Date: Mon, 25 Mar 2019 23:10:06 +0100 Subject: [PATCH] Stack & heap stuff --- ProjectTree | 22 +++++++++-- boot/loader/loader.asm | 22 +++++++---- boot/loader/mem/management.inc | 33 ++++++++++++++++ boot/loader/mem/structures.inc | 9 ++++- boot/loader/multiboot/header.inc | 1 - build/kernel.ld | 4 +- kaleid/include/kernel/base.h | 9 +++++ kaleid/include/kernel/cpu.h | 66 +++++++++++++++++++++++++++++++- kaleid/include/kernel/heap.h | 3 +- kaleid/kernel/cpu/cpuid.c | 10 ++++- kaleid/kernel/cpu/idt.c | 37 ++++++++++++++++++ kaleid/kernel/init/init.c | 16 ++------ kaleid/kernel/mm/heap.c | 24 ++++++++---- kaleid/kernel/mm/malloc.c | 3 +- kaleid/kernel/mm/stack.c | 23 +++++++++++ 15 files changed, 243 insertions(+), 39 deletions(-) create mode 100644 kaleid/kernel/cpu/idt.c create mode 100644 kaleid/kernel/mm/stack.c diff --git a/ProjectTree b/ProjectTree index f44e941..4dee93e 100644 --- a/ProjectTree +++ b/ProjectTree @@ -56,6 +56,17 @@ │   │   │   └── loader.o │   │   └── kaleid │   │   ├── kernel +│   │   │   ├── init +│   │   │   │   ├── init.o +│   │   │   │   └── table.o +│   │   │   ├── io +│   │   │   │   ├── cursor.o +│   │   │   │   ├── term.o +│   │   │   │   └── vga.o +│   │   │   ├── ke +│   │   │   │   └── panic.o +│   │   │   ├── bprint.o +│   │   │   ├── bput.o │   │   │   ├── buf.o │   │   │   ├── cpuid.o │   │   │   ├── cursor.o @@ -64,6 +75,7 @@ │   │   │   ├── malloc.o │   │   │   ├── map.o │   │   │   ├── panic.o +│   │   │   ├── sched.o │   │   │   ├── table.o │   │   │   ├── term.o │   │   │   └── vga.o @@ -131,9 +143,12 @@ │   │   └── kalext.h │   └── kernel │   ├── buf +│   │   ├── bprint.c +│   │   ├── bput.c │   │   └── buf.c │   ├── cpu -│   │   └── cpuid.c +│   │   ├── cpuid.c +│   │   └── idt.c │   ├── init │   │   ├── init.c │   │   └── table.c @@ -147,7 +162,8 @@ │   ├── mm │   │   ├── heap.c │   │   ├── malloc.c -│   │   └── map.c +│   │   ├── map.c +│   │   └── stack.c │   └── proc │   ├── Makefile │   └── sched.c @@ -162,4 +178,4 @@ ├── qemu.log └── Readme.md -28 directories, 109 files +31 directories, 122 files diff --git a/boot/loader/loader.asm b/boot/loader/loader.asm index 0e56cdc..0a3fc44 100644 --- a/boot/loader/loader.asm +++ b/boot/loader/loader.asm @@ -44,7 +44,7 @@ MB_header: dd MB_HEADER_MAGIC dd MB_HEADER_FLAGS dd CHECKSUM - times 5 dd 0x0 + times 5 dd 0x0 ; The unused section (provided for a.out) dd MB_VIDEO_MODE dd MB_VIDEO_WIDTH dd MB_VIDEO_HEIGHT @@ -52,7 +52,7 @@ MB_header: [section .text] -;;MULTIBOOT POINT ENTRY FOR GRUB ------------------------------------------- ;; +;;MULTIBOOT POINT ENTRY FOR GRUB -------------------------------------------- ;; MB_start: mov esp, KERNEL_STACK ; Setup the stack push 0 ; Reset EFLAGS @@ -133,8 +133,9 @@ lbegin: [BITS 64] -x64_K db "Now in x64 long mode", 0x0A, 0x0D, 0x0 +x64_K db "64 bits long mode activated !", 0x0A, 0x0D, 0x0 GoKernel db "Launching Kernel...", 0 +GoStack db "Initializing the stack...", 0x0A, 0x0D, 0x0 nokernel db 219, 219, 219, " Error 05 : Kernel returns",0 _loader64: @@ -154,14 +155,21 @@ _loader64: mov bl, 0x0A mov esi, x64_K call write + + ;; Initialize the stack + mov bl, 0x0F + mov esi, GoStack + call write + + call tritemporize ; Let time to see + call InitStack + + ;; Launch the kernel ! mov bl, 0x0F mov esi, GoKernel call write - ;; Launch the kernel ! - ;; XXX CHECK THE RAM BEFORE CALLING KERNEL ! - call tritemporize ; Let time to see - + mov qword [newKernelEnd], KERNEL_STACK mov rdi, [mbInfo] mov rsi, [mbMagic] call BtStartKern diff --git a/boot/loader/mem/management.inc b/boot/loader/mem/management.inc index b44bf4f..cfdf3c4 100644 --- a/boot/loader/mem/management.inc +++ b/boot/loader/mem/management.inc @@ -106,3 +106,36 @@ CheckA20: .A20_err: mov ax, "04" ; ERROR 04 : A20 line failed jmp Error + +[BITS 64] +; ---------------------------------------------------------------------------- ; +; Initilizes the stack ; +; ---------------------------------------------------------------------------- ; +InitStack: + xor rax, rax ; "Fill pattern" + push rcx + push rdi + + ;; Begin address to fill and length + mov rdi, kernelEnd + mov rcx, KERNEL_STACK - kernelEnd - 16 + ; stop before the return address + + ;; If bit 0 is on, fill one byte + sar rcx, 1 ; Shift bit 0 into CY + jnc $ + 3 + stosb + ;; We are word aligned and if bit 1 was on fill another word + sar rcx, 1 ; Shift bit 1 into CY + jnc $ + 4 + stosw + ;; We are dword aligned and if bit 2 was on fill another dword + 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. + + pop rdi + pop rcx + ret diff --git a/boot/loader/mem/structures.inc b/boot/loader/mem/structures.inc index 0c7bd8b..dc1c607 100644 --- a/boot/loader/mem/structures.inc +++ b/boot/loader/mem/structures.inc @@ -24,6 +24,13 @@ ;=----------------------------------------------------------------------------=; [BITS 32] +extern kernelEnd +global newKernelEnd + +[section .text] +KERNEL_STACK equ kernelEnd + 4096 * 2 * 1024 ; 8MB of stack +newKernelEnd dq 0x0 + [section .rodata] ;; GDT WITH DOC ALIGN 4096 @@ -43,6 +50,7 @@ GDT64: dw $ - GDT64 - 1 dq GDT64 + ;; EMPTY PAGE TABLES (identity of the first 1GiB) [section .bss] ALIGN 4096 @@ -52,4 +60,3 @@ PDP_table: resb 4096 PD_table: resb 4096 - diff --git a/boot/loader/multiboot/header.inc b/boot/loader/multiboot/header.inc index 0cfea0c..e7a8b1c 100644 --- a/boot/loader/multiboot/header.inc +++ b/boot/loader/multiboot/header.inc @@ -36,4 +36,3 @@ MB_HEADER_MAGIC equ 0x1badb002 MB_GRUB_MAGIC equ 0x2badb002 MB_HEADER_FLAGS equ MB_AOUT_KLUDGE|MB_ALIGN|MB_MEMINFO|MB_VIDEOINFO CHECKSUM equ -(MB_HEADER_MAGIC + MB_HEADER_FLAGS) -KERNEL_STACK equ 0x00200000 ; Stack starts at the 2mb address & grows down diff --git a/build/kernel.ld b/build/kernel.ld index 50a5d81..7500a25 100644 --- a/build/kernel.ld +++ b/build/kernel.ld @@ -61,10 +61,10 @@ SECTIONS { *(.rodata) /* all rodata sections from all files */ } - kernelEnd = .; - /DISCARD/ : { *(.comment) } + + kernelEnd = .; } diff --git a/kaleid/include/kernel/base.h b/kaleid/include/kernel/base.h index 7ae02d7..2d7534b 100644 --- a/kaleid/include/kernel/base.h +++ b/kaleid/include/kernel/base.h @@ -74,6 +74,15 @@ struct Processor_t // CPU number, index in CPU list int index; + // CPU APIC id + int apicId; + // CPU Vendor String (always 12 characters) + char vendorStr[12]; + // CPU Model code (enum in cpu.h) + int modelCode; + // CPU Features flag + uint featureFlag; + // Number of ticks since boot time ulong ticks; diff --git a/kaleid/include/kernel/cpu.h b/kaleid/include/kernel/cpu.h index ae2c7b9..73dbb75 100644 --- a/kaleid/include/kernel/cpu.h +++ b/kaleid/include/kernel/cpu.h @@ -29,14 +29,76 @@ #ifndef _KALKERN_CPU_H #define _KALKERN_CPU_H -//------------------------------------------// +// -------------------------------------------------------------------------- // #define KeCPUID(in, a, b, c, d) asm("cpuid" \ : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \ : "a" (in) \ ); -//------------------------------------------// +// -------------------------------------------------------------------------- // +// CPU features masks +enum { + FEAT_ECX_SSE3 = 1 << 0, + FEAT_ECX_PCLMUL = 1 << 1, + FEAT_ECX_DTES64 = 1 << 2, + FEAT_ECX_MONITOR = 1 << 3, + FEAT_ECX_DS_CPL = 1 << 4, + FEAT_ECX_VMX = 1 << 5, + FEAT_ECX_SMX = 1 << 6, + FEAT_ECX_EST = 1 << 7, + FEAT_ECX_TM2 = 1 << 8, + FEAT_ECX_SSSE3 = 1 << 9, + FEAT_ECX_CID = 1 << 10, + FEAT_ECX_FMA = 1 << 12, + FEAT_ECX_CX16 = 1 << 13, + FEAT_ECX_ETPRD = 1 << 14, + FEAT_ECX_PDCM = 1 << 15, + FEAT_ECX_PCIDE = 1 << 17, + FEAT_ECX_DCA = 1 << 18, + FEAT_ECX_SSE4_1 = 1 << 19, + FEAT_ECX_SSE4_2 = 1 << 20, + FEAT_ECX_x2APIC = 1 << 21, + FEAT_ECX_MOVBE = 1 << 22, + FEAT_ECX_POPCNT = 1 << 23, + FEAT_ECX_AES = 1 << 25, + FEAT_ECX_XSAVE = 1 << 26, + FEAT_ECX_OSXSAVE = 1 << 27, + FEAT_ECX_AVX = 1 << 28, + + FEAT_EDX_FPU = 1 << 0, + FEAT_EDX_VME = 1 << 1, + FEAT_EDX_DE = 1 << 2, + FEAT_EDX_PSE = 1 << 3, + FEAT_EDX_TSC = 1 << 4, + FEAT_EDX_MSR = 1 << 5, + FEAT_EDX_PAE = 1 << 6, + FEAT_EDX_MCE = 1 << 7, + FEAT_EDX_CX8 = 1 << 8, + FEAT_EDX_APIC = 1 << 9, + FEAT_EDX_SEP = 1 << 11, + FEAT_EDX_MTRR = 1 << 12, + FEAT_EDX_PGE = 1 << 13, + FEAT_EDX_MCA = 1 << 14, + FEAT_EDX_CMOV = 1 << 15, + FEAT_EDX_PAT = 1 << 16, + FEAT_EDX_PSE36 = 1 << 17, + FEAT_EDX_PSN = 1 << 18, + FEAT_EDX_CLF = 1 << 19, + FEAT_EDX_DTES = 1 << 21, + FEAT_EDX_ACPI = 1 << 22, + FEAT_EDX_MMX = 1 << 23, + FEAT_EDX_FXSR = 1 << 24, + FEAT_EDX_SSE = 1 << 25, + FEAT_EDX_SSE2 = 1 << 26, + FEAT_EDX_SS = 1 << 27, + FEAT_EDX_HTT = 1 << 28, + FEAT_EDX_TM1 = 1 << 29, + FEAT_EDX_IA64 = 1 << 30, + FEAT_EDX_PBE = 1 << 31 +}; + +// -------------------------------------------------------------------------- // #endif diff --git a/kaleid/include/kernel/heap.h b/kaleid/include/kernel/heap.h index d8f4c78..062bf0a 100644 --- a/kaleid/include/kernel/heap.h +++ b/kaleid/include/kernel/heap.h @@ -31,7 +31,8 @@ //------------------------------------------// -#define _HEAP_START (8 * MB) +// Address of the heap +void *_heap_start; void MmInitHeap(void); diff --git a/kaleid/kernel/cpu/cpuid.c b/kaleid/kernel/cpu/cpuid.c index ef8b36a..d1f756b 100644 --- a/kaleid/kernel/cpu/cpuid.c +++ b/kaleid/kernel/cpu/cpuid.c @@ -22,4 +22,12 @@ // along with OS/K. If not, see . // //----------------------------------------------------------------------------// -int stub; + +char *KeGetVendorString(void) { + return "Null"; +} + + + + + diff --git a/kaleid/kernel/cpu/idt.c b/kaleid/kernel/cpu/idt.c new file mode 100644 index 0000000..ae3c860 --- /dev/null +++ b/kaleid/kernel/cpu/idt.c @@ -0,0 +1,37 @@ +//----------------------------------------------------------------------------// +// 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 . // +//----------------------------------------------------------------------------// + + +// +// Registers the new idt in the idtr register. +// +static inline void lidt(void* idtAddr, ushort size) +{ + struct { + ushort length; + void* base; + } __attribute__((packed)) IDTR = { size, idtAddr }; + + asm volatile( "lidt %0" : : "m"(IDTR) ); +} diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c index 7ec185b..4fd22bd 100644 --- a/kaleid/kernel/init/init.c +++ b/kaleid/kernel/init/init.c @@ -37,7 +37,7 @@ void BtInitBootInfo(multiboot_info_t *mbi) { extern ulong MB_header; - extern ulong kernelEnd; + extern ulong newKernelEnd; // We need the multiboot structure KalAlwaysAssert(mbi); @@ -48,7 +48,7 @@ void BtInitBootInfo(multiboot_info_t *mbi) if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_BOOT_LOADER_NAME) { BtGetBootInfo(btldr).grubName = (char*)(ulong)(mbi->boot_loader_name); BtGetBootInfo(btldr).kernelAddr = (void*)&MB_header; - BtGetBootInfo(btldr).kernelEndAddr = (void*)&kernelEnd; + BtGetBootInfo(btldr).kernelEndAddr = (void*)newKernelEnd; BtGetBootInfo(btldr).valid = 1; } if (BtGetBootInfo(btldr).grubFlags & MULTIBOOT_INFO_MODS) { @@ -142,22 +142,12 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, int mbMagic) mapBad ); - KernLog("[Init] TEST First zone from %p : %p\n", (void*)0xB8010, - MmGetFirstAvailZone((void*)0xB8010)); - KernLog("[Init] TEST Size of zone : %u Kio\n\n", - MmGetAvailZoneSize(MmGetFirstAvailZone((void*)0xB8010)) / KB); - MmInitHeap(); PsInitSched(); - ClearTerm(StdOut); - Buffer_t *buf = BOpenLineBuf(NULL, BS_WRONLY, 80, 24, 1, NULL); - //BPrintOnBuf(buf, "xxx\nxxx\ry\tw\n%d %s\n%%%p", 1, "abcd", 0); - //int i; for(i=0;i<100;i++) BPrintOnBuf(buf,"%d\n",i); - - error_t rc = BPrintOnBuf(buf, "%+#05X", 0xcafeb00b); + error_t rc = BPrintOnBuf(buf, "%+#05x", 0xcafeb00b); if(rc)KernLog("error\n"); KernLog((char*)buf->buf); diff --git a/kaleid/kernel/mm/heap.c b/kaleid/kernel/mm/heap.c index 16c8fe9..86c6878 100644 --- a/kaleid/kernel/mm/heap.c +++ b/kaleid/kernel/mm/heap.c @@ -24,6 +24,7 @@ #include #include +#include // Least address out of the heap static void *_heap_end; @@ -40,8 +41,17 @@ static Lock_t _heap_lock = ExINITLOCK(KLOCK_SPINLOCK); void MmInitHeap(void) { assert(_heap_end == NULL); - _heap_end = (void *)_HEAP_START; - _heap_max = lmin(8 * MB, MmGetAvailZoneSize((void *)_HEAP_START)); + + // Get the first available zone address + _heap_start = MmGetFirstAvailZone((void*)0); + // Align it + while ((size_t)_heap_start % alignof(QWORD)) { + _heap_start++; + } + // Initialize the heap + _heap_end = _heap_start; + _heap_max = lmin(8 * MB, MmGetAvailZoneSize(_heap_end)); + KernLog("[InitHeap] Start address : %p, Max length : %u Mio\n\n", _heap_start, _heap_max / MB); } // @@ -65,7 +75,7 @@ void MmUnlockHeap(void) // size_t MmGetHeapSize(void) { - return (size_t)_heap_end - _HEAP_START; + return (size_t)_heap_end - (size_t)_heap_start; } // @@ -81,11 +91,11 @@ size_t MmGetMaxHeapSize(void) // error_t MmSetMaxHeapSize(size_t new) { - if (new > MmGetAvailZoneSize((void *)_HEAP_START)) { + if (new > MmGetAvailZoneSize((void *)_heap_start)) { return ENOMEM; } - if (new < (size_t)_heap_end - _HEAP_START) { + if (new < (size_t)_heap_end - (size_t)_heap_start) { return EADDRINUSE; } @@ -101,7 +111,7 @@ error_t MmGrowHeap(size_t req) { assert(req % alignof(QWORD) == 0); - if ((size_t)_heap_end + req > _HEAP_START + _heap_max) { + if ((size_t)_heap_end + req > (size_t)_heap_start + _heap_max) { return ENOMEM; } @@ -117,7 +127,7 @@ error_t MmShrinkHeap(size_t req) { assert(req % alignof(QWORD) == 0); - if (req > (size_t)_heap_end - _HEAP_START) { + if (req > (size_t)_heap_end - (size_t)_heap_start) { return EADDRINUSE; } diff --git a/kaleid/kernel/mm/malloc.c b/kaleid/kernel/mm/malloc.c index 6d7262a..a510204 100644 --- a/kaleid/kernel/mm/malloc.c +++ b/kaleid/kernel/mm/malloc.c @@ -29,6 +29,7 @@ error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align) { error_t rc; size_t brk; + extern void *_heap_start; if (align == 0) align = M_DEFAULT_ALIGNMENT; @@ -38,7 +39,7 @@ error_t KalAllocMemory(void **ptr, size_t req, int flags, size_t align) MmLockHeap(); - brk = _HEAP_START + MmGetHeapSize(); + brk = (size_t)_heap_start + MmGetHeapSize(); req = _ALIGN_UP(req + brk, align) - brk; rc = MmGrowHeap(req); diff --git a/kaleid/kernel/mm/stack.c b/kaleid/kernel/mm/stack.c new file mode 100644 index 0000000..2bb1aaf --- /dev/null +++ b/kaleid/kernel/mm/stack.c @@ -0,0 +1,23 @@ +//----------------------------------------------------------------------------// +// GNU GPL OS/K // +// // +// Desc: Mapping and checking memory 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 . // +//----------------------------------------------------------------------------//