42 #define PHYSMEMEXTRA_SIZE 0x1000 43 #define PHYSMEMEXTRA_MASK 0x3FF 44 #define PHYSMEMEXTRA_BITS 10 45 #define PHYSMEMEXTRA_COUNT 0x400 62 static bool physMemInitialized =
false;
69 #define LINKER_KERNEL_BEGIN ((uint32_t)&__kernelBegin) 70 #define LINKER_KERNEL_SIZE ((uint32_t)&__kernelEnd - (uint32_t)&__kernelBegin) 72 static const char *error_outOfMemory[] =
75 " The system ran out of physical memory!",
80 asm(
".text\n.align 4\n" 87 static struct physMemExtraInfo *__getPhysMemExtraInfo(uint32_t index,
bool alloc)
95 if (!alloc)
return NULL;
120 assert(!physMemInitialized);
125 memset(physMemExtra, 0,
sizeof(physMemExtra));
138 while (offset < bootInfo->mmap_length)
140 uint64_t startIndex, stopIndex;
143 offset +=
sizeof(memMap->
size) + memMap->
size;
152 if (stopIndex <= startIndex)
186 for (uint32_t i = 0; i < bootInfo->mods_count; i++)
188 if (module[i].mod_start >= module[i].mod_end)
209 physMemInitialized =
true;
246 uint32_t mask = reserved ? 0xFFFFFFFF : 0;
249 for (longIndex = 0; longIndex <
sizeof(physMemMap) /
sizeof(physMemMap[0]); longIndex++)
250 physMemMap[longIndex] = mask;
267 assert(startIndex <= stopIndex);
288 assert(startIndex <= stopIndex);
302 uint32_t stopIndex = ((uint64_t)addr + length) >>
PAGE_BITS;
307 assert(startIndex <= stopIndex);
321 uint32_t longIndex, longOffset;
328 longIndex = startIndex >> 5;
329 longOffset = startIndex & 31;
336 if (length > 32 - longOffset)
338 mask = 0xFFFFFFFF << longOffset;
339 length -= (32 - longOffset);
343 mask = ((1 << length) - 1) << longOffset;
348 physMemMap[longIndex++] |= mask;
350 physMemMap[longIndex++] &= ~mask;
354 mask = reserved ? 0xFFFFFFFF : 0;
357 physMemMap[longIndex++] = mask;
364 mask = (1 << length) - 1;
367 physMemMap[longIndex] |= mask;
369 physMemMap[longIndex] &= ~mask;
385 uint32_t
try, longIndex, longOffset;
387 for (
try = 0;
try < 0x10;
try++)
390 for (longIndex = lowmem ? 0 : 8 ; longIndex <
sizeof(physMemMap) /
sizeof(physMemMap[0]); longIndex++)
392 if (physMemMap[longIndex] != 0xFFFFFFFF)
396 if (longIndex <
sizeof(physMemMap) /
sizeof(physMemMap[0]))
400 while ((physMemMap[longIndex] >> longOffset) & 1)
403 physMemMap[longIndex] |= (1 << longOffset);
405 return longIndex << 5 | longOffset;
429 uint32_t longIndex, longOffset;
431 longIndex = index >> 5;
432 longOffset = index & 31;
435 assert(((physMemMap[longIndex] >> longOffset) & 1));
437 info = __getPhysMemExtraInfo(index,
false);
438 if (info && info->
value)
443 if (--info->
ref)
return info->
ref;
450 physMemMap[longIndex] &= ~(1 << longOffset);
513 return (!info || !info->
value || info->
ref == 1);
546 uint32_t startIndex = 0;
548 uint32_t mask = reserved ? 0xFFFFFFFF : 0;
551 uint32_t longIndex = 0, longOffset = 0;
553 uint32_t usableMemory = 0;
561 longIndex = index >> 5;
562 longOffset = index & 31;
564 if (physMemMap[longIndex] == mask)
566 index += (32 - longOffset);
569 else if (((physMemMap[longIndex] >> longOffset) & 1) ==
reserved)
585 usableMemory += (index - startIndex) <<
PAGE_BITS;
591 startIndex = index++;
592 reserved = (physMemMap[longIndex] >> longOffset) & 1;
593 mask = reserved ? 0xFFFFFFFF : 0;
void physMemFreeMemory(uint32_t addr, uint32_t length)
Marks all pages fully contained within the memory range as free.
uint32_t physMemReleasePage(uint32_t index)
Releases a page of physical memory.
#define PHYSMEMEXTRA_MASK
uint32_t physMemMarkUnpageable(uint32_t index)
Marks a physical page as unpageable.
#define MULTIBOOT_INFO_CMDLINE
void * memset(void *ptr, int value, size_t num)
Fills a memory region with some specific byte value.
uint32_t physMemPageIn(UNUSED uint32_t hdd_index)
Pages in some data from the hard drive.
uint32_t stringLength(const char *str)
Returns the length of a nullterminated string.
void physMemProtectBootEntry(uint32_t addr, uint32_t length)
Marks all pages within a memory range as reserved and adds them to the boot map.
#define LINKER_KERNEL_BEGIN
bool physMemIsLastRef(uint32_t index)
Checks if a physical page is only referenced exactly one time.
void * pagingAllocatePhysMem(struct process *p, uint32_t length, bool rw, bool user)
Allocates several pages of physical memory in a process.
#define MULTIBOOT_MEMORY_INFO
void physMemReserveMemory(uint32_t addr, uint32_t length)
Marks all pages within a memory range as reserved.
#define MULTIBOOT_INFO_MODS
uint32_t physMemAddRefPage(uint32_t index)
Increment the refcounter of a physical page.
void physMemSetMemoryBits(uint32_t startIndex, uint32_t length, bool reserved)
Marks a specific range of pages as reserved or free.
void physMemInit(multiboot_info_t *bootInfo)
Initializes the physical memory management.
uint32_t physMemRAMSize()
Query RAM size.
#define PHYSMEMEXTRA_BITS
#define MULTIBOOT_MEMORY_AVAILABLE
#define LINKER_KERNEL_SIZE
multiboot_uint32_t mmap_addr
void consoleWriteHex32(uint32_t value)
Write a 32 bit integer as hex value on the console.
#define SYSTEM_FAILURE(lines,...)
#define PHYSMEMEXTRA_COUNT
void physMemDumpMemInfo()
Dumps information about the physical memory usage.
uint32_t physMemAllocPage(bool lowmem)
Allocates a page of physical memory.
uint32_t pagingGetPhysMem(struct process *p, void *addr)
Returns the physical page index for a virtual address.
void physMemClearMemoryBits(bool reserved)
Marks the full memory range as reserved or free.
void consoleWriteString(const char *str)
Write a C string to the console.
void physMemPageOut(UNUSED uint32_t length)
Pages out some memory to the hard drive.
multiboot_uint32_t mem_upper
#define MULTIBOOT_INFO_MEM_MAP
uint32_t physMemUsableMemory()
Query usable RAM size.
void pagingInsertBootMap(uint32_t startIndex, uint32_t stopIndex)
Appends a specific range of physical pages to the bootmap.