diff --git a/src/core/compat/minilibc.c b/src/core/compat/minilibc.c index e78e1dd..87eb680 100644 --- a/src/core/compat/minilibc.c +++ b/src/core/compat/minilibc.c @@ -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; diff --git a/src/core/main.c b/src/core/main.c index c8e837e..7e40ed1 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1,15 +1,18 @@ -#include +#include "efi.h" +#include "quickjs.h" +#include "stdio.h" +#include "system_prog.h" +#include "util.h" +#include #include #include -#include -#include "stdio.h" -#include "quickjs.h" -#include "efi.h" -#include "util.h" -#include "system_prog.h" +#include 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,24 +72,27 @@ 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; - char buf[2] = { (char)c, 0 }; + if (stream != stdout && stream != stderr) + return c; + char buf[2] = {(char)c, 0}; print(AsciiToUnicode(buf)); 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_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), "", 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), + "", 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; }