From e1a5a15ff663d68e107edf0ad0a2bc878c0670d5 Mon Sep 17 00:00:00 2001 From: John Hodge Date: Fri, 10 Aug 2012 00:15:42 +0800 Subject: [PATCH] Kernel/x86_64 - Rework to use pmemmap.h (and share code with x86) - Involved breaking the mboot parsing code out of x86/main.c and into a helper file x86/mboot.c This file is used by x86_64 too. - Added a common boot module format --- KernelLand/Kernel/arch/x86/Makefile | 2 +- KernelLand/Kernel/arch/x86/main.c | 95 +----- KernelLand/Kernel/arch/x86/mboot.c | 109 +++++++ KernelLand/Kernel/arch/x86_64/Makefile | 1 + .../Kernel/arch/x86_64/include/archinit.h | 16 + KernelLand/Kernel/arch/x86_64/main.c | 18 +- KernelLand/Kernel/arch/x86_64/mm_phys.c | 297 +++++++----------- KernelLand/Kernel/include/bootmod.h | 21 ++ KernelLand/Kernel/include/mboot.h | 7 + 9 files changed, 294 insertions(+), 272 deletions(-) create mode 100644 KernelLand/Kernel/arch/x86/mboot.c create mode 100644 KernelLand/Kernel/arch/x86_64/include/archinit.h create mode 100644 KernelLand/Kernel/include/bootmod.h diff --git a/KernelLand/Kernel/arch/x86/Makefile b/KernelLand/Kernel/arch/x86/Makefile index c83a5af2..c3223d01 100644 --- a/KernelLand/Kernel/arch/x86/Makefile +++ b/KernelLand/Kernel/arch/x86/Makefile @@ -20,7 +20,7 @@ endif ASFLAGS += -D USE_MP=$(USE_MP) CPPFLAGS += -DUSE_MP=$(USE_MP) -A_OBJ = start.ao main.o lib.o desctab.ao errors.o irq.o +A_OBJ = start.ao main.o mboot.o lib.o desctab.ao errors.o irq.o A_OBJ += mm_phys.o mm_virt.o A_OBJ += proc.o proc.ao time.o vm8086.o A_OBJ += kpanic.o pci.o diff --git a/KernelLand/Kernel/arch/x86/main.c b/KernelLand/Kernel/arch/x86/main.c index 8fcbaefc..af9007da 100644 --- a/KernelLand/Kernel/arch/x86/main.c +++ b/KernelLand/Kernel/arch/x86/main.c @@ -30,18 +30,12 @@ extern int Time_Setup(void); // === GLOBALS === char *gsBootCmdLine = NULL; -struct { - Uint32 PBase; - void *Base; - Uint Size; - char *ArgString; -} *gaArch_BootModules; +tBootModule *gaArch_BootModules; int giArch_NumBootModules = 0; // === CODE === int kmain(Uint MbMagic, void *MbInfoPtr) { - tMBoot_Module *mods; tMBoot_Info *mbInfo; tPMemMapEnt pmemmap[MAX_PMEMMAP_ENTS]; int nPMemMapEnts; @@ -58,61 +52,13 @@ int kmain(Uint MbMagic, void *MbInfoPtr) case MULTIBOOT_MAGIC: { // TODO: Handle when this isn't in the mapped area gsBootCmdLine = (char*)(mbInfo->CommandLine + KERNEL_BASE); - - tMBoot_MMapEnt *ent = (void*)mbInfo->MMapAddr; - tMBoot_MMapEnt *last = (void*)(mbInfo->MMapAddr + mbInfo->MMapLength); - - // Build up memory map - nPMemMapEnts = 0; - while( ent < last && nPMemMapEnts < MAX_PMEMMAP_ENTS ) - { - tPMemMapEnt *nent = &pmemmap[nPMemMapEnts]; - nent->Start = ent->Base; - nent->Length = ent->Length; - switch(ent->Type) - { - case 1: - nent->Type = PMEMTYPE_FREE; - break; - default: - nent->Type = PMEMTYPE_RESERVED; - break; - } - nent->NUMADomain = 0; - - nPMemMapEnts ++; - ent = (void*)( (tVAddr)ent + ent->Size + 4 ); - } - - // Ensure it's valid - nPMemMapEnts = PMemMap_ValidateMap(pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS); - // TODO: Error handling - - // Replace kernel with PMEMTYPE_USED - nPMemMapEnts = PMemMap_MarkRangeUsed( - pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS, - KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_LOAD - KERNEL_BASE - ); - - // Replace modules with PMEMTYPE_USED - nPMemMapEnts = PMemMap_MarkRangeUsed(pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS, - mbInfo->Modules, mbInfo->ModuleCount*sizeof(*mods) - ); - mods = (void*)mbInfo->Modules; - for( int i = 0; i < mbInfo->ModuleCount; i ++ ) - { - nPMemMapEnts = PMemMap_MarkRangeUsed( - pmemmap, nPMemMapEnts, MAX_PMEMMAP_ENTS, - mods->Start, mods->End - mods->Start - ); - } - - // Debug - Output map - PMemMap_DumpBlocks(pmemmap, nPMemMapEnts); // Adjust Multiboot structure address mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE ); - + + nPMemMapEnts = Multiboot_LoadMemoryMap(mbInfo, KERNEL_BASE, pmemmap, MAX_PMEMMAP_ENTS, + KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_BASE); + break; } // Multiboot 2 @@ -145,36 +91,7 @@ int kmain(Uint MbMagic, void *MbInfoPtr) VFS_Init(); // Load initial modules - mods = (void*)( mbInfo->Modules + KERNEL_BASE ); - giArch_NumBootModules = mbInfo->ModuleCount; - gaArch_BootModules = malloc( giArch_NumBootModules * sizeof(*gaArch_BootModules) ); - for( int i = 0; i < mbInfo->ModuleCount; i ++ ) - { - int ofs; - - Log_Log("Arch", "Multiboot Module at 0x%08x, 0x%08x bytes (String at 0x%08x)", - mods[i].Start, mods[i].End-mods[i].Start, mods[i].String); - - gaArch_BootModules[i].PBase = mods[i].Start; - gaArch_BootModules[i].Size = mods[i].End - mods[i].Start; - - // Always HW map the module data - ofs = mods[i].Start&0xFFF; - gaArch_BootModules[i].Base = (void*)( MM_MapHWPages(mods[i].Start, - (gaArch_BootModules[i].Size+ofs+0xFFF) / 0x1000 - ) + ofs ); - - // Only map the string if needed - if( (tVAddr)mods[i].String > MAX_ARGSTR_POS ) - { - // Assumes the string is < 4096 bytes long) - gaArch_BootModules[i].ArgString = (void*)( - MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF) - ); - } - else - gaArch_BootModules[i].ArgString = (char *)mods[i].String + KERNEL_BASE; - } + gaArch_BootModules = Multiboot_LoadModules(mbInfo, KERNEL_BASE, &giArch_NumBootModules); // Pass on to Independent Loader Log_Log("Arch", "Starting system"); diff --git a/KernelLand/Kernel/arch/x86/mboot.c b/KernelLand/Kernel/arch/x86/mboot.c new file mode 100644 index 00000000..5fe4068d --- /dev/null +++ b/KernelLand/Kernel/arch/x86/mboot.c @@ -0,0 +1,109 @@ +/* + * Acess2 Kernel x86 Port + * - By John Hodge (thePowersGang) + * + * mboot.c + * - Multiboot Support + */ +#define DEBUG 0 +#include +#include + +// === CODE === +int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *Map, const int MapSize, tPAddr KStart, tPAddr KEnd) +{ + int nPMemMapEnts = 0; + tMBoot_MMapEnt *ent = (void*)((tVAddr)MBInfo->MMapAddr + MapOffset); + tMBoot_MMapEnt *last = (void*)((tVAddr)ent + MBInfo->MMapLength); + + ENTER("pMBInfo pMapOffset pMap iMapSize PKStart PKEnd", + MBInfo, MapOffset, Map, MapSize, KStart, KEnd); + + // Build up memory map + nPMemMapEnts = 0; + while( ent < last && nPMemMapEnts < MapSize ) + { + tPMemMapEnt *nent = &Map[nPMemMapEnts]; + nent->Start = ent->Base; + nent->Length = ent->Length; + switch(ent->Type) + { + case 1: + nent->Type = PMEMTYPE_FREE; + break; + default: + nent->Type = PMEMTYPE_RESERVED; + break; + } + nent->NUMADomain = 0; + + nPMemMapEnts ++; + ent = (void*)( (tVAddr)ent + ent->Size + 4 ); + } + + // Ensure it's valid + nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize); + // TODO: Error handling + + // Replace kernel with PMEMTYPE_USED + nPMemMapEnts = PMemMap_MarkRangeUsed( + Map, nPMemMapEnts, MapSize, + KStart, KEnd - KStart + ); + + // Replace modules with PMEMTYPE_USED + nPMemMapEnts = PMemMap_MarkRangeUsed(Map, nPMemMapEnts, MapSize, + MBInfo->Modules, MBInfo->ModuleCount*sizeof(tMBoot_Module) + ); + tMBoot_Module *mods = (void*)( (tVAddr)MBInfo->Modules + MapOffset); + for( int i = 0; i < MBInfo->ModuleCount; i ++ ) + { + nPMemMapEnts = PMemMap_MarkRangeUsed( + Map, nPMemMapEnts, MapSize, + mods->Start, mods->End - mods->Start + ); + } + + // Debug - Output map + PMemMap_DumpBlocks(Map, nPMemMapEnts); + + LEAVE('i', nPMemMapEnts); + return nPMemMapEnts; +} + +tBootModule *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount) +{ + tMBoot_Module *mods = (void*)( MBInfo->Modules + MapOffset ); + *ModuleCount = MBInfo->ModuleCount; + tBootModule *ret = malloc( MBInfo->ModuleCount * sizeof(*ret) ); + for( int i = 0; i < MBInfo->ModuleCount; i ++ ) + { + int ofs; + + Log_Log("Arch", "Multiboot Module at 0x%08x, 0x%08x bytes (String at 0x%08x)", + mods[i].Start, mods[i].End-mods[i].Start, mods[i].String); + + ret[i].PBase = mods[i].Start; + ret[i].Size = mods[i].End - mods[i].Start; + + // Always HW map the module data + ofs = mods[i].Start&0xFFF; + ret[i].Base = (void*)( MM_MapHWPages(mods[i].Start, + (ret[i].Size+ofs+0xFFF) / 0x1000 + ) + ofs ); + + // Only map the string if needed + if( !MM_GetPhysAddr( (void*)(mods[i].String + MapOffset) ) ) + { + // Assumes the string is < 4096 bytes long) + ret[i].ArgString = (void*)( + MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF) + ); + } + else + ret[i].ArgString = (char*)(tVAddr)mods[i].String + MapOffset; + } + + return ret; +} + diff --git a/KernelLand/Kernel/arch/x86_64/Makefile b/KernelLand/Kernel/arch/x86_64/Makefile index a72216a3..4c030a58 100644 --- a/KernelLand/Kernel/arch/x86_64/Makefile +++ b/KernelLand/Kernel/arch/x86_64/Makefile @@ -27,6 +27,7 @@ A_OBJ := start32.ao start64.ao desctab.ao proc.ao A_OBJ += main.o lib.o proc.o mm_virt.o mm_phys.o A_OBJ += kernelpanic.o errors.o time.o pci.o A_OBJ += vm8086.o +A_OBJ += ../x86/mboot.o # rme.o POSTBUILD = objcopy $(BIN) -F elf32-i386 $(BIN) diff --git a/KernelLand/Kernel/arch/x86_64/include/archinit.h b/KernelLand/Kernel/arch/x86_64/include/archinit.h new file mode 100644 index 00000000..68988b8c --- /dev/null +++ b/KernelLand/Kernel/arch/x86_64/include/archinit.h @@ -0,0 +1,16 @@ +/* + * Acess2 Kernel x86_64 + * - By John Hodge (thePowersGang) + * + * include/init.h + * - Arch-internal init functions + */ +#ifndef _ARCH__INIT_H_ +#define _ARCH__INIT_H_ + +#include + +extern void MM_InitPhys(int NPMemRanges, tPMemMapEnt *PMemRanges); + +#endif + diff --git a/KernelLand/Kernel/arch/x86_64/main.c b/KernelLand/Kernel/arch/x86_64/main.c index cefeeb47..0348de68 100644 --- a/KernelLand/Kernel/arch/x86_64/main.c +++ b/KernelLand/Kernel/arch/x86_64/main.c @@ -1,11 +1,18 @@ /* - * Acess2 x86_64 Project + * Acess2 Kernel x86_64 + * - By John Hodge (thePowersGang) + * + * main.c + * - Kernel C entrypoint */ #include #include #include +#include +#include // === CONSTANTS === +#define KERNEL_LOAD 0x100000 #define MAX_PMEMMAP_ENTS 16 // === IMPORTS === @@ -14,7 +21,7 @@ extern void MM_InitVirt(void); extern void Heap_Install(void); extern int Time_Setup(void); -extern void MM_InitPhys_Multiboot(tMBoot_Info *MBoot); +extern char gKernelEnd[]; // === PROTOTYPES === void kmain(Uint MbMagic, void *MbInfoPtr); @@ -26,6 +33,8 @@ char *gsBootCmdLine = NULL; void kmain(Uint MbMagic, void *MbInfoPtr) { tMBoot_Info *mbInfo; + tPMemMapEnt pmemmap[MAX_PMEMMAP_ENTS]; + int nPMemMapEnts; LogF("%s\r\n", gsBuildInfo); @@ -41,7 +50,9 @@ void kmain(Uint MbMagic, void *MbInfoPtr) // Adjust Multiboot structure address mbInfo = (void*)( (Uint)MbInfoPtr + KERNEL_BASE ); gsBootCmdLine = (char*)( (Uint)mbInfo->CommandLine + KERNEL_BASE); - MM_InitPhys_Multiboot( mbInfo ); // Set up physical memory manager + nPMemMapEnts = Multiboot_LoadMemoryMap(mbInfo, KERNEL_BASE, pmemmap, MAX_PMEMMAP_ENTS, + KERNEL_LOAD, (tVAddr)&gKernelEnd - KERNEL_BASE + ); break; default: Panic("Multiboot magic invalid %08x, expected %08x\n", @@ -49,6 +60,7 @@ void kmain(Uint MbMagic, void *MbInfoPtr) return ; } + MM_InitPhys( nPMemMapEnts, pmemmap ); // Set up physical memory manager Log("gsBootCmdLine = '%s'", gsBootCmdLine); *(Uint16*)(KERNEL_BASE|0xB8000) = 0x1F00|'D'; diff --git a/KernelLand/Kernel/arch/x86_64/mm_phys.c b/KernelLand/Kernel/arch/x86_64/mm_phys.c index b537a9f4..27c4946e 100644 --- a/KernelLand/Kernel/arch/x86_64/mm_phys.c +++ b/KernelLand/Kernel/arch/x86_64/mm_phys.c @@ -5,7 +5,8 @@ */ #define DEBUG 0 #include -#include +#include +#include #include #define TRACE_REF 0 @@ -25,7 +26,7 @@ extern char gKernelBase[]; extern char gKernelEnd[]; // === PROTOTYPES === -void MM_InitPhys_Multiboot(tMBoot_Info *MBoot); +//void MM_InitPhys(int NPMemRanges, tPMemMapEnt *PMemRanges); //tPAddr MM_AllocPhysRange(int Num, int Bits); //tPAddr MM_AllocPhys(void); //void MM_RefPhys(tPAddr PAddr); @@ -52,6 +53,7 @@ Uint64 giPhysRangeFree[NUM_MM_PHYS_RANGES]; // Number of free pages in each rang 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 +Uint64 giTotalMemorySize = 0; // Only used in init, allows the init code to provide pages for use by // the allocator before the bitmaps exist. // 3 entries because the are three calls to MM_AllocPhys in MM_Map @@ -62,10 +64,8 @@ tPAddr gaiStaticAllocPages[NUM_STATIC_ALLOC] = {0}; /** * \brief Initialise the physical memory map using a Multiboot 1 map */ -void MM_InitPhys_Multiboot(tMBoot_Info *MBoot) +void MM_InitPhys(int NPMemRanges, tPMemMapEnt *PMemRanges) { - tMBoot_MMapEnt *mmapStart; - tMBoot_MMapEnt *ent; Uint64 maxAddr = 0; int numPages, superPages; int i; @@ -73,226 +73,165 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot) tVAddr vaddr; tPAddr paddr, firstFreePage; - ENTER("pMBoot=%p", MBoot); + ENTER("iNPMemRanges pPMemRanges", + NPMemRanges, PMemRanges); // Scan the physical memory map // Looking for the top of physical memory - mmapStart = (void *)( KERNEL_BASE | MBoot->MMapAddr ); - LOG("mmapStart = %p", mmapStart); - ent = mmapStart; - while( (Uint)ent < (Uint)mmapStart + MBoot->MMapLength ) + for( i = 0; i < NPMemRanges; i ++ ) { + tPMemMapEnt *ent = &PMemRanges[i]; // Adjust for the size of the entry - ent->Size += 4; - LOG("ent={Type:%i,Base:0x%x,Length:%x", - ent->Type, ent->Base, ent->Length); + LOG("%i: ent={Type:%i,Base:0x%x,Length:%x}", i, ent->Type, ent->Start, ent->Length); // If entry is RAM and is above `maxAddr`, change `maxAddr` - if(ent->Type == 1 && ent->Base + ent->Length > maxAddr) - maxAddr = ent->Base + ent->Length; - - // Go to next entry - ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size ); + if(ent->Type == PMEMTYPE_FREE || ent->Type == PMEMTYPE_USED ) + { + if( ent->Start + ent->Length > maxAddr) + maxAddr = ent->Start + ent->Length; + giTotalMemorySize += ent->Length >> 12; + } } - // Did we find a valid end? - if(maxAddr == 0) { - // No, darn, let's just use the HighMem hack - giMaxPhysPage = (MBoot->HighMem >> 2) + 256; // HighMem is a kByte value - } - else { - // Goodie, goodie gumdrops - giMaxPhysPage = maxAddr >> 12; - } + giMaxPhysPage = maxAddr >> 12; LOG("giMaxPhysPage = 0x%x", giMaxPhysPage); - - // Find a contigous section of memory to hold it in - // - Starting from the end of the kernel - // - We also need a region for the super bitmap + + // Get counts of pages needed for basic structures superPages = ((giMaxPhysPage+64*8-1)/(64*8) + 0xFFF) >> 12; - numPages = (giMaxPhysPage + 7) / 8; - numPages = (numPages + 0xFFF) >> 12; + numPages = ((giMaxPhysPage+7)/8 + 0xFFF) >> 12; // bytes to hold bitmap, divided up to nearest page LOG("numPages = %i, superPages = %i", numPages, superPages); - if(maxAddr == 0) + + // --- Allocate Bitmaps --- + int todo = numPages*2 + superPages; + int mapent = NPMemRanges-1; + vaddr = MM_PAGE_BITMAP; + paddr = -1; + while( todo ) { - int todo = numPages*2 + superPages; - // Ok, naieve allocation, just put it after the kernel - // - Allocated Bitmap - vaddr = MM_PAGE_BITMAP; - paddr = (tPAddr)&gKernelEnd - KERNEL_BASE; - while(todo ) + while(PMemRanges[mapent].Type != PMEMTYPE_FREE && mapent != -1) + mapent --; + if( paddr + 1 == 0 ) + paddr = PMemRanges[mapent].Start; + if( mapent == -1 ) { + // OOM During init, bad thing + Log_KernelPanic("PMem", "Out of memory during init"); + for(;;); + } + + // Ensure that the static allocation pool has pages + for( i = 0; i < NUM_STATIC_ALLOC; i++) { - // Allocate statics - for( i = 0; i < NUM_STATIC_ALLOC; i++) { - if(gaiStaticAllocPages[i] != 0) continue; + if(gaiStaticAllocPages[i] == 0) + { gaiStaticAllocPages[i] = paddr; - paddr += 0x1000; + // break to ensure we update the address correctly + break; } - + } + + if( i == NUM_STATIC_ALLOC ) + { + // Map MM_Map(vaddr, paddr); - vaddr += 0x1000; - paddr += 0x1000; - todo --; + // Update virtual pointer + vaddr += 0x1000; if( todo == numPages + superPages ) vaddr = MM_PAGE_DBLBMP; if( todo == superPages ) vaddr = MM_PAGE_SUPBMP; + } + + // Update physical pointer + // (underflows are detected at the top of the loop) + paddr += 0x1000; + if( paddr - PMemRanges[mapent].Start > PMemRanges[mapent].Length ) + mapent --; + else { + // NOTE: This hides some actually valid memory, but since the pmm + // structures have an "infinite" lifetime, this is of no concequence. + PMemRanges[mapent].Start += 0x1000; + PMemRanges[mapent].Length -= 0x1000; } } - // Scan for a nice range - else - { - int todo = numPages*2 + superPages; - paddr = 0; - vaddr = MM_PAGE_BITMAP; - // Scan! - for( - ent = mmapStart; - (Uint)ent < (Uint)mmapStart + MBoot->MMapLength; - ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size ) - ) - { - int avail; - - // RAM only please - if( ent->Type != 1 ) - continue; - - // Let's not put it below the kernel, shall we? - if( ent->Base + ent->Size < (tPAddr)&gKernelBase ) - continue; - - LOG("%x <= %x && %x > %x", - ent->Base, (tPAddr)&gKernelBase, - ent->Base + ent->Size, (tPAddr)&gKernelEnd - KERNEL_BASE - ); - // Check if the kernel is in this range - if( ent->Base <= (tPAddr)&gKernelBase - && ent->Base + ent->Length > (tPAddr)&gKernelEnd - KERNEL_BASE ) - { - avail = ent->Length >> 12; - avail -= ((tPAddr)&gKernelEnd - KERNEL_BASE - ent->Base) >> 12; - paddr = (tPAddr)&gKernelEnd - KERNEL_BASE; - } - // No? then we can use all of the block - else - { - avail = ent->Length >> 12; - paddr = ent->Base; - } - - Log("MM_InitPhys_Multiboot: paddr=0x%x, avail=0x%x pg", paddr, avail); - - // Map - while( todo && avail --) - { - // Static Allocations - for( i = 0; i < NUM_STATIC_ALLOC && avail; i++) { - if(gaiStaticAllocPages[i] != 0) continue; - gaiStaticAllocPages[i] = paddr; - paddr += 0x1000; - avail --; - } - if(!avail) break; - - // Map - MM_Map(vaddr, paddr); - todo --; - vaddr += 0x1000; - paddr += 0x1000; - - // Alter the destination address when needed - if(todo == superPages+numPages) - vaddr = MM_PAGE_DBLBMP; - if(todo == superPages) - vaddr = MM_PAGE_SUPBMP; - } - - // Fast quit if there's nothing left to allocate - if( !todo ) break; - } - } + + PMemMap_DumpBlocks(PMemRanges, NPMemRanges); + // Save the current value of paddr to simplify the allocation later firstFreePage = paddr; LOG("Clearing multi bitmap"); - // Fill the bitmaps - memset(gaMultiBitmap, 0, (numPages<<12)/8); - // - initialise to one, then clear the avaliable areas - memset(gaMainBitmap, -1, (numPages<<12)/8); - memset(gaSuperBitmap, -1, (numPages<<12)/(8*64)); - LOG("Setting main bitmap"); + // Fill the bitmaps (set most to "allocated") + memset(gaMultiBitmap, 0, numPages<<12); + memset(gaMainBitmap, 255, numPages<<12); // - Clear all Type=1 areas LOG("Clearing valid regions"); - for( - ent = mmapStart; - (Uint)ent < (Uint)mmapStart + MBoot->MMapLength; - ent = (tMBoot_MMapEnt *)( (Uint)ent + ent->Size ) - ) + for( i = 0; i < NPMemRanges; i ++ ) { + tPMemMapEnt *ent = &PMemRanges[i]; // Check if the type is RAM - if(ent->Type != 1) continue; + if(ent->Type != PMEMTYPE_FREE) continue; // Main bitmap - base = ent->Base >> 12; - size = ent->Size >> 12; - - if(base & 63) { - Uint64 val = -1LL << (base & 63); - gaMainBitmap[base / 64] &= ~val; - size -= (base & 63); - base += 64 - (base & 63); - } - memset( &gaMainBitmap[base / 64], 0, size/8 ); - if( size & 7 ) { - Uint64 val = -1LL << (size & 7); - val <<= (size/8)&7; - gaMainBitmap[base / 64] &= ~val; + base = ent->Start >> 12; + size = ent->Length >> 12; + + LOG("%i: base=%x, size=%x", i, base, size); + if( base % 64 + size < 64 ) + { + Uint64 bits = (1ULL << size) - 1; + bits <<= base % 64; + gaMainBitmap[base / 64] &= ~bits; } - - // Super Bitmap - base = ent->Base >> 12; - size = ent->Size >> 12; - size = (size + (base & 63) + 63) >> 6; - base = base >> 6; - if(base & 63) { - Uint64 val = -1LL << (base & 63); - gaSuperBitmap[base / 64] &= ~val; -// size -= (base & 63); -// base += 64 - (base & 63); + else + { + if(base & 63) + { + // Keep lower bits + Uint64 bits = (1ULL << (base & 63)) - 1; + gaMainBitmap[base / 64] &= bits; + + size -= 64 - base % 64; + base += 64 - base % 64; + } + LOG("%i: base=%x, size=%x", i, base, size); + memset( &gaMainBitmap[base / 64], 0, (size/64)*8 ); + base += size & ~(64-1); + size -= size & ~(64-1); + LOG("%i: base=%x, size=%x", i, base, size); + if( size & 63 ) + { + // Unset lower bits (hence the bitwise not) + Uint64 val = (1ULL << (size & 63)) - 1; + gaMainBitmap[base / 64] &= ~val; + } } } - // Reference the used pages - base = (tPAddr)&gKernelBase >> 12; - size = firstFreePage >> 12; - memset( &gaMainBitmap[base / 64], -1, size/8 ); - if( size & 7 ) { - Uint64 val = -1LL << (size & 7); - val <<= (size/8)&7; - gaMainBitmap[base / 64] |= val; - } - // Free the unused static allocs - for( i = 0; i < NUM_STATIC_ALLOC; i++) { - if(gaiStaticAllocPages[i] != 0) - continue; - gaMainBitmap[ gaiStaticAllocPages[i] >> (12+6) ] - &= ~(1LL << ((gaiStaticAllocPages[i]>>12)&63)); + LOG("Freeing unused static allocations"); + for( i = 0; i < NUM_STATIC_ALLOC; i++) + { + if(gaiStaticAllocPages[i] == 0) + { + gaMainBitmap[ gaiStaticAllocPages[i] >> (12+6) ] + &= ~(1LL << ((gaiStaticAllocPages[i]>>12)&63)); + gaiStaticAllocPages[i] = 0; + } } // Fill the super bitmap LOG("Filling super bitmap"); memset(gaSuperBitmap, 0, superPages<<12); - for( base = 0; base < (size+63)/64; base ++) + int nsuperbits = giMaxPhysPage / 64; // 64 pages per bit + for( i = 0; i < (nsuperbits+63)/64; i ++) { - if( gaMainBitmap[ base ] + 1 == 0 ) - gaSuperBitmap[ base/64 ] |= 1LL << (base&63); + if( gaMainBitmap[ i ] + 1 == 0 ) + gaSuperBitmap[ i/64 ] |= 1ULL << (i % 64); } - // Set free page counts + // Set free page counts for each address class for( base = 1; base < giMaxPhysPage; base ++ ) { int rangeID; @@ -311,8 +250,8 @@ void MM_InitPhys_Multiboot(tMBoot_Info *MBoot) // Set last (when the last free page is reached, this won't be // updated anymore, hence will be correct) giPhysRangeLast[ rangeID ] = base; - } - + } + LEAVE('-'); } diff --git a/KernelLand/Kernel/include/bootmod.h b/KernelLand/Kernel/include/bootmod.h new file mode 100644 index 00000000..09793895 --- /dev/null +++ b/KernelLand/Kernel/include/bootmod.h @@ -0,0 +1,21 @@ +/* + * Acess2 Kernel + * - By John Hodge (thePowersGang) + * + * include/bootmod.h + * - Common boot modules type + */ +#ifndef _BOOTMOD_H_ +#define _BOOTMOD_H_ + +typedef struct sBootModule tBootModule; + +struct sBootModule { + tPAddr PBase; + void *Base; + Uint Size; + char *ArgString; +}; + +#endif + diff --git a/KernelLand/Kernel/include/mboot.h b/KernelLand/Kernel/include/mboot.h index c7f33ddb..61c689bd 100644 --- a/KernelLand/Kernel/include/mboot.h +++ b/KernelLand/Kernel/include/mboot.h @@ -4,9 +4,13 @@ */ #ifndef _MBOOT_H #define _MBOOT_H +#include #define MULTIBOOT_MAGIC 0x2BADB002 +#include +#include + // === TYPES === typedef struct { Uint32 Flags; @@ -35,4 +39,7 @@ typedef struct { Uint32 Type; //1:RAM,Else Reserved } __attribute__ ((packed)) tMBoot_MMapEnt; +extern int Multiboot_LoadMemoryMap(tMBoot_Info *MBInfo, tVAddr MapOffset, tPMemMapEnt *Map, const int MapSize, tPAddr KStart, tPAddr KEnd); +extern tBootModule *Multiboot_LoadModules(tMBoot_Info *MBInfo, tVAddr MapOffset, int *ModuleCount); + #endif -- 2.20.1