From e7d03978fb7c0c6ab1250e56e73afba9ffb89923 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 14 May 2010 07:55:36 +0800 Subject: [PATCH] More memory management functions implemented, other fixes too --- Kernel/arch/x86_64/mm_phys.c | 30 +++++++++++++++++++++++++++--- Kernel/arch/x86_64/proc.c | 8 ++++---- Kernel/arch/x86_64/start32.asm | 8 +++++--- Kernel/arch/x86_64/start64.asm | 6 ++++++ 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/Kernel/arch/x86_64/mm_phys.c b/Kernel/arch/x86_64/mm_phys.c index c64e1e03..3535fbca 100644 --- a/Kernel/arch/x86_64/mm_phys.c +++ b/Kernel/arch/x86_64/mm_phys.c @@ -19,11 +19,13 @@ enum eMMPhys_Ranges // === GLOBALS === tSpinlock glPhysicalPages; Uint64 *gaSuperBitmap; // 1 bit = 64 Pages -Uint64 *gaPrimaryBitmap; // 1 bit = 1 Page +Uint64 *gaPrimaryBitmap; // 1 bit = 64 Pages +Uint32 *gaiPageReferences; // Reference Counts tPAddr giFirstFreePage; // First possibly free page Uint64 giPhysRangeFree[NUM_MM_PHYS_RANGES]; // Number of free pages in each range Uint64 giPhysRangeFirst[NUM_MM_PHYS_RANGES]; // First free page in each range Uint64 giPhysRangeLast[NUM_MM_PHYS_RANGES]; // Last free page in each range +Uint64 giMaxPhysPage = 0; // Maximum Physical page // === CODE === void MM_InitPhys() @@ -92,14 +94,14 @@ tPAddr MM_AllocPhysRange(int Num, int Bits) continue; } // Check page block (64 pages) - if( gaPrimaryBitmap[addr >> 6] == -1) { + if( gaSuperBitmap[addr >> (6+6)] & (1 << (addr>>6)&63)) { nFree = 0; addr += 1 << (12+6); addr &= (1 << (12+6)) - 1; continue; } // Check individual page - if( gaPrimaryBitmap[addr >> 6] & (1 << (addr&63)) ) { + if( gaiPageReferences[addr] ) { nFree = 0; addr ++; continue; @@ -134,6 +136,7 @@ tPAddr MM_AllocPhysRange(int Num, int Bits) addr -= Num; for( i = 0; i < Num; i++ ) { + gaiPageReferences[addr] = 1; gaPrimaryBitmap[addr>>6] |= 1 << (addr & 63); if( gaPrimaryBitmap[addr>>6] == -1 ) gaSuperBitmap[addr>>12] |= 1 << ((addr >> 6) & 64); @@ -158,3 +161,24 @@ tPAddr MM_AllocPhys(void) { return MM_AllocPhysRange(1, -1); } + +void MM_RefPhys(tPAddr PAddr) +{ + if( PAddr > giMaxPhysPage ) return ; + gaiPageReferences[ PAddr >> 12 ] ++; + + gaPrimaryBitmap[PAddr >> 18] |= 1 << ((PAddr>>12) & 63); + if( gaPrimaryBitmap[PAddr >> 18] == -1 ) + gaSuperBitmap[PAddr >> 24] |= 1 << ((PAddr >> 18) & 64); +} + +void MM_DerefPhys(tPAddr PAddr) +{ + if( PAddr > giMaxPhysPage ) return ; + gaiPageReferences[ PAddr >> 12 ] --; + if( gaiPageReferences[ PAddr >> 12 ] ) + { + gaPrimaryBitmap[PAddr >> 18] &= ~(1 << ((PAddr >> 12) & 63)); + gaSuperBitmap[PAddr >> 24] &= ~(1 << ((PAddr >> 18) & 64)); + } +} diff --git a/Kernel/arch/x86_64/proc.c b/Kernel/arch/x86_64/proc.c index 5bb66af9..b30eb224 100644 --- a/Kernel/arch/x86_64/proc.c +++ b/Kernel/arch/x86_64/proc.c @@ -24,8 +24,8 @@ extern tGDT gGDT[]; extern void APStartup(); // 16-bit AP startup code extern Uint GetRIP(); // start.asm -extern Uint64 gaInitPML4[512]; // start.asm -extern void Kernel_Stack_Top; +extern Uint64 gInitialPML4[512]; // start.asm +extern void gInitialKernelStack; extern tSpinlock glThreadListLock; extern int giNumCPUs; extern int giNextTID; @@ -288,7 +288,7 @@ void ArchThreads_Init() gCurrentThread = &gThreadZero; #endif - gThreadZero.MemState.CR3 = (Uint)gaInitPML4 - KERNEL_BASE; + gThreadZero.MemState.CR3 = (Uint)gInitialPML4 - KERNEL_BASE; // Set timer frequency outb(0x43, 0x34); // Set Channel 0, Low/High, Rate Generator @@ -376,7 +376,7 @@ void Proc_ChangeStack() return; } - curBase = (Uint)&Kernel_Stack_Top; + curBase = (Uint)&gInitialKernelStack; LOG("curBase = 0x%x, newBase = 0x%x", curBase, newBase); diff --git a/Kernel/arch/x86_64/start32.asm b/Kernel/arch/x86_64/start32.asm index 248fa8db..1163b31a 100644 --- a/Kernel/arch/x86_64/start32.asm +++ b/Kernel/arch/x86_64/start32.asm @@ -19,7 +19,7 @@ start: mov cr4, eax ; Load PDP4 - mov eax, gInitialPML4 + mov eax, gInitialPML4 - KERNEL_BASE mov cr3, eax ; Enable long/compatability mode @@ -34,7 +34,7 @@ start: mov cr0, eax ; Load GDT - lgdt [gGDTPtr] + lgdt [gGDTPtr - KERNEL_BASE] mov ax, 0x10 mov ss, ax mov ds, ax @@ -45,6 +45,7 @@ start: jmp 0x08:start64 - KERNEL_BASE [section .data] +[global gGDT] gGDT: dd 0,0 dd 0x00000000, 0x00209800 ; 0x08: 64-bit Code @@ -56,10 +57,11 @@ gGDT: times MAX_CPUS dd 0, 0, 0, 0 ; 0x38+16*n: TSS 0 gGDTPtr: dw $-gGDT-1 - dd gGDT + dd gGDT-KERNEL_BASE dd 0 [section .padata] +[global gInitialPML4] gInitialPML4: ; Covers 256 TiB (Full 48-bit Virtual Address Space) dd gInitialPDP - KERNEL_BASE + 3, 0 ; Identity Map Low 4Mb times 256-1 dq 0 diff --git a/Kernel/arch/x86_64/start64.asm b/Kernel/arch/x86_64/start64.asm index bf7293b6..beb22e5a 100644 --- a/Kernel/arch/x86_64/start64.asm +++ b/Kernel/arch/x86_64/start64.asm @@ -3,6 +3,7 @@ ; [bits 64] +[section .text] [global start64] start64: ; Set kernel stack @@ -13,3 +14,8 @@ start64: GetRIP: mov rax, [rsp] ret + +[section .bss] +[global gInitialKernelStack] + resd 1024*1 ; 1 Page +gInitialKernelStack: -- 2.20.1