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 . //
+//----------------------------------------------------------------------------//