Using the memory map for the heap.
This commit is contained in:
parent
97732de3ae
commit
164f05bd59
@ -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)
|
||||||
|
@ -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)
|
||||||
|
@ -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 = .;
|
||||||
}
|
}
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
@ -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()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user