fix: plug memory map leak, save sp_el0, dynamic UART, kill loop
- Bootloader: reallocate memory map buffer when ExitBootServices fails, so GetMemoryMap doesn't scribble past the old allocation on retry. - vectors.S: actually store sp_el0 into the exception frame. Previously it was read into x24 and then… vanished. EL0 tasks would wake up with a corrupted stack pointer. Not great. - Serial: split hardcoded 0x09000000 into a fallback default; add SerialUpdate() so the DTB-parsed UART address actually gets used. - DTB: add bounds check on reserved[] with PMM's 3 extra slots accounted for, so malformed/overstuffed DTBs don't silently corrupt memory. - PMM.h: bump kVMMaxReservedRegions 128→256, define kPMMReservedRegionCount. - Types.h: remove `#define loop while(1)`. while(true) is fine. - Rename IOSerial* → Serial* — the IO prefix was redundant, Serial.c already lives under IO/.
This commit is contained in:
@@ -192,6 +192,7 @@ static efi_status_t populate_memory_map(Bootinfo* boot_info) {
|
||||
while (1) {
|
||||
status = gBS->GetMemoryMap(&map_size, map, &map_key, &descriptor_size, &descriptor_version);
|
||||
if (EFI_ERROR(status)) {
|
||||
gBS->FreePool(map);
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -206,7 +207,12 @@ static efi_status_t populate_memory_map(Bootinfo* boot_info) {
|
||||
return EFI_SUCCESS;
|
||||
}
|
||||
|
||||
gBS->FreePool(map);
|
||||
map_size += 2 * descriptor_size;
|
||||
status = gBS->AllocatePool(EfiLoaderData, map_size, (void**)&map);
|
||||
if (EFI_ERROR(status)) {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
#include <Types.h>
|
||||
|
||||
enum {
|
||||
kUARTBaseAddress = 0x09000000, // TODO: make it dynamic by parsing DTB
|
||||
kUARTBaseAddress = 0x09000000,
|
||||
};
|
||||
|
||||
Int32 IOSerialPutCharacter(ASCII character);
|
||||
Int32 IOSerialPutString(const ASCII* string);
|
||||
void SerialUpdate(UInt64 address);
|
||||
Int32 SerialPutCharacter(ASCII character);
|
||||
Int32 SerialPutString(const ASCII* string);
|
||||
|
||||
@@ -31,4 +31,3 @@ typedef UInt64 Size;
|
||||
typedef char ASCII;
|
||||
|
||||
typedef _Bool Boolean;
|
||||
#define loop while (1)
|
||||
@@ -4,7 +4,8 @@
|
||||
enum {
|
||||
kVMPageSize = 4096,
|
||||
kVMBlocksPerByte = 8,
|
||||
kVMMaxReservedRegions = 128,
|
||||
kVMMaxReservedRegions = 256,
|
||||
kPMMReservedRegionCount = 3,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -28,6 +28,9 @@ void DTBParse(Pointer dtb, VMBootMemoryMap* bootMap) {
|
||||
Boolean inReservedMemory = false;
|
||||
|
||||
while (true) {
|
||||
if (bootMap->reservedCount + kPMMReservedRegionCount >= kVMMaxReservedRegions) {
|
||||
OSPanic("Too many reserved memory regions!"); // should never occur but jic
|
||||
}
|
||||
UInt32 token = BytesSwap32(*(UInt32*)structs);
|
||||
structs += 4;
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ ExceptionsTrapEntry:
|
||||
|
||||
stp x30, x21, [sp, #16 * 15]
|
||||
stp x22, x23, [sp, #16 * 16]
|
||||
stp x24, xzr, [sp, #16 * 17]
|
||||
|
||||
mov x0, sp
|
||||
bl ExceptionsHandler
|
||||
|
||||
@@ -2,22 +2,28 @@
|
||||
#include <Arch/IO.h>
|
||||
#include <Arch/CPU.h>
|
||||
|
||||
Int32 IOSerialPutCharacter(ASCII character) {
|
||||
static UInt64 sUARTAddress = kUARTBaseAddress;
|
||||
|
||||
void SerialUpdate(UInt64 address) {
|
||||
sUARTAddress = address;
|
||||
}
|
||||
|
||||
Int32 SerialPutCharacter(ASCII character) {
|
||||
// TXFF -- TRansmit FIFO Full for PL011 is 5 bit of FR reg (0x18)
|
||||
UInt64 uartFR = kUARTBaseAddress + 0x18;
|
||||
UInt64 uartFR = sUARTAddress + 0x18;
|
||||
|
||||
while ((IOAddressRead32(uartFR) & (1 << 5)) != 0) {
|
||||
CPUYield();
|
||||
}
|
||||
|
||||
IOAddressWrite32(kUARTBaseAddress, character);
|
||||
IOAddressWrite32(sUARTAddress, character);
|
||||
return character;
|
||||
}
|
||||
|
||||
Int32 IOSerialPutString(const ASCII* string) {
|
||||
Int32 SerialPutString(const ASCII* string) {
|
||||
Int i = 0;
|
||||
while (string[i] != '\0') {
|
||||
IOSerialPutCharacter(string[i]);
|
||||
SerialPutCharacter(string[i]);
|
||||
i++;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
#include <Arch/Timer.h>
|
||||
#include <Arch/CPU.h>
|
||||
#include <Arch/GIC.h>
|
||||
#include <IO/Serial.h>
|
||||
#include <VM/PMM.h>
|
||||
#include <VM/VMM.h>
|
||||
#include <VM/Heap.h>
|
||||
@@ -20,6 +21,7 @@ void KernelMain(Bootinfo* bootinfo) {
|
||||
|
||||
bootMap.reservedCount = 0;
|
||||
DTBParse(bootinfo->dtb, &bootMap);
|
||||
SerialUpdate(bootMap.UART.base);
|
||||
|
||||
PMMInitialize(&bootMap);
|
||||
VMMInitialize(&bootMap, bootinfo);
|
||||
|
||||
@@ -11,5 +11,5 @@ void OSLog(const ASCII* format, ...) {
|
||||
StringFormatVariadic(buffer, kOSLogBufferSize, format, args);
|
||||
va_end(args);
|
||||
|
||||
IOSerialPutString(buffer);
|
||||
SerialPutString(buffer);
|
||||
}
|
||||
@@ -40,7 +40,7 @@ static const ASCII* sFunMessages[] = {
|
||||
};
|
||||
|
||||
__attribute__((noreturn)) static void Halt() {
|
||||
loop {
|
||||
while (true) {
|
||||
CPUDisableInterrupts();
|
||||
CPUWaitForInterrupt();
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ Address SchedulerNext(Address stackPointer) {
|
||||
if (gOSSchedulerCurrentTask->sleepTicks > 0) gOSSchedulerCurrentTask->sleepTicks--;
|
||||
|
||||
OSTask* nextTask = gOSSchedulerCurrentTask->next;
|
||||
loop {
|
||||
while (true) {
|
||||
if (nextTask->state == OSTaskStateDead) {
|
||||
nextTask = nextTask->next;
|
||||
if (nextTask == gOSSchedulerCurrentTask) OSPanic("No running tasks");
|
||||
|
||||
Reference in New Issue
Block a user