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);
// Check that the memory map is present
if( MBInfo->Flags & (1 << 6) )
{
+ tMBoot_MMapEnt *ent = (void*)((tVAddr)MBInfo->MMapAddr + MapOffset);
+ tMBoot_MMapEnt *last = (void*)((tVAddr)ent + MBInfo->MMapLength);
// Build up memory map
nPMemMapEnts = 0;
while( ent < last && nPMemMapEnts < MapSize )
if( !MM_GetPhysAddr(ent) )
Log_KernelPanic("MBoot", "MBoot Map entry %i addres bad (%p)",
nPMemMapEnts, ent);
+ LOG("%llx+%llx", ent->Base, ent->Length);
nent->Start = ent->Base;
nent->Length = ent->Length;
nPMemMapEnts ++;
ent = (void*)( (tVAddr)ent + ent->Size + 4 );
}
+ if( ent < last )
+ {
+ Log_Warning("MBoot", "Memory map has >%i entries, internal version is truncated",
+ MapSize);
+ }
}
else if( MBInfo->Flags & (1 << 0) )
{
Log_Warning("MBoot", "No memory map passed, using mem_lower and mem_upper");
+ ASSERT(MapSize >= 2);
nPMemMapEnts = 2;
Map[0].Start = 0;
Map[0].Length = MBInfo->LowMem * 1024;
}
// Ensure it's valid
+ LOG("Validating");
nPMemMapEnts = PMemMap_ValidateMap(Map, nPMemMapEnts, MapSize);
// TODO: Error handling
// Replace kernel with PMEMTYPE_USED
+ LOG("Marking kernel");
nPMemMapEnts = PMemMap_MarkRangeUsed(
Map, nPMemMapEnts, MapSize,
KStart, KEnd - KStart
);
+ LOG("Dumping");
PMemMap_DumpBlocks(Map, nPMemMapEnts);
// Check if boot modules were passed
// 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 );
+ ret[i].Base = (void*)( (tVAddr)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;
+ // Assumes the string is < 4096 bytes long)
+ ret[i].ArgString = (char*)MM_MapHWPages(mods[i].String, 2) + (mods[i].String&0xFFF);
}
return ret;
}
+void Multiboot_FreeModules(const int ModuleCount, tBootModule *Modules)
+{
+ for( int i = 0; i < ModuleCount; i ++ )
+ {
+ Uint ofs = Modules[i].PBase % PAGE_SIZE;
+ Uint nPages = (Modules[i].Size+ofs+PAGE_SIZE-1) / PAGE_SIZE;
+ MM_UnmapHWPages(Modules[i].Base, nPages);
+ MM_UnmapHWPages(Modules[i].ArgString, 2);
+
+ // TODO: handle previous freeing of this page
+ for( int pg = 0; pg < nPages; pg ++ )
+ MM_DerefPhys( Modules[i].PBase + pg*PAGE_SIZE );
+ }
+ free(Modules);
+}
+