Add dynamic heap size allocation

This commit is contained in:
2025-12-04 20:59:26 +01:00
parent 8761d6867c
commit f6b4039348
2 changed files with 170 additions and 38 deletions

View File

@@ -244,15 +244,119 @@ long strtol(const char *str, char **endptr, int base) {
return result * sign;
}
#define HEAP_SIZE (8 * 1024 * 1024)
static unsigned char heap[HEAP_SIZE];
// Dynamic heap - will be initialized based on available RAM
static unsigned char *heap = NULL;
static size_t heap_size = 0;
static size_t heap_pos = 0;
// Forward declare EFI types we need
typedef uint64_t EFI_STATUS;
typedef void* EFI_HANDLE;
typedef uint64_t UINT64;
typedef uint32_t UINT32;
typedef uintptr_t UINTN;
typedef struct {
UINT32 Type;
UINT64 PhysicalStart;
UINT64 VirtualStart;
UINT64 NumberOfPages;
UINT64 Attribute;
} EFI_MEMORY_DESCRIPTOR;
typedef struct EFI_BOOT_SERVICES_PARTIAL {
// EFI_TABLE_HEADER (24 bytes) + 5 pointers (RaiseTPL, RestoreTPL, AllocatePages, FreePages, GetMemoryMap)
char padding[64]; // 24 + 5*8 = 64 bytes to reach AllocatePool
EFI_STATUS (*AllocatePool)(UINT32 PoolType, UINTN Size, void **Buffer);
} EFI_BOOT_SERVICES_PARTIAL;
typedef struct {
char hdr[24]; // EFI_TABLE_HEADER
void *firmwareVendor;
UINT32 firmwareRevision;
void *consoleInHandle;
void *conIn;
void *consoleOutHandle;
void *ConOut;
void *standardErrorHandle;
void *stdErr;
void *runtimeServices;
EFI_BOOT_SERVICES_PARTIAL *BootServices;
} EFI_SYSTEM_TABLE_PARTIAL;
#define EfiConventionalMemory 7
// Initialize heap with maximum available memory
void init_heap(void *system_table) {
// Static fallback heap in case EFI allocation fails
static unsigned char static_heap[64 * 1024 * 1024]; // 64 MB fallback
EFI_SYSTEM_TABLE_PARTIAL *st = (EFI_SYSTEM_TABLE_PARTIAL*)system_table;
// Safety check
if (!st || !st->BootServices || !st->BootServices->AllocatePool) {
printf("WARNING: EFI Boot Services not available, using static heap\n");
heap = static_heap;
heap_size = sizeof(static_heap);
heap_pos = 0;
printf("Heap initialized: %zu MB (static fallback)\n", heap_size / (1024 * 1024));
return;
}
// Try to allocate a very large heap - start with 16 GB and work down if needed
size_t sizes[] = {
16ULL * 1024 * 1024 * 1024, // 16 GB
8ULL * 1024 * 1024 * 1024, // 8 GB
4ULL * 1024 * 1024 * 1024, // 4 GB
2ULL * 1024 * 1024 * 1024, // 2 GB
1ULL * 1024 * 1024 * 1024, // 1 GB
512ULL * 1024 * 1024, // 512 MB
256ULL * 1024 * 1024, // 256 MB
128ULL * 1024 * 1024, // 128 MB
64ULL * 1024 * 1024, // 64 MB
32ULL * 1024 * 1024, // 32 MB
16ULL * 1024 * 1024, // 16 MB
8ULL * 1024 * 1024 // 8 MB (fallback)
};
for (int i = 0; i < 12; i++) {
EFI_STATUS status = st->BootServices->AllocatePool(
EfiConventionalMemory,
sizes[i],
(void**)&heap
);
if (status == 0) { // EFI_SUCCESS
heap_size = sizes[i];
heap_pos = 0;
if (heap_size >= 1024ULL * 1024 * 1024) {
printf("Heap initialized: %zu GB (%zu bytes)\n",
heap_size / (1024ULL * 1024 * 1024), heap_size);
} else {
printf("Heap initialized: %zu MB (%zu bytes)\n",
heap_size / (1024 * 1024), heap_size);
}
return;
}
}
// If all EFI allocations failed, use static heap
printf("WARNING: EFI allocation failed, using static heap\n");
heap = static_heap;
heap_size = sizeof(static_heap);
heap_pos = 0;
printf("Heap initialized: %zu MB (static fallback)\n", heap_size / (1024 * 1024));
}
void *malloc(size_t size) {
if (!heap) {
printf("malloc failed: heap not initialized\n");
return (void*)0;
}
size = (size + 7) & ~7;
size_t total = size + 8;
if (heap_pos + total > HEAP_SIZE) {
printf("malloc failed: OOM\n");
if (heap_pos + total > heap_size) {
printf("malloc failed: OOM (requested %zu, available %zu)\n", total, heap_size - heap_pos);
return (void*)0;
}
*(size_t*)&heap[heap_pos] = size;

View File

@@ -1,15 +1,18 @@
#include <stdint.h>
#include "efi.h"
#include "quickjs.h"
#include "stdio.h"
#include "system_prog.h"
#include "util.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdarg.h>
#include "stdio.h"
#include "quickjs.h"
#include "efi.h"
#include "util.h"
#include "system_prog.h"
#include <stdint.h>
static EFI_SYSTEM_TABLE *gST = NULL;
// Declare heap initialization function from minilibc.c
extern void init_heap(void *system_table);
void print(uint16_t *str) {
if (gST && gST->ConOut)
gST->ConOut->OutputString(gST->ConOut, str);
@@ -29,7 +32,8 @@ int printf(const char *format, ...) {
}
int fprintf(FILE *stream, const char *format, ...) {
if (stream != stdout && stream != stderr) return 0;
if (stream != stdout && stream != stderr)
return 0;
char buf[1024];
va_list ap;
@@ -44,7 +48,8 @@ int fprintf(FILE *stream, const char *format, ...) {
}
size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
if (stream != stdout && stream != stderr) return 0;
if (stream != stdout && stream != stderr)
return 0;
const char *p = ptr;
size_t total = size * nmemb;
@@ -53,7 +58,8 @@ size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
while (i < total) {
size_t chunk = total - i;
if (chunk > 1024) chunk = 1024;
if (chunk > 1024)
chunk = 1024;
memcpy(buf, p + i, chunk);
buf[chunk] = 0;
@@ -66,7 +72,8 @@ size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream) {
}
int fputc(int c, FILE *stream) {
if (stream != stdout && stream != stderr) return c;
if (stream != stdout && stream != stderr)
return c;
char buf[2] = {(char)c, 0};
print(AsciiToUnicode(buf));
@@ -74,16 +81,18 @@ int fputc(int c, FILE *stream) {
return c;
}
int putchar(int c) {
return fputc(c, stdout);
}
int putchar(int c) { return fputc(c, stdout); }
// ------------------------------- Kernel C TS bindings -------------------------------
JSValue jsKCPrintln(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst *argv) {
if (argc < 1) return JS_ThrowSyntaxError(ctx, "Missing argument");
// ------------------------------- Kernel C TS bindings
// -------------------------------
JSValue jsKCPrintln(JSContext *ctx, JSValueConst jsThis, int argc,
JSValueConst *argv) {
if (argc < 1)
return JS_ThrowSyntaxError(ctx, "Missing argument");
const char *str = JS_ToCString(ctx, argv[0]);
if (!str) return JS_EXCEPTION;
if (!str)
return JS_EXCEPTION;
print(AsciiToUnicode(str));
print(L"\r\n");
@@ -93,25 +102,32 @@ JSValue jsKCPrintln(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst
return JS_UNDEFINED;
}
JSValue jsKCClearScreen(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst *argv) {
JSValue jsKCClearScreen(JSContext *ctx, JSValueConst jsThis, int argc,
JSValueConst *argv) {
gST->ConOut->ClearScreen(gST->ConOut);
return JS_UNDEFINED;
}
JSValue jsKCPCIReadDword(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst *argv) {
if (argc < 1) return JS_ThrowSyntaxError(ctx, "Missing argument");
JSValue jsKCPCIReadDword(JSContext *ctx, JSValueConst jsThis, int argc,
JSValueConst *argv) {
if (argc < 1)
return JS_ThrowSyntaxError(ctx, "Missing argument");
uint32_t addr_u32;
JS_ToUint32(ctx, &addr_u32, argv[0]);
UINT64 addr = (UINT64)addr_u32; // Ensure type matches EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_RW's Address parameter
UINT64 addr = (UINT64)
addr_u32; // Ensure type matches EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_RW's
// Address parameter
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *pci;
EFI_GUID pciGuid = EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GUID;
EFI_STATUS status = gST->BootServices->LocateProtocol(&pciGuid, NULL, (void**)&pci);
EFI_STATUS status =
gST->BootServices->LocateProtocol(&pciGuid, NULL, (void **)&pci);
if (EFI_ERROR(status)) {
return JS_ThrowInternalError(ctx, "Failed to locate PCI Root Bridge IO Protocol: %d", status);
return JS_ThrowInternalError(
ctx, "Failed to locate PCI Root Bridge IO Protocol: %d", status);
}
UINT32 data = 0;
@@ -134,7 +150,8 @@ void initKC(JSContext *ctx) {
JS_FreeValue(ctx, global);
}
// ------------------------------------- EFI main -------------------------------------
// ------------------------------------- EFI main
// -------------------------------------
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
(void)ImageHandle;
@@ -143,6 +160,9 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
print(L"Booting LintsOS...\r\n");
// Initialize heap with maximum available memory
init_heap(SystemTable);
JSRuntime *rt = JS_NewRuntime();
if (!rt) {
print(L"!!! Kernel panic: Failed to create runtime !!!\r\n");
@@ -159,16 +179,21 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
initKC(ctx);
JSValue val;
JSValue eval_result = JS_Eval(ctx, SYSTEM_PROG_JS, strlen(SYSTEM_PROG_JS), "<input>", JS_EVAL_TYPE_GLOBAL);
if (JS_IsException(eval_result)) val = eval_result;
JSValue eval_result = JS_Eval(ctx, SYSTEM_PROG_JS, strlen(SYSTEM_PROG_JS),
"<input>", JS_EVAL_TYPE_GLOBAL);
if (JS_IsException(eval_result))
val = eval_result;
else {
JS_FreeValue(ctx, eval_result);
JSValue global_obj = JS_GetGlobalObject(ctx);
JSValue kentry_func = JS_GetPropertyStr(ctx, global_obj, "KEntry");
if (JS_IsFunction(ctx, kentry_func)) val = JS_Call(ctx, kentry_func, JS_UNDEFINED, 0, NULL);
else val = JS_ThrowReferenceError(ctx, "KEntry function not found or not callable");
if (JS_IsFunction(ctx, kentry_func))
val = JS_Call(ctx, kentry_func, JS_UNDEFINED, 0, NULL);
else
val = JS_ThrowReferenceError(ctx,
"KEntry function not found or not callable");
JS_FreeValue(ctx, kentry_func);
JS_FreeValue(ctx, global_obj);
@@ -181,7 +206,8 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
if (str) {
printf("!!! Kernel panic: %s !!!\n", str);
JS_FreeCString(ctx, str);
} else printf("!!! Kernel panic: [unknown] !!!\n");
} else
printf("!!! Kernel panic: [unknown] !!!\n");
JS_FreeValue(ctx, ex);
} else {
@@ -189,7 +215,8 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
if (str) {
printf("!!! Kernel panic: %s !!!\n", str);
JS_FreeCString(ctx, str);
} else printf("!!! Kernel panic: [unknown] !!!\n");
} else
printf("!!! Kernel panic: [unknown] !!!\n");
JS_FreeValue(ctx, val);
}
@@ -197,7 +224,8 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
JS_FreeContext(ctx);
JS_FreeRuntime(rt);
for(;;);
for (;;)
;
return EFI_SUCCESS;
}