diff --git a/Makefile b/Makefile
index 05c091e..bb5f2a7 100644
--- a/Makefile
+++ b/Makefile
@@ -46,7 +46,7 @@ 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
CFLAGS= $(CFLAGS1) $(CFLAGS2)
-CFLAGS_MATHS= $(CFLAGS1) -c -mno-red-zone -mno-mmx -mno-sse2
+CFLAGS_MATHS= $(CFLAGS1) -c -mno-red-zone -mno-mmx
ifeq ($(mode), release)
CFLAGS += -D_NO_DEBUG
@@ -115,7 +115,7 @@ KernSources = kernel/ke/cpuid.c kernel/mm/paging.c \
kernel/sh/shell.c kernel/sh/shcmds.c \
kernel/sh/musage.c kernel/io/ata.c \
kernel/sh/argv.c kernel/ke/pit.c \
- kernel/sh/testcmds.c
+ kernel/sh/testcmds.c kernel/mm/palloc.c
KernObj=$(patsubst %.c,$(KOBJDIR)/%.o,$(KernSources))
KernDep=$(patsubst %.c,$(KOBJDIR)/%.d,$(KernSources))
diff --git a/ProjectTree b/ProjectTree
index 1c063cc..a5adff2 100644
--- a/ProjectTree
+++ b/ProjectTree
@@ -74,7 +74,8 @@
│ │ ├── heap.h
│ │ ├── malloc.h
│ │ ├── map.h
-│ │ └── paging.h
+│ │ ├── paging.h
+│ │ └── palloc.h
│ ├── po
│ │ └── shtdwn.h
│ ├── sh
@@ -116,7 +117,8 @@
│ │ │ ├── malloc.c
│ │ │ ├── map.c
│ │ │ ├── paging.asm
-│ │ │ └── paging.c
+│ │ │ ├── paging.c
+│ │ │ └── palloc.c
│ │ ├── po
│ │ │ └── shtdwn.c
│ │ ├── ps
@@ -157,4 +159,4 @@
├── ProjectTree
└── README.md
-28 directories, 104 files
+28 directories, 106 files
diff --git a/boot/loader/mem/management.inc b/boot/loader/mem/management.inc
index dc67950..961478f 100644
--- a/boot/loader/mem/management.inc
+++ b/boot/loader/mem/management.inc
@@ -23,43 +23,36 @@
; along with OS/K. If not, see . ;
;=----------------------------------------------------------------------------=;
-%define MAX_MEMORY 1 ; GiB
-
[BITS 32]
[section .text]
; ---------------------------------------------------------------------------- ;
; Constructor for the page tables in protected mode ;
; ---------------------------------------------------------------------------- ;
Setup_paging:
- ;; Map the first PML4 entry to PDP table
+ ;; Map first PML4 entry to PDP table
mov eax, PDP_table
- or eax, 1 << 1 | 1 << 0 ; present + writable
+ or eax, 0b11 ; Present + writable
mov [PML4_table], eax
- ;; Map the PDP entries to PD tables
- mov ebx, PD_table ; start address
- mov ecx, 0x0 ; counter variable
-.map_pdp_table:
- mov eax, ebx
- or eax, 1 << 1 | 1 << 0 ; present + writable
- mov [PDP_table + 8 * ecx], eax
- inc ecx
- add ebx, 4096
- cmp ecx, MAX_MEMORY ; PDP table is mapped if MAX_MEMORY
- jne .map_pdp_table ; else map the next entry
+ ;; Map first PDP entry to PD table
+ mov eax, PD_table
+ or eax, 0b11 ; Present + writable
+ mov [PDP_table], eax
- ;; Map each PD entry to a 'huge' 4MiB page
+ ;; Map each PD entry to a huge 2MiB page
+ mov ecx, 0 ; counter variable
- mov ecx, 0x0 ; counter variable
.map_pd_table:
- ;; map ecx-th PD entry to a huge page that starts at address 4MiB*ecx
- mov eax, 0x200000
+ ;; Map ecx-th PD entry to a huge page that starts at address 2MiB*ecx
+ mov eax, 0x200000 ; 2MiB
mul ecx ; start address of ecx-th page
- or eax, 1 << 7 | 1 << 1 | 1 << 0 ; present + writable + huge
- mov [PD_table + ecx * 8], eax
- inc ecx
- cmp ecx, 512 * MAX_MEMORY ; PD table is mapped if 512
+ or eax, 0b10000011 ; present + writable + huge
+ mov [PD_table + ecx * 8], eax ; map ecx-th entry
+
+ inc ecx ; increase counter
+ cmp ecx, 512 ; if counter == 512, the whole P2 table is mapped
jne .map_pd_table ; else map the next entry
+
ret
; ---------------------------------------------------------------------------- ;
diff --git a/boot/loader/mem/structures.inc b/boot/loader/mem/structures.inc
index 590f651..e52bba6 100644
--- a/boot/loader/mem/structures.inc
+++ b/boot/loader/mem/structures.inc
@@ -31,7 +31,7 @@ global newStackEnd
global GDT64
[section .text]
-KERNEL_STACK equ 16 * 1024 ; 16KB of stack
+KERNEL_STACK equ 16 * 1024 * 1024 ; 16MB of stack
newKernelEnd dq 0x0
newStackEnd dq 0x0
@@ -63,4 +63,4 @@ PML4_table:
PDP_table:
resb 4096
PD_table:
- times MAX_MEMORY resb 4096
+ resb 4096
diff --git a/include/ke/time.h b/include/ke/time.h
index b205289..8407312 100644
--- a/include/ke/time.h
+++ b/include/ke/time.h
@@ -64,7 +64,7 @@ void KeEnablePIT(void);
void KeSleep(uint);
Timer_t *KeSetTimer(uint delay);
int KeGetTimer(Timer_t*);
-
+ulong KeGetTicks(void);
//----------------------------------------------------------------------------//
diff --git a/include/libc.h b/include/libc.h
index bf96d63..21a52e2 100644
--- a/include/libc.h
+++ b/include/libc.h
@@ -168,6 +168,7 @@ unsigned long strtoul(const char *restrict, char **restrict, int);
//----------------------------------------------------------------------------//
void *calloc(size_t, size_t) __attribute__((__malloc__));
+void *memalign(size_t n, size_t align) __attribute__((__malloc__));
void *malloc(size_t) __attribute__((__malloc__));
void free(void *);
diff --git a/include/mm/paging.h b/include/mm/paging.h
index d76f0ec..c4f2845 100644
--- a/include/mm/paging.h
+++ b/include/mm/paging.h
@@ -33,7 +33,7 @@
#define KPAGESIZE (4 * KB)
#define UPAGESIZE (4 * KB)
-#define USERSPACE 0x80000000
+#define USERSPACE 0x200000000
//----------------------------------------------------------------------------//
@@ -49,6 +49,19 @@ typedef pde_t* pdpe_t;
// Page directory L4 pointer offset
typedef pdpe_t* pml4_t;
+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
+};
+
//----------------------------------------------------------------------------//
//
diff --git a/include/mm/palloc.h b/include/mm/palloc.h
index bada93f..98dc5b2 100644
--- a/include/mm/palloc.h
+++ b/include/mm/palloc.h
@@ -31,7 +31,22 @@
//----------------------------------------------------------------------------//
+typedef struct AllocatedPage_t{
+ void *phyAddress;
+ ulong id;
+ struct AllocatedPage_t *next;
+} AllocatedPage_t;
+#define CONTIGUOUS true
+#define NORMAL false
+
+//----------------------------------------------------------------------------//
+
+ulong MmAllocPageFrameEx(void ***frameListPtr, size_t *pageNumber, size_t size, bool contiguous);
+ulong MmAllocPageFrame(size_t size, bool contiguous);
+void MmFreePageFrame(ulong id);
+
+error_t MmTestBusyPage(void);
//----------------------------------------------------------------------------//
diff --git a/kaleid/kernel/init/init.c b/kaleid/kernel/init/init.c
index 3a3144c..a739f7a 100644
--- a/kaleid/kernel/init/init.c
+++ b/kaleid/kernel/init/init.c
@@ -84,6 +84,8 @@ noreturn void BtStartKern(multiboot_info_t *mbInfo, uint mbMagic, void *codeSeg)
// Command line (kernel mode)
ShStartShell();
+ //KeCrashSystem();
// Exit !
PoShutdown();
+
}
diff --git a/kaleid/kernel/init/ssp.c b/kaleid/kernel/init/ssp.c
index 958f1b2..bf2d70d 100644
--- a/kaleid/kernel/init/ssp.c
+++ b/kaleid/kernel/init/ssp.c
@@ -24,7 +24,7 @@
#include
-ulong __stack_chk_guard = 0x447c0ffe4dbf9e55;
+ulong __stack_chk_guard = 0xec0ffec0ffec0ffe;
noreturn void __stack_chk_fail(void)
{
diff --git a/kaleid/kernel/ke/pit.c b/kaleid/kernel/ke/pit.c
index a9d961c..4a0ee7b 100644
--- a/kaleid/kernel/ke/pit.c
+++ b/kaleid/kernel/ke/pit.c
@@ -219,3 +219,8 @@ ulong KeGetTimeStamp(void)
+ (time->year + time->century * 100)
* dpy * 24 * 60 * 60;
}
+
+ulong KeGetTicks(void)
+{
+ return Ticks;
+}
diff --git a/kaleid/kernel/mm/gdt.c b/kaleid/kernel/mm/gdt.c
index 6a5c188..372bebe 100644
--- a/kaleid/kernel/mm/gdt.c
+++ b/kaleid/kernel/mm/gdt.c
@@ -58,9 +58,9 @@ void MmInitGdt(void)
tssDesc.veryHighBase = ((ulong)&tss >> 32) & 0xFFFFFFFF;
tssDesc.lowLimit = sizeof(tss);
- 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.ist1 = (ulong)0x00007BFF; // ISR RESCUE STACK, GARANTIED FREE FOR USE BY OSDEV.ORG
+ tss.ist2 = (ulong)0x00043F00; // ISR STACK, GARANTIED FREE FOR USE BY OSDEV.ORG
+ tss.ist3 = (ulong)0x0007FFFF; // 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/malloc.c b/kaleid/kernel/mm/malloc.c
index cfd25e2..f513660 100644
--- a/kaleid/kernel/mm/malloc.c
+++ b/kaleid/kernel/mm/malloc.c
@@ -59,7 +59,7 @@ error_t KalAllocMemoryEx(void **ptr, size_t req, int flags, size_t align)
KeStartPanic("KalAllocMemory: Out of memory");
}
- *ptr = (void *)brk;
+ *ptr = (void *)_ALIGN_UP(brk, align);
if (flags & M_ZEROED) {
memzero(*ptr, req);
diff --git a/kaleid/kernel/mm/map.c b/kaleid/kernel/mm/map.c
index 64156fe..08868de 100644
--- a/kaleid/kernel/mm/map.c
+++ b/kaleid/kernel/mm/map.c
@@ -102,14 +102,11 @@ static error_t InitMemoryMap(void)
KernLog("\tAvailable RAM size : %u MB\n",
memoryMap.freeRamSize / MB);
- // Magic value in memory to prevent smashing
- ulong * heapStart = BtLoaderInfo.stackEndAddr + 8;
- *heapStart = 0xbad00badbad00bad;
-
return EOK;
}
-size_t MmGetAvailZoneSize(void *start) {
+size_t MmGetAvailZoneSize(void *start)
+{
uint i;
// Because the kernel is the kernel
@@ -133,7 +130,33 @@ size_t MmGetAvailZoneSize(void *start) {
return 0;
}
-void *MmGetFirstAvailZone(void *start) {
+bool MmIsFailingZoneSize(void *start)
+{
+ uint i;
+
+ // Because the kernel is the kernel
+ if (start < BtLoaderInfo.stackEndAddr + 16)
+ return 0;
+
+ // Search the zone where the start address is
+ for (i = 0; i < memoryMap.length; i++) {
+ // if the address is in a failing zone, we can return 1
+ if (
+ (memoryMap.entry[i].type == BADRAM_ZONE) &&
+ (ulong)start >= (ulong)memoryMap.entry[i].addr &&
+ (ulong)start < ((ulong)memoryMap.entry[i].addr +
+ (ulong)memoryMap.entry[i].length)
+ ) {
+ return 1;
+ }
+ }
+
+ // If there is no zone, we return a 0 size
+ return 0;
+}
+
+void *MmGetFirstAvailZone(void *start)
+{
uint i;
void *current = 0;
@@ -174,7 +197,8 @@ void *MmGetFirstAvailZone(void *start) {
return current;
}
-void MmPrintMemoryMap(void) {
+void MmPrintMemoryMap(void)
+{
char avStr[15];
extern int shcol;
diff --git a/kaleid/kernel/mm/paging.c b/kaleid/kernel/mm/paging.c
index 6c3487f..ad253d6 100644
--- a/kaleid/kernel/mm/paging.c
+++ b/kaleid/kernel/mm/paging.c
@@ -31,11 +31,12 @@
#include
#include
#include
+#include
//-----------
-pml4_t MmPageMapLevel4[512] __attribute__((__aligned__(KPAGESIZE)));
-ulong *MmPhysicalPageTable;
+static pml4_t MmPageMapLevel4[512] __attribute__((__aligned__(KPAGESIZE)));
+static ulong *MmPhysicalPageTable __attribute__((__aligned__(KPAGESIZE)));
extern ulong _text;
extern ulong _text_end;
@@ -46,23 +47,10 @@ extern ulong _data_end;
extern MemoryMap_t memoryMap;
-ulong MmStackGuards[2] = { 0 };
+static ulong MmStackGuards[2] = { 0 };
ulong MmVirtLastAddress = 0;
ulong MmPhysLastKernAddress = 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
-};
-
//-----------
//
@@ -74,84 +62,106 @@ void MmInitPaging(void)
pde_t *MmPD = NULL;
pte_t *MmPT = NULL;
ulong index, xedni;
+ ulong curAddrPML4;
+ ulong curAddrPDP;
+ ulong curAddrPD;
+ ulong curAddrPT;
+
ulong firstDirectoryAddr = 0;
ulong lastDirectoryAddr = 0;
ulong phDirSize = 0;
+ KernLog("\tActivating paging...\n");
+
// Maximum PHYSICAL address in memory
ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
// Difference between the end of kernel and the begin of userspace
MmPhysLastKernAddress = (ulong)(_heap_start + _heap_max);
- ulong diffKernUsr = (ulong)USERSPACE - MmPhysLastKernAddress - KPAGESIZE;
+
+ // Size of physical table
+ phDirSize = (((phRamSize + KPAGESIZE) / KPAGESIZE)*sizeof(ulong));
// Maximum VIRTUAL address in memory
- MmVirtLastAddress = phRamSize + diffKernUsr;
+ MmVirtLastAddress = phRamSize;
- //DebugLog("\tPaging gap : %u MB (%p)\n\tLast virtual address %p\n", diffKernUsr / MB, diffKernUsr, MmVirtLastAddress);
+ // Alloc structures
+ memzero((void *)&MmPageMapLevel4[0], 512*sizeof(ulong));
+ MmPhysicalPageTable = memalign(phDirSize, KPAGESIZE);
- memzero((void *)&MmPageMapLevel4[0], sizeof(MmPageMapLevel4));
- phDirSize = ((phRamSize / KPAGESIZE)*sizeof(ulong) + KPAGESIZE) & ( ~(KPAGESIZE - 1));
+ //DebugLog("\t\t\t\tPhysical map addr : %p\n", MmPhysicalPageTable);
- 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;
+ for (curAddrPML4 = 0;
+ curAddrPML4 < 512 * KPAGESIZE * 0x8000000;
curAddrPML4 += ((ulong)KPAGESIZE * 0x8000000)) {
// Create an entry in PML4 each 512GB
// 0x8000000 = 512 ^ 3
- MmPDP = (pdpe_t *)malloc(512*sizeof(pde_t));
+ index = (curAddrPML4 / ((ulong)KPAGESIZE * 0x8000000)) % 512;
+
+ if (curAddrPML4 > MmPhysLastKernAddress) {
+ MmPageMapLevel4[index] = (pdpe_t *)0;
+ ////DebugLog("PML4 %d\n", index);
+ continue;
+ }
+
+ MmPDP = memalign(512*sizeof(pde_t), KPAGESIZE);
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;
+ for (curAddrPDP = curAddrPML4;
+ curAddrPDP < (curAddrPML4 + ((ulong)KPAGESIZE * 0x8000000));
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;
+
+ if (curAddrPDP > MmPhysLastKernAddress) {
+ MmPDP[index] = (pde_t *)0;
+ //DebugLog("PDP %d\n", index);
+ continue;
+ }
+
+ MmPD = memalign(512*sizeof(pde_t), KPAGESIZE);
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;
+ for (curAddrPD = curAddrPDP;
+ curAddrPD < (curAddrPDP + ((ulong)KPAGESIZE * 0x40000));
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;
+ if (curAddrPD > MmPhysLastKernAddress) {
+ MmPD[index] = (pte_t *)0;
+ //DebugLog("PD %d\n", index);
+ continue;
+ }
+
+ MmPT = memalign(512*sizeof(pte_t), KPAGESIZE);
+
//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;
+ for (curAddrPT = curAddrPD;
+ curAddrPT < (curAddrPD + ((ulong)KPAGESIZE * 0x200));
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;
@@ -179,7 +189,7 @@ void MmInitPaging(void)
}
// SECTION .RODATA PROTECTION
else if ((ulong)curAddrPT >= (ulong)&_rodata && (ulong)curAddrPT <= (ulong)&_rodata_end) {
- MmPT[index] = (ulong)curAddrPT | PRESENT | WRITETHR | NX;
+ MmPT[index] = (ulong)curAddrPT | PRESENT | NX;
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
//DebugLog("\tSection .rodata at %p\n", curAddrPT);
}
@@ -187,26 +197,11 @@ void MmInitPaging(void)
else if ((ulong)curAddrPT <= MmPhysLastKernAddress) {
MmPT[index] = (ulong)curAddrPT | PRESENT | READWRITE;
MmPhysicalPageTable[xedni] = (ulong)curAddrPT;
-
- if ((ulong)curAddrPT == MmPhysLastKernAddress) {
- //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;
+ MmPT[index] = (ulong)0;
+ MmPhysicalPageTable[xedni] = (ulong)0;
}
-
- KeFlushTlbSingle(curAddrPT);
}
}
}
@@ -214,7 +209,7 @@ void MmInitPaging(void)
lastDirectoryAddr = (ulong)MmPT;
MmLoadPML4((void *)MmPageMapLevel4);
- //MmEnableWriteProtect();
+ MmEnableWriteProtect();
DebugLog("\tPage table size : %u MB\n", (lastDirectoryAddr - firstDirectoryAddr + phDirSize)/MB);
}
@@ -222,46 +217,88 @@ void MmInitPaging(void)
//
// Get a page from an address
//
-static pte_t *MmGetPageDescriptorFromVirtual(void *virtualAddr)
+ulong *MmGetPageDescriptorFromVirtual(void *virtualAddr)
{
- ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1));
+ register ulong pml4Index = ((ulong)virtualAddr & 0xFF8000000000) >> 39; // Select bit from 39 to 48
+ register ulong pdpIndex = ((ulong)virtualAddr & 0x7FC0000000) >> 30; // Select bit from 39 to 48
+ register ulong pdIndex = ((ulong)virtualAddr & 0x3FE00000) >> 21; // Select bit from 39 to 48
+ register ulong ptIndex = ((ulong)virtualAddr & 0x1FF000) >> 12; // Select bit from 39 to 48
+ pdpe_t *pdp = NULL;
+ pde_t *pd = NULL;
+ pte_t *pt = NULL;
- if (virtAddrPage > MmVirtLastAddress) {
- KeStartPanic("MmSetPage() Out of bound of the address space !");
+ DebugLog("PML4[%d], PDP[%d], PD[%d], PT[%d]\n", pml4Index, pdpIndex, pdIndex, ptIndex);
+
+ if (!((ulong)MmPageMapLevel4[pml4Index] & 0xFFFFFFFFFF000)) { // Select bit from 12 to 51
+
+ // Alloc space
+ MmPageMapLevel4[pml4Index] = memalign(512*sizeof(pdpe_t), KPAGESIZE);
+
+ // Set present
+ MmPageMapLevel4[pml4Index] = (pml4_t)((ulong)MmPageMapLevel4[pml4Index] | PRESENT | READWRITE);
+
+ pdp = (pdpe_t *)((ulong)MmPageMapLevel4[pml4Index] & 0xFFFFFFFFFF000);
+ DebugLog("\tCreate PDP at %p\n", MmPageMapLevel4[pml4Index]);
+
+ } else {
+ pdp = (pdpe_t *)((ulong)MmPageMapLevel4[pml4Index] & 0xFFFFFFFFFF000);
}
- 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);
+ DebugLog("\tPDP[%d] = %p\n", pdpIndex, pdp[pdpIndex]);
- pte_t *page = &pt[(virtAddrPage / ((ulong)KPAGESIZE)) % 512];
- //DebugLog("page (with flags): %p\n", page);
+ if (!((ulong)pdp[pdpIndex] & 0xFFFFFFFFFF000)) { // Select bit from 12 to 51
- return page;
+ pdp[pdpIndex] = memalign(512*sizeof(pde_t), KPAGESIZE);
+
+ pdp[pdpIndex] = (pdpe_t)((ulong)pdp[pdpIndex] | PRESENT | READWRITE);
+
+ pd = (pde_t *)((ulong)pdp[pdpIndex] & 0xFFFFFFFFFF000);
+ DebugLog("\tCreate PD at %p\n", (ulong)pdp[pdpIndex]);
+
+ } else {
+ pd = (pde_t *)((ulong)pdp[pdpIndex] & 0xFFFFFFFFFF000);
+ }
+
+ DebugLog("\tPD[%d] = %p\n", pdIndex, pd[pdIndex]);
+
+ if (!((ulong)pd[pdIndex] & 0xFFFFFFFFFF000)) { // Select bit from 12 to 51
+
+ pd[pdIndex] = memalign(512*sizeof(pte_t), KPAGESIZE);
+
+ pd[pdIndex] = (pde_t)((ulong)pd[pdIndex] | PRESENT | READWRITE);
+
+ pt = (pte_t *)((ulong)pd[pdIndex] & 0xFFFFFFFFFF000);
+ DebugLog("\tCreate PT at %p\n", (ulong)pd[pdIndex]);
+
+ } else {
+ pt = (pte_t *)((ulong)pd[pdIndex] & 0xFFFFFFFFFF000);
+ }
+
+ DebugLog("\tPT[%d] = %p\n", ptIndex, pt[ptIndex]);
+
+ MmLoadPML4((void *)MmPageMapLevel4);
+
+ return &pt[ptIndex];
}
-
//
// Translates a virtual address to its physical equivalent
//
void *MmTransVirtToPhyAddr(void* virtualAddr)
{
ulong virtAddrPage = (ulong)virtualAddr & ( ~(KPAGESIZE - 1));
- pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
+ ulong *page = MmGetPageDescriptorFromVirtual(virtualAddr);
- if (*page == (*page & ~(KPAGESIZE - 1))) {
+ if (!(page)) {
return NULL;
}
- return (void*)((*page & ~(KPAGESIZE - 1))+ ((ulong)virtualAddr - (ulong)virtAddrPage));
+ return (void*)(((ulong)*page & 0xFFFFFFFFFF000)+ ((ulong)virtualAddr - (ulong)virtAddrPage));
}
void *MmTransPhyToVirtAddr(void* physicalAddr)
{
- ulong phyAddrPage = (ulong)physicalAddr & ( ~(KPAGESIZE - 1));
+ ulong phyAddrPage = (ulong)physicalAddr & ( ~((KPAGESIZE - 1) | NX));
return (void*)( MmPhysicalPageTable[(ulong)physicalAddr
/ ((ulong)KPAGESIZE)
] + ((ulong)physicalAddr - phyAddrPage));
@@ -272,9 +309,7 @@ void *MmTransPhyToVirtAddr(void* physicalAddr)
//
void MmSetPage(void* virtualAddr, ulong flags)
{
- pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
-
- *page |= flags;
+ ulong *page = MmGetPageDescriptorFromVirtual(virtualAddr);
KeFlushTlbSingle(*page);
}
@@ -284,9 +319,7 @@ void MmSetPage(void* virtualAddr, ulong flags)
//
void MmUnsetPage(void* virtualAddr, ulong flags)
{
- pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
-
- *page &= (~flags);
+ ulong *page = MmGetPageDescriptorFromVirtual(virtualAddr);
KeFlushTlbSingle(*page);
}
@@ -296,11 +329,22 @@ void MmUnsetPage(void* virtualAddr, ulong flags)
//
void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags)
{
- pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
+ //DebugLog("Request %p:%p with %lu\n", virtualAddr, physicalAddr, flags);
- *page = ((ulong)physicalAddr & ~(KPAGESIZE - 1)) | flags;
+ ulong *page = MmGetPageDescriptorFromVirtual(virtualAddr);
- KeFlushTlbSingle(*page);
+ *page = (ulong)physicalAddr | flags;
+
+ MmPhysicalPageTable[(ulong)physicalAddr
+ / ((ulong)KPAGESIZE)
+ ] = (ulong)virtualAddr;
+
+ KeFlushTlbSingle(virtualAddr);
+
+ //DebugLog("Done %p at page %p\n", *page, page);
+
+ if ((ulong)virtualAddr > MmVirtLastAddress)
+ MmVirtLastAddress = (ulong)virtualAddr + KPAGESIZE;
}
//
@@ -308,11 +352,17 @@ void MmMapPage(void* virtualAddr, void* physicalAddr, ulong flags)
//
void MmUnmapPage(void* virtualAddr)
{
- pte_t *page = MmGetPageDescriptorFromVirtual(virtualAddr);
+ ulong *page = MmGetPageDescriptorFromVirtual(virtualAddr);
- *page = 0;
+ /* MmPhysicalPageTable[(ulong)(MmTransVirtToPhyAddr(virtualAddr)) */
+ /* / ((ulong)KPAGESIZE) */
+ /* ] = 0; */
- KeFlushTlbSingle(*page);
+ /* pt[ */
+ /* (virtualAddr / (ulong)KPAGESIZE) % 512 */
+ /* ] = 0; */
+
+ KeFlushTlbSingle(virtualAddr);
}
//-----------
@@ -415,5 +465,5 @@ static void PagingHandler(ISRFrame_t *regs)
void MmActivatePageHandler(void)
{
KeRegisterISR(PagingHandler, 0xe);
- DebugLog("\tPaging activated\n");
+ //DebugLog("\tPage handler activated\n");
}
diff --git a/kaleid/kernel/mm/palloc.c b/kaleid/kernel/mm/palloc.c
index 22a0fdf..31fb17a 100644
--- a/kaleid/kernel/mm/palloc.c
+++ b/kaleid/kernel/mm/palloc.c
@@ -27,12 +27,310 @@
#include
#include
#include
+#include
#include
+#include
+#include
//---------
+enum
+{
+ Whatever = 1UL << 52,
+ Whatever2 = 1UL << 62
+};
+static AllocatedPage_t busyPagesList = { (void*)0, 0, (AllocatedPage_t*)0 };
+extern MemoryMap_t memoryMap;
+extern ulong MmPhysLastKernAddress;
+static ulong NSuccessfulAlloc = 0;
+static ulong NSuccessfulFree = 0;
//---------
-
+
+static bool isPageBusy(void *phyPageAddr)
+{
+ AllocatedPage_t *busyPage = &busyPagesList;
+ bool isBusy = false;
+
+ // In case of NVS, ACPI or BADRAM zone, considered busy
+ if (!MmGetAvailZoneSize(phyPageAddr))
+ return true;
+
+ // Search in the busylist if the phy addr is here
+ while(busyPage->next) {
+ busyPage = busyPage->next;
+ if (phyPageAddr == busyPage->phyAddress) {
+ isBusy = true;
+ break;
+ }
+ }
+ return isBusy;
+}
+
+static void printBusyPages(void)
+{
+ AllocatedPage_t *busyPage = &busyPagesList;
+
+ if (!busyPage->next) {
+ KernLog("No busy page\n");
+ } else {
+ while(busyPage->next) {
+ busyPage = busyPage->next;
+ KernLog("Busy page at %p\n", busyPage->phyAddress);
+ }
+ }
+}
+
+static ulong MmBusyPagesSpace(void)
+{
+ ulong c = 0;
+ AllocatedPage_t *busyPage = &busyPagesList;
+
+ if (!busyPage->next) {
+ return 0;
+ } else {
+ while(busyPage->next) {
+ busyPage = busyPage->next;
+ c += 4096;
+ }
+ }
+ return c;
+}
+
+
+static void addPageToBusyList(void *phyPageAddr, ulong id)
+{
+ AllocatedPage_t *busyPage = &busyPagesList;
+ AllocatedPage_t *prevBusyPage = NULL;
+
+ while(busyPage->next) {
+ prevBusyPage = busyPage;
+ busyPage = busyPage->next;
+
+ if (busyPage->phyAddress > phyPageAddr) {
+ busyPage = prevBusyPage;
+ break;
+ }
+ }
+
+ AllocatedPage_t *newBusyPage = (AllocatedPage_t*)malloc(sizeof(AllocatedPage_t));
+ newBusyPage->phyAddress = phyPageAddr;
+ newBusyPage->id = id;
+ newBusyPage->next = busyPage->next;
+ busyPage->next = newBusyPage;
+}
+
+static void removePageFromBusyList(void *phyPageAddr)
+{
+ AllocatedPage_t *busyPage = &busyPagesList;
+ AllocatedPage_t *prevBusyPage = NULL;
+
+ while(busyPage->next) {
+ prevBusyPage = busyPage;
+ busyPage = busyPage->next;
+
+ if (phyPageAddr == busyPage->phyAddress) {
+ prevBusyPage->next = busyPage->next;
+ free(busyPage);
+ break;
+ }
+ }
+}
+
+//
+// Returns an id to identify a page frame allocated (kernel)
+//
+ulong MmAllocPageFrameEx(void ***frameListPtr, size_t *pageNumber, size_t size, bool contiguous)
+{
+ static ulong id = 0;
+ *pageNumber = (((ulong)size - 1) / KPAGESIZE) + 1;
+
+ *frameListPtr = (void**)malloc(sizeof(void*)*(*pageNumber));
+ size_t curNumber = 0;
+ bool inBlock = false;
+
+ // Incrementing id
+ id++;
+
+ // Maximum PHYSICAL address in memory
+ ulong phRamSize = memoryMap.freeRamSize + memoryMap.nonfreeRamSize;
+
+ ////DebugLog("Allocating %d pages...\n", *pageNumber);
+ if (contiguous) {
+ for (void *curPage = (void*)(MmPhysLastKernAddress + KPAGESIZE); curPage < (void*)phRamSize; curPage += KPAGESIZE) {
+ if (!isPageBusy(curPage)) {
+ (*frameListPtr)[curNumber] = curPage;
+ inBlock = true;
+ ////DebugLog("Select page : %p\n", curPage);
+ if (++curNumber >= *pageNumber) {
+ break;
+ }
+ } else {
+ inBlock = false;
+ }
+ if (contiguous)
+ if (!inBlock)
+ curNumber = 0;
+ }
+ } else {
+ for (void *curPage = (void*)(MmPhysLastKernAddress + KPAGESIZE); curPage < (void*)phRamSize; curPage += KPAGESIZE) {
+ if (!isPageBusy(curPage)) {
+ (*frameListPtr)[curNumber] = curPage;
+ ////DebugLog("Select page : %p\n", curPage);
+ if (++curNumber >= *pageNumber) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (curNumber != *pageNumber) {
+ KeStartPanic("MmAllocPageFrameEx() : No more free pages to allocate");
+ }
+
+ for (size_t i = 0; i < *pageNumber; i++) {
+ addPageToBusyList((*frameListPtr)[i], id);
+ ////DebugLog("Allocating page : %p\n", *frameListPtr[i]);
+ }
+
+ NSuccessfulAlloc++;
+
+ return id;
+}
+
+ulong MmAllocPageFrame(size_t size, bool contiguous)
+{
+ void **ptr = NULL;
+ ulong d = 0;
+ return MmAllocPageFrameEx(&ptr, &d, size, contiguous);
+ (void)ptr;
+ (void)d;
+}
+
+
+//
+// Frees a page frame by its id
+//
+void MmFreePageFrame(ulong id)
+{
+ AllocatedPage_t *busyPage = &busyPagesList;
+ bool success = false;
+
+ while(busyPage->next) {
+ busyPage = busyPage->next;
+
+ if (id == busyPage->id) {
+ removePageFromBusyList(busyPage->phyAddress);
+ success = true;
+ }
+ }
+
+ if (success)
+ NSuccessfulFree++;
+}
+
+//
+// Maps an allocated page frame to the given address
+//
+error_t MmMapPageFrame(ulong id, void *virtAddr, ulong flags)
+{
+ AllocatedPage_t *busyPage = &busyPagesList;
+
+ while(busyPage->next) {
+ busyPage = busyPage->next;
+
+ if (MmTransPhyToVirtAddr(busyPage->phyAddress)) {
+ return EADDRINUSE;
+ }
+
+ if (id == busyPage->id) {
+ DebugLog("Map %p at %p\n", busyPage->phyAddress, virtAddr);
+ MmMapPage((void*)((ulong)virtAddr), busyPage->phyAddress, flags);
+ virtAddr += KPAGESIZE;
+ }
+ }
+
+ return EOK;
+}
+
+error_t MmUnmapPageFrame(ulong id)
+{
+ AllocatedPage_t *busyPage = &busyPagesList;
+ void *actualPhys = 0;
+
+ while(busyPage->next) {
+ busyPage = busyPage->next;
+ actualPhys = MmTransPhyToVirtAddr(busyPage->phyAddress);
+
+ ////DebugLog("Physical : %p is %p\n", busyPage->phyAddress, actualPhys);
+
+ if (actualPhys && id == busyPage->id) {
+ ////DebugLog("Unmap %p from %p\n", busyPage->phyAddress, MmTransPhyToVirtAddr(busyPage->phyAddress));
+ MmUnmapPage(MmTransPhyToVirtAddr(busyPage->phyAddress));
+ }
+ }
+
+ return EOK;
+}
+
+ulong tab[4000] = {0};
+
+error_t MmTestBusyPage(void)
+{
+ int j = 0;
+
+ /* for (int i = 0; i < 2000; i++) { */
+ /* if (rand() %2) { */
+ /* if (rand() %2) { */
+ /* tab[j++] = MmAllocPageFrame(rand()%6553689, NORMAL); */
+ /* } else { */
+ /* tab[j++] = MmAllocPageFrame(rand()%6553689, CONTIGUOUS); */
+ /* } */
+ /* } else { */
+ /* MmFreePageFrame(tab[rand() % (j+1)]); */
+ /* } */
+ /* //DebugLog("Alloc : %d; Free : %d; Count : %lu Mo\n", NSuccessfulAlloc, NSuccessfulFree, MmBusyPagesSpace() / MB); */
+ /* } */
+
+ ulong a = KeGetTicks();
+ DebugLog("Start alloc 30 MB: %lu s\n", a/1000);
+ tab[j++] = MmAllocPageFrame(5*MB, NORMAL);
+ tab[j++] = MmAllocPageFrame(5*MB, NORMAL);
+ ulong b = KeGetTicks();
+ DebugLog("End alloc : %lu s\n", b/1000);
+ DebugLog("Alloc time : %lu s\n", (b-a)/1000);
+ DebugLog("Alloc : %d; Free : %d; Count : %lu Mo\n", NSuccessfulAlloc, NSuccessfulFree, MmBusyPagesSpace() / MB);
+
+ /* a = KeGetTicks(); */
+ /* DebugLog("Start alloc 30MB : %lu s\n", a/1000); */
+ /* tab[j++] = MmAllocPageFrame(5*MB, NORMAL); */
+ /* b = KeGetTicks(); */
+ /* DebugLog("End alloc : %lu s\n", b/1000); */
+ /* DebugLog("Alloc time : %lu s\n", (b-a)/1000); */
+ /* DebugLog("Alloc : %d; Free : %d; Count : %lu Mo\n", NSuccessfulAlloc, NSuccessfulFree, MmBusyPagesSpace() / MB); */
+
+ /* j = 0; */
+
+ /* a = KeGetTicks(); */
+ /* DebugLog("Start free : %lu ms\n", a); */
+ /* MmFreePageFrame(tab[j++]); */
+ /* b = KeGetTicks(); */
+ /* DebugLog("End free : %lu ms\n", b); */
+ /* DebugLog("Free time : %lu ms\n", (b-a)); */
+ /* DebugLog("Alloc : %d; Free : %d; Count : %lu Mo\n", NSuccessfulAlloc, NSuccessfulFree, MmBusyPagesSpace() / MB); */
+
+ a = KeGetTicks();
+ DebugLog("Start map at %p: %lu ms\n", USERSPACE, a);
+ MmMapPageFrame(tab[1], (void*)(USERSPACE), PRESENT | READWRITE);
+ b = KeGetTicks();
+ DebugLog("End map : %lu ms\n", b);
+ DebugLog("Map time : %lu ms\n", (b-a));
+
+ //printBusyPages();
+
+ //DebugLog("Finished !\n");
+
+ return EOK;
+}
diff --git a/kaleid/kernel/sh/testcmds.c b/kaleid/kernel/sh/testcmds.c
index 271de10..9d9895e 100644
--- a/kaleid/kernel/sh/testcmds.c
+++ b/kaleid/kernel/sh/testcmds.c
@@ -24,6 +24,7 @@
#include
#include
+#include
#include
#include
#include
@@ -112,19 +113,19 @@ error_t CmdDumpATASect(int argc, char **argv, char *cmdline)
error_t CmdDumpMem(int argc, char **argv, char *cmdline)
{
- char sector[1024] = {0};
+ char sector[8] = {0};
char *address = (char*)strtoul(argv[1], NULL, 16);
int nb = 1; //atoi(argv[2]);
int x = 0;
- int step = 16;
+ int step = 8;
KernLog("Address begin: %p\n", address);
- for (int i = 0; i < 1024*nb; i++) {
+ for (int i = 0; i < 8*nb; i++) {
sector[i] = *address++;
}
- while(x < 1024*nb) {
+ while(x < 8*nb) {
KernLog("%C", shcol);
for (int i = 0; i < step; i++) {
KernLog("%02x ", (uchar)sector[i+x]);
@@ -219,19 +220,6 @@ error_t CmdPageTranslatePhyToVirt(int argc, char **argv, char *cmdline)
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);
@@ -253,12 +241,8 @@ error_t CmdPageUnmap(int argc, char **argv, char *cmdline)
error_t CmdPageBlock(int argc, char **argv, char *cmdline)
{
- size_t size = (size_t)atoi(argv[1]);
- bool usermode = (bool)atoi(argv[2]);
-
- //MmGetPhyPageBlock(size, usermode);
-
- return EOK;
+ error_t err = MmTestBusyPage();
+ return err;
}
error_t CmdPF(int argc, char **argv, char *cmdline)
diff --git a/kaleid/libc/mem.c b/kaleid/libc/mem.c
index 7107bd0..46772d2 100644
--- a/kaleid/libc/mem.c
+++ b/kaleid/libc/mem.c
@@ -46,6 +46,21 @@ void *malloc(size_t n)
return ptr;
}
+void *memalign(size_t n, size_t align)
+{
+ void *ptr;
+ error_t rc;
+
+#ifndef _KALEID_KERNEL
+ rc = KalAllocMemoryEx(&ptr, n, 0, align);
+#else
+ rc = KalAllocMemoryEx(&ptr, n, M_ZEROED, align);
+#endif
+ if (rc > 0) seterrno(rc);
+
+ return ptr;
+}
+
void *calloc(size_t n, size_t m)
{
void *ptr;