fix(kernel/memory): correct bitmap address calculation

This commit is contained in:
EnderIce2 2025-04-08 02:31:40 +00:00
parent eb89b060f6
commit 3d87345a51
Signed by: enderice2
GPG Key ID: FEB6B8A8507BA62E
4 changed files with 45 additions and 63 deletions

View File

@ -28,8 +28,7 @@
namespace Memory namespace Memory
{ {
__no_sanitize("alignment") void Physical::FindBitmapRegion(uintptr_t &BitmapAddress, __no_sanitize("alignment") void Physical::FindBitmapRegion(uintptr_t &BitmapAddress, size_t &BitmapAddressSize)
size_t &BitmapAddressSize)
{ {
size_t BitmapSize = (size_t)(bInfo.Memory.Size / PAGE_SIZE) / 8 + 1; size_t BitmapSize = (size_t)(bInfo.Memory.Size / PAGE_SIZE) / 8 + 1;
@ -47,24 +46,19 @@ namespace Memory
uintptr_t RSDPStart = 0x0; uintptr_t RSDPStart = 0x0;
uintptr_t RSDPEnd = 0x0; uintptr_t RSDPEnd = 0x0;
if (bInfo.Kernel.Symbols.Num && if (bInfo.Kernel.Symbols.Num && bInfo.Kernel.Symbols.EntSize && bInfo.Kernel.Symbols.Shndx)
bInfo.Kernel.Symbols.EntSize &&
bInfo.Kernel.Symbols.Shndx)
{ {
char *sections = r_cst(char *, bInfo.Kernel.Symbols.Sections); char *sections = r_cst(char *, bInfo.Kernel.Symbols.Sections);
SectionsStart = (uintptr_t)sections; SectionsStart = (uintptr_t)sections;
SectionsEnd = (uintptr_t)sections + bInfo.Kernel.Symbols.EntSize * SectionsEnd = (uintptr_t)sections + bInfo.Kernel.Symbols.EntSize * bInfo.Kernel.Symbols.Num;
bInfo.Kernel.Symbols.Num;
for (size_t i = 0; i < bInfo.Kernel.Symbols.Num; ++i) for (size_t i = 0; i < bInfo.Kernel.Symbols.Num; ++i)
{ {
Elf_Shdr *sym = (Elf_Shdr *)&sections[bInfo.Kernel.Symbols.EntSize * i]; Elf_Shdr *sym = (Elf_Shdr *)&sections[bInfo.Kernel.Symbols.EntSize * i];
Elf_Shdr *str = (Elf_Shdr *)&sections[bInfo.Kernel.Symbols.EntSize * Elf_Shdr *str = (Elf_Shdr *)&sections[bInfo.Kernel.Symbols.EntSize * sym->sh_link];
sym->sh_link];
if (sym->sh_type == SHT_SYMTAB && if (sym->sh_type == SHT_SYMTAB && str->sh_type == SHT_STRTAB)
str->sh_type == SHT_STRTAB)
{ {
Symbols = (uintptr_t)sym->sh_addr; Symbols = (uintptr_t)sym->sh_addr;
StringAddress = (uintptr_t)str->sh_addr; StringAddress = (uintptr_t)str->sh_addr;
@ -95,8 +89,7 @@ namespace Memory
if (Memory::Virtual().Check(ACPIPtr)) if (Memory::Virtual().Check(ACPIPtr))
{ {
size_t TableSize = ((ACPIPtr->Length - sizeof(ACPI::ACPI::ACPIHeader)) / size_t TableSize = ((ACPIPtr->Length - sizeof(ACPI::ACPI::ACPIHeader)) / (XSDT ? 8 : 4));
(XSDT ? 8 : 4));
debug("There are %d ACPI tables", TableSize); debug("There are %d ACPI tables", TableSize);
} }
#endif #endif
@ -131,6 +124,7 @@ namespace Memory
{ {
uintptr_t Start; uintptr_t Start;
uintptr_t End; uintptr_t End;
char Description[16];
}; };
auto SortAddresses = [](AddrRange *Array, size_t n) auto SortAddresses = [](AddrRange *Array, size_t n)
@ -151,61 +145,57 @@ namespace Memory
AddrRange PtrArray[] = AddrRange PtrArray[] =
{ {
{KernelStart, {KernelStart, KernelEnd, "kernel"},
KernelEnd}, {SectionsStart, SectionsEnd, "sections"},
{SectionsStart, {Symbols, Symbols + SymbolSize, "symbols"},
SectionsEnd}, {StringAddress, StringAddress + StringSize, "string"},
{Symbols, {RSDPStart, RSDPEnd, "rsdp"},
Symbols + SymbolSize}, {(uintptr_t)bInfo.Kernel.FileBase, (uintptr_t)bInfo.Kernel.FileBase + bInfo.Kernel.Size, "file"},
{StringAddress, {(uintptr_t)bInfo.Modules[0].Address, (uintptr_t)bInfo.Modules[0].Address + bInfo.Modules[0].Size, "module 0"},
StringAddress + StringSize}, {(uintptr_t)bInfo.Modules[1].Address, (uintptr_t)bInfo.Modules[1].Address + bInfo.Modules[1].Size, "module 1"},
{RSDPStart, {(uintptr_t)bInfo.Modules[2].Address, (uintptr_t)bInfo.Modules[2].Address + bInfo.Modules[2].Size, "module 2"},
RSDPEnd}, {(uintptr_t)bInfo.Modules[3].Address, (uintptr_t)bInfo.Modules[3].Address + bInfo.Modules[3].Size, "module 3"},
{(uintptr_t)bInfo.Kernel.FileBase,
(uintptr_t)bInfo.Kernel.FileBase + bInfo.Kernel.Size},
{(uintptr_t)bInfo.Modules[0].Address,
(uintptr_t)bInfo.Modules[0].Address + bInfo.Modules[0].Size},
{(uintptr_t)bInfo.Modules[1].Address,
(uintptr_t)bInfo.Modules[1].Address + bInfo.Modules[1].Size},
{(uintptr_t)bInfo.Modules[2].Address,
(uintptr_t)bInfo.Modules[2].Address + bInfo.Modules[2].Size},
{(uintptr_t)bInfo.Modules[3].Address,
(uintptr_t)bInfo.Modules[3].Address + bInfo.Modules[3].Size},
/* MAX_MODULES == 4 */ /* MAX_MODULES == 4 */
}; };
SortAddresses(PtrArray, sizeof(PtrArray) / sizeof(PtrArray[0])); SortAddresses(PtrArray, sizeof(PtrArray) / sizeof(PtrArray[0]));
uintptr_t MaxEnd = RegionAddress;
for (size_t i = 0; i < sizeof(PtrArray) / sizeof(PtrArray[0]); i++) for (size_t i = 0; i < sizeof(PtrArray) / sizeof(PtrArray[0]); i++)
{ {
if (PtrArray[i].Start == 0x0) if (PtrArray[i].Start == 0x0)
{
debug("skipping %#lx %zu %s", PtrArray[i].Start, i, PtrArray[i].Description);
continue; continue;
}
uintptr_t Start = PtrArray[i].Start; uintptr_t Start = PtrArray[i].Start;
uintptr_t End = PtrArray[i].End; uintptr_t End = PtrArray[i].End;
debug("%#lx - %#lx", Start, End); debug("[%s] %#lx - %#lx", PtrArray[i].Description, Start, End);
if (RegionAddress >= Start && if ((Start < (RegionAddress + RegionSize)) && (End > RegionAddress))
End <= (RegionAddress + RegionSize))
{ {
BitmapAddress = End; if (End > MaxEnd)
BitmapAddressSize = RegionSize - (End - RegionAddress); MaxEnd = End;
} }
} }
if ((BitmapSize + 0x100) > BitmapAddressSize) if (MaxEnd >= RegionAddress && MaxEnd < (RegionAddress + RegionSize))
{ {
debug("Region %p-%p (%d MiB) is too small for bitmap.", BitmapAddress = MaxEnd;
(void *)BitmapAddress, BitmapAddressSize = RegionAddress + RegionSize - MaxEnd;
(void *)(BitmapAddress + BitmapAddressSize),
TO_MiB(BitmapAddressSize));
continue;
}
debug("Found free memory for bitmap: %p (%d MiB)", debug("BitmapAddress = %#lx; Size = %zu", BitmapAddress, BitmapAddressSize);
(void *)BitmapAddress,
TO_MiB(BitmapAddressSize)); if ((BitmapSize + 0x100) > BitmapAddressSize)
break; {
debug("Region %#lx-%#lx (%d MiB) is too small for bitmap.", BitmapAddress, BitmapAddress + BitmapAddressSize, TO_MiB(BitmapAddressSize));
continue;
}
debug("Found free memory for bitmap: %#lx (%d MiB)", BitmapAddress, TO_MiB(BitmapAddressSize));
break;
}
} }
} }
} }

View File

@ -340,7 +340,7 @@ NIF void InitializeMemoryManagement()
KernelAllocator.Init(); KernelAllocator.Init();
debug("Memory Info:\n\n%lld MiB / %lld MiB (%lld MiB reserved)\n", debug("Memory Info:\n\n%lld MiB / %lld MiB (%lld MiB reserved)\n",
TO_MiB(KernelAllocator.GetUsedMemory()), TO_MiB(KernelAllocator.GetUsedMemory()),
TO_MiB(KernelAllocator.GetTotalMemory()), TO_MiB(KernelAllocator.GetTotalMemory() - KernelAllocator.GetReservedMemory()),
TO_MiB(KernelAllocator.GetReservedMemory())); TO_MiB(KernelAllocator.GetReservedMemory()));
/* -- Debugging -- /* -- Debugging --
@ -361,8 +361,7 @@ NIF void InitializeMemoryManagement()
CreatePageTable(KernelPageTable); CreatePageTable(KernelPageTable);
trace("Applying new page table from address %#lx", trace("Applying new page table from address %#lx", KernelPageTable);
KernelPageTable);
CPU::PageTable(KernelPageTable); CPU::PageTable(KernelPageTable);
debug("Page table updated."); debug("Page table updated.");

View File

@ -322,8 +322,7 @@ namespace Memory
SmartLock(this->MemoryLock); SmartLock(this->MemoryLock);
uint64_t MemorySize = bInfo.Memory.Size; uint64_t MemorySize = bInfo.Memory.Size;
debug("Memory size: %lld bytes (%ld pages)", debug("Memory size: %lld bytes (%ld pages)", MemorySize, TO_PAGES(MemorySize));
MemorySize, TO_PAGES(MemorySize));
TotalMemory.store(MemorySize); TotalMemory.store(MemorySize);
FreeMemory.store(MemorySize); FreeMemory.store(MemorySize);
@ -338,16 +337,10 @@ namespace Memory
CPU::Stop(); CPU::Stop();
} }
debug("Initializing Bitmap at %p-%p (%d Bytes)", debug("Initializing Bitmap at %#lx-%#lx (%zu Bytes)", BitmapAddress, BitmapAddress + BitmapSize, BitmapSize);
BitmapAddress,
(void *)(BitmapAddress + BitmapSize),
BitmapSize);
PageBitmap.Size = BitmapSize; PageBitmap.Size = BitmapSize;
PageBitmap.Buffer = (uint8_t *)BitmapAddress; PageBitmap.Buffer = (uint8_t *)BitmapAddress;
for (size_t i = 0; i < BitmapSize; i++) memset((void *)BitmapAddress, 0, BitmapSize);
*(uint8_t *)(PageBitmap.Buffer + i) = 0;
ReserveEssentials(); ReserveEssentials();
} }

View File

@ -184,7 +184,7 @@ namespace SymbolResolver
if (unlikely(sym->st_name == (Elf_Word)-1 || sym->st_value == (Elf_Addr)-1 || sym->st_size == (uintptr_t)-1)) if (unlikely(sym->st_name == (Elf_Word)-1 || sym->st_value == (Elf_Addr)-1 || sym->st_size == (uintptr_t)-1))
{ {
error("Symbol %d is invalid", i); error("Symbol %d is invalid; ptr:%#lx", i, sym);
continue; continue;
} }