Using the memory map for the heap.

This commit is contained in:
Patrick 2024-01-11 22:54:41 +01:00
parent 97732de3ae
commit 164f05bd59
6 changed files with 139 additions and 15 deletions

View File

@ -42,7 +42,8 @@ env['LINKCOM'] = env['LINKCOM'].replace('$_LIBFLAGS', f'{crti_o[0]} {crtbegin_o}
prog_os = env.Program( prog_os = env.Program(
target = 'os.bin', target = 'os.bin',
source = os_sources source = os_sources,
LIBS = ['gcc']
) )
env.Depends(prog_os, [crti_o, crtn_o]) env.Depends(prog_os, [crti_o, crtn_o])
env.Default(prog_os) env.Default(prog_os)

View File

@ -13,4 +13,6 @@ using ::malloc;
using ::free; using ::free;
} }
void __ba_registerAllocatableMemory(void* memory, size_t size) noexcept;
#endif // !defined(BAD_APPLE_OS_CSTDLIB_INCLUDED) #endif // !defined(BAD_APPLE_OS_CSTDLIB_INCLUDED)

View File

@ -57,4 +57,5 @@ SECTIONS
/* The compiler may produce other sections, by default it will put them in /* The compiler may produce other sections, by default it will put them in
a segment with the same name. Simply add stuff here as needed. */ a segment with the same name. Simply add stuff here as needed. */
gKernelEnd = .;
} }

View File

