From 7d7952eb5cab57587c50a9c0d8c1bc45c55c0f2c Mon Sep 17 00:00:00 2001 From: John Hodge Date: Mon, 31 May 2010 23:01:17 +0800 Subject: [PATCH] New kernel stack, fixing pmem alloc bug, updated to maintain free page positions - Misc changes in other places --- Kernel/arch/x86_64/include/proc.h | 3 +++ Kernel/arch/x86_64/main.c | 5 ++++- Kernel/arch/x86_64/mm_phys.c | 19 +++++++++++++------ Kernel/arch/x86_64/mm_virt.c | 25 +++++++++++++++++++++---- 4 files changed, 41 insertions(+), 11 deletions(-) diff --git a/Kernel/arch/x86_64/include/proc.h b/Kernel/arch/x86_64/include/proc.h index 2672ca14..cf9a4461 100644 --- a/Kernel/arch/x86_64/include/proc.h +++ b/Kernel/arch/x86_64/include/proc.h @@ -41,5 +41,8 @@ typedef struct sTaskState Uint RIP, RSP, RBP; } tTaskState; +// === CONSTANTS === +#define KERNEL_STACK_SIZE 0x10000 // 64 KiB + #endif diff --git a/Kernel/arch/x86_64/main.c b/Kernel/arch/x86_64/main.c index 6388d1bf..f2a92298 100644 --- a/Kernel/arch/x86_64/main.c +++ b/Kernel/arch/x86_64/main.c @@ -59,7 +59,10 @@ void kmain(Uint MbMagic, void *MbInfoPtr) // Load Virtual Filesystem VFS_Init(); - *(Uint16*)(0xB8000) = 0x1F00|'G'; + *(Uint16*)(0xB8000) = 0x1F00|'Z'; + *(Uint16*)(0xB8002) = 0x1F00|'Z'; + *(Uint16*)(0xB8004) = 0x1F00|'Z'; + *(Uint16*)(0xB8006) = 0x1F00|'Z'; // Pass on to Independent Loader Log_Log("Arch", "Starting system"); diff --git a/Kernel/arch/x86_64/mm_phys.c b/Kernel/arch/x86_64/mm_phys.c index e8d834d8..68701b28 100644 --- a/Kernel/arch/x86_64/mm_phys.c +++ b/Kernel/arch/x86_64/mm_phys.c @@ -3,7 +3,7 @@ * * Physical Memory Manager */ -#define DEBUG 0 +#define DEBUG 1 #include #include #include @@ -368,7 +368,7 @@ tPAddr MM_AllocPhysRange(int Num, int Bits) LOG("nFree = %i = 0 (super) (0x%x)", nFree, addr); nFree = 0; addr += 1 << (6+6); - addr &= (1 << (6+6)) - 1; + addr &= ~( (1 << (6+6)) - 1 ); continue; } // Check page block (64 pages) @@ -376,7 +376,7 @@ tPAddr MM_AllocPhysRange(int Num, int Bits) LOG("nFree = %i = 0 (main) (0x%x)", nFree, addr); nFree = 0; addr += 1 << (12+6); - addr &= (1 << (12+6)) - 1; + addr &= ~( (1 << (12+6)) - 1 ); continue; } // Check individual page @@ -423,8 +423,10 @@ tPAddr MM_AllocPhysRange(int Num, int Bits) for( i = 0; i < Num; i++, addr++ ) { gaMainBitmap[addr >> 6] |= 1 << (addr & 63); - rangeID = MM_int_GetRangeID(addr); + rangeID = MM_int_GetRangeID(addr << 12); giPhysRangeFree[ rangeID ] --; + if(addr << 12 == giPhysRangeFirst[ rangeID ]) + giPhysRangeFirst[ rangeID ] += 1; } ret = addr; // Save the return address @@ -507,15 +509,20 @@ void MM_DerefPhys(tPAddr PAddr) else gaMainBitmap[ page >> 6 ] &= ~(1 << (page&63)); - // TODO: Update free counts + // Update the free counts if the page was freed if( !(gaMainBitmap[ page >> 6 ] & (1 << (page&63))) ) { int rangeID; rangeID = MM_int_GetRangeID( PAddr ); giPhysRangeFree[ rangeID ] ++; + if( giPhysRangeFirst[rangeID] > page ) + giPhysRangeFirst[rangeID] = page; + if( giPhysRangeLast[rangeID] < page ) + giPhysRangeLast[rangeID] = page; } - if(gaMainBitmap[ page >> 6 ] == 0) { + // If the bitmap entry is not -1, unset the bit in the super bitmap + if(gaMainBitmap[ page >> 6 ] != -1 ) { gaSuperBitmap[page >> 12] &= ~(1 << ((page >> 6) & 63)); } } diff --git a/Kernel/arch/x86_64/mm_virt.c b/Kernel/arch/x86_64/mm_virt.c index 6924b1a8..4ec08471 100644 --- a/Kernel/arch/x86_64/mm_virt.c +++ b/Kernel/arch/x86_64/mm_virt.c @@ -3,6 +3,7 @@ * * Virtual Memory Manager */ +#define DEBUG 0 #include #include #include @@ -213,7 +214,7 @@ int MM_Map(tVAddr VAddr, tPAddr PAddr) { tPAddr tmp; - Log("MM_Map: (VAddr=0x%x, PAddr=0x%x)", VAddr, PAddr); + ENTER("xVAddr xPAddr", VAddr, PAddr); // Check PML4 //Log(" MM_Map: &PAGEMAPLVL4(%x) = %x", VAddr >> 39, &PAGEMAPLVL4(VAddr >> 39)); @@ -257,8 +258,8 @@ int MM_Map(tVAddr VAddr, tPAddr PAddr) PAGETABLE(VAddr >> PTAB_SHIFT) = PAddr | 3; INVLPG( VAddr ); - Log("MM_Map: RETURN 1"); - + + LEAVE('i', 1); return 1; } @@ -559,8 +560,24 @@ tVAddr MM_NewWorkerStack(void) return 0; } +/** + * \brief Allocate a new kernel stack + */ tVAddr MM_NewKStack(void) { - Log_KernelPanic("MM", "TODO: Implement MM_NewKStack"); + tVAddr base = MM_KSTACK_BASE; + Uint i; + for( ; base < MM_KSTACK_TOP; base += KERNEL_STACK_SIZE ) + { + if(MM_GetPhysAddr(base) != 0) + continue; + + Log("MM_NewKStack: Found one at %p", base + KERNEL_STACK_SIZE); + for( i = 0; i < KERNEL_STACK_SIZE; i += 0x1000) + MM_Allocate(base+i); + + return base + KERNEL_STACK_SIZE; + } + Log_Warning("MM", "MM_NewKStack - No address space left\n"); return 0; } -- 2.20.1