Add dynamic heap size allocation
This commit is contained in:
@@ -244,15 +244,119 @@ long strtol(const char *str, char **endptr, int base) {
|
|||||||
return result * sign;
|
return result * sign;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define HEAP_SIZE (8 * 1024 * 1024)
|
// Dynamic heap - will be initialized based on available RAM
|
||||||
static unsigned char heap[HEAP_SIZE];
|
static unsigned char *heap = NULL;
|
||||||
|
static size_t heap_size = 0;
|
||||||
static size_t heap_pos = 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) {
|
void *malloc(size_t size) {
|
||||||
|
if (!heap) {
|
||||||
|
printf("malloc failed: heap not initialized\n");
|
||||||
|
return (void*)0;
|
||||||
|
}
|
||||||
size = (size + 7) & ~7;
|
size = (size + 7) & ~7;
|
||||||
size_t total = size + 8;
|
size_t total = size + 8;
|
||||||
if (heap_pos + total > HEAP_SIZE) {
|
if (heap_pos + total > heap_size) {
|
||||||
printf("malloc failed: OOM\n");
|
printf("malloc failed: OOM (requested %zu, available %zu)\n", total, heap_size - heap_pos);
|
||||||
return (void*)0;
|
return (void*)0;
|
||||||
}
|
}
|
||||||
*(size_t*)&heap[heap_pos] = size;
|
*(size_t*)&heap[heap_pos] = size;
|
||||||
|
|||||||
@@ -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 <stdbool.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdarg.h>
|
#include <stdint.h>
|
||||||
#include "stdio.h"
|
|
||||||
#include "quickjs.h"
|
|
||||||
#include "efi.h"
|
|
||||||
#include "util.h"
|
|
||||||
#include "system_prog.h"
|
|
||||||
|
|
||||||
static EFI_SYSTEM_TABLE *gST = NULL;
|
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) {
|
void print(uint16_t *str) {
|
||||||
if (gST && gST->ConOut)
|
if (gST && gST->ConOut)
|
||||||
gST->ConOut->OutputString(gST->ConOut, str);
|
gST->ConOut->OutputString(gST->ConOut, str);
|
||||||
@@ -29,7 +32,8 @@ int printf(const char *format, ...) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int fprintf(FILE *stream, 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];
|
char buf[1024];
|
||||||
va_list ap;
|
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) {
|
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;
|
const char *p = ptr;
|
||||||
size_t total = size * nmemb;
|
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) {
|
while (i < total) {
|
||||||
size_t chunk = total - i;
|
size_t chunk = total - i;
|
||||||
if (chunk > 1024) chunk = 1024;
|
if (chunk > 1024)
|
||||||
|
chunk = 1024;
|
||||||
|
|
||||||
memcpy(buf, p + i, chunk);
|
memcpy(buf, p + i, chunk);
|
||||||
buf[chunk] = 0;
|
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) {
|
int fputc(int c, FILE *stream) {
|
||||||
if (stream != stdout && stream != stderr) return c;
|
if (stream != stdout && stream != stderr)
|
||||||
char buf[2] = { (char)c, 0 };
|
return c;
|
||||||
|
char buf[2] = {(char)c, 0};
|
||||||
|
|
||||||
print(AsciiToUnicode(buf));
|
print(AsciiToUnicode(buf));
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
int putchar(int c) {
|
int putchar(int c) { return fputc(c, stdout); }
|
||||||
return fputc(c, stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------------------------- Kernel C TS bindings -------------------------------
|
// ------------------------------- Kernel C TS bindings
|
||||||
JSValue jsKCPrintln(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst *argv) {
|
// -------------------------------
|
||||||
if (argc < 1) return JS_ThrowSyntaxError(ctx, "Missing argument");
|
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]);
|
const char *str = JS_ToCString(ctx, argv[0]);
|
||||||
if (!str) return JS_EXCEPTION;
|
if (!str)
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
|
||||||
print(AsciiToUnicode(str));
|
print(AsciiToUnicode(str));
|
||||||
print(L"\r\n");
|
print(L"\r\n");
|
||||||
@@ -93,25 +102,32 @@ JSValue jsKCPrintln(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst
|
|||||||
return JS_UNDEFINED;
|
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);
|
gST->ConOut->ClearScreen(gST->ConOut);
|
||||||
|
|
||||||
return JS_UNDEFINED;
|
return JS_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
JSValue jsKCPCIReadDword(JSContext *ctx, JSValueConst jsThis, int argc, JSValueConst *argv) {
|
JSValue jsKCPCIReadDword(JSContext *ctx, JSValueConst jsThis, int argc,
|
||||||
if (argc < 1) return JS_ThrowSyntaxError(ctx, "Missing argument");
|
JSValueConst *argv) {
|
||||||
|
if (argc < 1)
|
||||||
|
return JS_ThrowSyntaxError(ctx, "Missing argument");
|
||||||
|
|
||||||
uint32_t addr_u32;
|
uint32_t addr_u32;
|
||||||
JS_ToUint32(ctx, &addr_u32, argv[0]);
|
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_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)) {
|
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;
|
UINT32 data = 0;
|
||||||
@@ -134,7 +150,8 @@ void initKC(JSContext *ctx) {
|
|||||||
JS_FreeValue(ctx, global);
|
JS_FreeValue(ctx, global);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------- EFI main -------------------------------------
|
// ------------------------------------- EFI main
|
||||||
|
// -------------------------------------
|
||||||
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
|
EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
|
||||||
(void)ImageHandle;
|
(void)ImageHandle;
|
||||||
|
|
||||||
@@ -143,6 +160,9 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
|
|||||||
|
|
||||||
print(L"Booting LintsOS...\r\n");
|
print(L"Booting LintsOS...\r\n");
|
||||||
|
|
||||||
|
// Initialize heap with maximum available memory
|
||||||
|
init_heap(SystemTable);
|
||||||
|
|
||||||
JSRuntime *rt = JS_NewRuntime();
|
JSRuntime *rt = JS_NewRuntime();
|
||||||
if (!rt) {
|
if (!rt) {
|
||||||
print(L"!!! Kernel panic: Failed to create runtime !!!\r\n");
|
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);
|
initKC(ctx);
|
||||||
|
|
||||||
JSValue val;
|
JSValue val;
|
||||||
JSValue eval_result = JS_Eval(ctx, SYSTEM_PROG_JS, strlen(SYSTEM_PROG_JS), "<input>", JS_EVAL_TYPE_GLOBAL);
|
JSValue eval_result = JS_Eval(ctx, SYSTEM_PROG_JS, strlen(SYSTEM_PROG_JS),
|
||||||
if (JS_IsException(eval_result)) val = eval_result;
|
"<input>", JS_EVAL_TYPE_GLOBAL);
|
||||||
|
if (JS_IsException(eval_result))
|
||||||
|
val = eval_result;
|
||||||
else {
|
else {
|
||||||
JS_FreeValue(ctx, eval_result);
|
JS_FreeValue(ctx, eval_result);
|
||||||
|
|
||||||
JSValue global_obj = JS_GetGlobalObject(ctx);
|
JSValue global_obj = JS_GetGlobalObject(ctx);
|
||||||
JSValue kentry_func = JS_GetPropertyStr(ctx, global_obj, "KEntry");
|
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);
|
if (JS_IsFunction(ctx, kentry_func))
|
||||||
else val = JS_ThrowReferenceError(ctx, "KEntry function not found or not callable");
|
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, kentry_func);
|
||||||
JS_FreeValue(ctx, global_obj);
|
JS_FreeValue(ctx, global_obj);
|
||||||
@@ -181,7 +206,8 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
|
|||||||
if (str) {
|
if (str) {
|
||||||
printf("!!! Kernel panic: %s !!!\n", str);
|
printf("!!! Kernel panic: %s !!!\n", str);
|
||||||
JS_FreeCString(ctx, str);
|
JS_FreeCString(ctx, str);
|
||||||
} else printf("!!! Kernel panic: [unknown] !!!\n");
|
} else
|
||||||
|
printf("!!! Kernel panic: [unknown] !!!\n");
|
||||||
|
|
||||||
JS_FreeValue(ctx, ex);
|
JS_FreeValue(ctx, ex);
|
||||||
} else {
|
} else {
|
||||||
@@ -189,7 +215,8 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
|
|||||||
if (str) {
|
if (str) {
|
||||||
printf("!!! Kernel panic: %s !!!\n", str);
|
printf("!!! Kernel panic: %s !!!\n", str);
|
||||||
JS_FreeCString(ctx, str);
|
JS_FreeCString(ctx, str);
|
||||||
} else printf("!!! Kernel panic: [unknown] !!!\n");
|
} else
|
||||||
|
printf("!!! Kernel panic: [unknown] !!!\n");
|
||||||
|
|
||||||
JS_FreeValue(ctx, val);
|
JS_FreeValue(ctx, val);
|
||||||
}
|
}
|
||||||
@@ -197,7 +224,8 @@ EFI_STATUS efi_main(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable) {
|
|||||||
JS_FreeContext(ctx);
|
JS_FreeContext(ctx);
|
||||||
JS_FreeRuntime(rt);
|
JS_FreeRuntime(rt);
|
||||||
|
|
||||||
for(;;);
|
for (;;)
|
||||||
|
;
|
||||||
|
|
||||||
return EFI_SUCCESS;
|
return EFI_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user