@ -3,21 +3,39 @@
#include <cassert> #include <cassert>
#include <cstdio> #include <cstdio>
#include <cstdlib>
#include "./multiboot.h" #include "./multiboot.h"
extern "C" int gKernelEnd;
namespace namespace
{ {
void initHeapFromMultibootHeader(const uint32_t firstEntryAddr, const size_t bufferLength) noexcept void initHeapFromMultibootHeader(const uint32_t firstEntryAddr, const size_t bufferLength) noexcept
{ {
const uint64_t minAddr = reinterpret_cast<uint64_t>(&gKernelEnd);
for (uint32_t addr = firstEntryAddr; addr < firstEntryAddr + bufferLength;) for (uint32_t addr = firstEntryAddr; addr < firstEntryAddr + bufferLength;)
{ {
const multiboot_memory_map_t& entry = *reinterpret_cast<multiboot_memory_map_t*>(addr); multiboot_memory_map_t entry = *reinterpret_cast<multiboot_memory_map_t*>(addr);
if(entry.type == MULTIBOOT_MEMORY_AVAILABLE) if(entry.type == MULTIBOOT_MEMORY_AVAILABLE)
{ {
std::printf("Start Addr: %d | Length: %d | Size: %d | Type: %d\n", std::printf("Start Addr: %X | Length: %b\n",
static_cast<int>(entry.addr), static_cast<int>(entry.len), static_cast<unsigned>(entry.addr), static_cast<size_t>(entry.len));
static_cast<int>(entry.size), static_cast<int>(entry.type));
// anything before the kernel we ignore
if (entry.addr < minAddr)
{
// if the entire entry is before the kernel, continue
if (entry.addr + entry.len <= minAddr)
{
addr += sizeof(entry.size) + entry.size;
continue;
}
// otherwise shrink it and use the rest
entry.len -= (minAddr - entry.addr);
entry.addr = minAddr;
}
__ba_registerAllocatableMemory(reinterpret_cast<void*>(entry.addr), entry.len);
} }
addr += sizeof(entry.size) + entry.size; addr += sizeof(entry.size) + entry.size;
} }
@ -39,6 +57,8 @@ void kernel_main()
/* Initialize terminal interface */ /* Initialize terminal interface */
tty::initialize(); tty::initialize();
std::printf("Kernel End: %p\n", &gKernelEnd);
/* Initialize the heap */ /* Initialize the heap */
assert(gMultibootHeader->flags & MULTIBOOT_INFO_MEM_MAP); assert(gMultibootHeader->flags & MULTIBOOT_INFO_MEM_MAP);
initHeapFromMultibootHeader(gMultibootHeader->mmap_addr, gMultibootHeader->mmap_length); initHeapFromMultibootHeader(gMultibootHeader->mmap_addr, gMultibootHeader->mmap_length);

View File

@ -38,6 +38,94 @@ int printInt(int value)
} }
return pos - digits; return pos - digits;
} }
int printUInt(uint64_t value)
{
if (value == 0)
{
putchar('0');
return 1;
}
char digits[20]; // 18,446,744,073,709,551,615 has 20 digits
char* pos = &digits[0];
while (value > 0)
{
*pos = static_cast<char>('0' + (value % 10));
value /= 10;
++pos;
}
for (char* chr = pos - 1; chr >= digits; --chr)
{
putchar(*chr);
}
return pos - digits;
}
int printHexInt(uint64_t value)
{
if (value == 0)
{
putchar('0');
return 1;
}
char digits[16]; // FFFFFFFFFFFFFFFF has 16 digits
char* pos = &digits[0];
while (value > 0)
{
const uint64_t digit = (value % 16);
if (digit < 10)
{
*pos = static_cast<char>('0' + digit);
}
else
{
*pos = static_cast<char>('A' + digit - 10);
}
value /= 16;
++pos;
}
for (char* chr = pos - 1; chr >= digits; --chr)
{
putchar(*chr);
}
return pos - digits;
}
int printPointer(void* ptr)
{
return printHexInt(reinterpret_cast<uint64_t>(ptr));
}
int printString(const char* str)
{
const size_t len = std::strlen(str);
for (size_t idx = 0; idx < len; ++idx)
{
putchar(str[idx]);
}
return static_cast<int>(len);
}
int printByteSize(size_t bytes)
{
const char* suffixes[] = {
"B", "KiB", "MiB", "GiB", "TiB"
};
int suffixIdx = 0;
for (; suffixIdx < sizeof(suffixes) / sizeof(suffixes[0]); ++suffixIdx)
{
if (bytes < 1024) {
break;
}
bytes /= 1024;
}
return printUInt(bytes) + printString(suffixes[suffixIdx]);
}
} }
int putchar(int chr) noexcept int putchar(int chr) noexcept
@ -81,6 +169,9 @@ int vprintf(const char* format, std::va_list vlist) BA_CXX_NOEXCEPT
// TODO: invalid format string, do something // TODO: invalid format string, do something
assert(!"Invalid format string, ends with %."); assert(!"Invalid format string, ends with %.");
return -1; return -1;
case 'b':
result += printByteSize(va_arg(vlist, size_t));
break;
case 'c': case 'c':
{ {
const char chr = static_cast<char>(va_arg(vlist, int)); const char chr = static_cast<char>(va_arg(vlist, int));
@ -89,20 +180,17 @@ int vprintf(const char* format, std::va_list vlist) BA_CXX_NOEXCEPT
break; break;
} }
case 's': case 's':
{ result += printString(va_arg(vlist, const char*));
const char* str = va_arg(vlist, const char*);
const size_t len = std::strlen(str);
for (size_t idx = 0; idx < len; ++idx)
{
putchar(str[idx]);
}
result += static_cast<int>(len);
break; break;
}
case 'd': case 'd':
result += printInt(va_arg(vlist, int)); result += printInt(va_arg(vlist, int));
break; break;
case 'p':
result += printPointer(va_arg(vlist, void*));
break;
case 'X':
result += printHexInt(va_arg(vlist, unsigned));
break;
default: default:
assert(!"Invalid format string, unknown format identifier."); assert(!"Invalid format string, unknown format identifier.");
return -1; return -1;

View File

@ -32,6 +32,18 @@ MallocBlock* gNextBlock = []()
}(); }();
} }
void __ba_registerAllocatableMemory(void* memory, size_t size) noexcept
{
if (size < sizeof(max_align_t))
{
return;
}
MallocBlock* newBlock = static_cast<MallocBlock*>(memory);
newBlock->nextBlock = gNextBlock;
newBlock->elements = size / sizeof(max_align_t);
gNextBlock = newBlock;
}
extern "C" extern "C"
{ {
void abort() void abort()