feat: pmm
This commit is contained in:
+1
-1
@@ -12,7 +12,7 @@ add_subdirectory(kernel)
|
|||||||
find_program(MCOPY_EXE mcopy)
|
find_program(MCOPY_EXE mcopy)
|
||||||
find_program(MKFS_EXE mkfs.fat)
|
find_program(MKFS_EXE mkfs.fat)
|
||||||
find_program(QEMU_EXE qemu-system-x86_64)
|
find_program(QEMU_EXE qemu-system-x86_64)
|
||||||
set(OVMF_PATH "/usr/share/qemu/ovmf-x86_64.bin" CACHE FILEPATH "Path to OVMF bios")
|
set(OVMF_PATH "/usr/share/edk2/ovmf/OVMF_CODE.fd" CACHE FILEPATH "Path to OVMF bios")
|
||||||
|
|
||||||
if(MCOPY_EXE AND MKFS_EXE)
|
if(MCOPY_EXE AND MKFS_EXE)
|
||||||
set(IMG_FILE "${CMAKE_BINARY_DIR}/termOS.img")
|
set(IMG_FILE "${CMAKE_BINARY_DIR}/termOS.img")
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ int main()
|
|||||||
uint64_t kernel_size = file_info->FileSize;
|
uint64_t kernel_size = file_info->FileSize;
|
||||||
uintn_t kernel_size_read = (uintn_t)kernel_size;
|
uintn_t kernel_size_read = (uintn_t)kernel_size;
|
||||||
efi_physical_address_t kernel_addr = 0x100000;
|
efi_physical_address_t kernel_addr = 0x100000;
|
||||||
uintn_t pages = (kernel_size + 0xFFF) / 0x1000;
|
uintn_t pages = (kernel_size + 0xFFF) / 0x1000 + 32;
|
||||||
|
|
||||||
status = gBS->AllocatePages(AllocateAddress, EfiLoaderData, pages, &kernel_addr);
|
status = gBS->AllocatePages(AllocateAddress, EfiLoaderData, pages, &kernel_addr);
|
||||||
if (EFI_ERROR(status)) {
|
if (EFI_ERROR(status)) {
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ add_executable(kernel
|
|||||||
src/modules/gdt.c
|
src/modules/gdt.c
|
||||||
src/modules/idt.c
|
src/modules/idt.c
|
||||||
src/modules/interrupts.c
|
src/modules/interrupts.c
|
||||||
|
src/modules/pmm.c
|
||||||
src/modules/memory.c
|
src/modules/memory.c
|
||||||
src/modules/serial.c
|
src/modules/serial.c
|
||||||
src/modules/console.c
|
src/modules/console.c
|
||||||
|
|||||||
@@ -1,9 +1,16 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
|
#define MAX(a, b) ({ \
|
||||||
|
auto _a = (a); \
|
||||||
|
auto _b = (b); \
|
||||||
|
_a > _b ? _a : _b; \
|
||||||
|
})
|
||||||
|
|
||||||
static inline int abs(int n) {
|
static inline int abs(int n) {
|
||||||
return (n < 0) ? -n : n;
|
return (n < 0) ? -n : n;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline i64 i64abs(i64 n) {
|
static inline i64 i64abs(i64 n) {
|
||||||
return (n < 0) ? -n : n;
|
return (n < 0) ? -n : n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
#define PANIC_H
|
#define PANIC_H
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
__attribute__((noreturn)) void panic(Registers *regs);
|
__attribute__((noreturn)) void panic_exception(Registers *regs);
|
||||||
|
__attribute__((noreturn)) void panic(const char* msg);
|
||||||
|
|
||||||
extern const char* exception_messages[];
|
extern const char* exception_messages[];
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
#ifndef PMM_H
|
||||||
|
#define PMM_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
#include "../common/bootinfo.h"
|
||||||
|
|
||||||
|
#define PAGE_SIZE 4096
|
||||||
|
#define BLOCKS_PER_BYTE 8
|
||||||
|
|
||||||
|
#define BITMAP_BYTE_INDEX(addr) ((addr / PAGE_SIZE) / BLOCKS_PER_BYTE)
|
||||||
|
#define BITMAP_BIT_OFFSET(addr) ((addr / PAGE_SIZE) % BLOCKS_PER_BYTE)
|
||||||
|
#define BITMAP_TEST(bitmap, addr) (bitmap[BITMAP_BYTE_INDEX(addr)] & (1 << BITMAP_BIT_OFFSET(addr)))
|
||||||
|
#define BITMAP_SET(bitmap, addr) (bitmap[BITMAP_BYTE_INDEX(addr)] |= (1 << BITMAP_BIT_OFFSET(addr)))
|
||||||
|
#define BITMAP_UNSET(bitmap, addr) (bitmap[BITMAP_BYTE_INDEX(addr)] &= ~(1 << BITMAP_BIT_OFFSET(addr)))
|
||||||
|
|
||||||
|
void pmm_init(BI_MemoryMap mmap);
|
||||||
|
u8* get_bitmap();
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -20,4 +20,32 @@ typedef struct {
|
|||||||
u64 rip, cs, rflags, rsp, ss; // Pushed by CPU
|
u64 rip, cs, rflags, rsp, ss; // Pushed by CPU
|
||||||
} Registers;
|
} Registers;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 type;
|
||||||
|
u32 pad;
|
||||||
|
u64 physical_start;
|
||||||
|
u64 virtual_start;
|
||||||
|
u64 number_of_pages;
|
||||||
|
u64 attribute;
|
||||||
|
} __attribute__((packed)) efi_memory_descriptor_k;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
EfiReservedMemoryType,
|
||||||
|
EfiLoaderCode,
|
||||||
|
EfiLoaderData,
|
||||||
|
EfiBootServicesCode,
|
||||||
|
EfiBootServicesData,
|
||||||
|
EfiRuntimeServicesCode,
|
||||||
|
EfiRuntimeServicesData,
|
||||||
|
EfiConventionalMemory,
|
||||||
|
EfiUnusableMemory,
|
||||||
|
EfiACPIReclaimMemory,
|
||||||
|
EfiACPIMemoryNVS,
|
||||||
|
EfiMemoryMappedIO,
|
||||||
|
EfiMemoryMappedIOPortSpace,
|
||||||
|
EfiPalCode,
|
||||||
|
EfiPersistentMemory,
|
||||||
|
EfiMaxMemoryType
|
||||||
|
} EFI_MEMORY_TYPE;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -3,6 +3,7 @@ ENTRY(_start)
|
|||||||
SECTIONS
|
SECTIONS
|
||||||
{
|
{
|
||||||
. = 0x100000;
|
. = 0x100000;
|
||||||
|
_kernel_start = .;
|
||||||
|
|
||||||
.text : {
|
.text : {
|
||||||
*(.text.entry)
|
*(.text.entry)
|
||||||
@@ -26,6 +27,9 @@ SECTIONS
|
|||||||
*(.stack)
|
*(.stack)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
. = ALIGN(4096);
|
||||||
|
_kernel_end = .;
|
||||||
|
|
||||||
/DISCARD/ : {
|
/DISCARD/ : {
|
||||||
*(.note*)
|
*(.note*)
|
||||||
*(.comment*)
|
*(.comment*)
|
||||||
|
|||||||
+14
-4
@@ -1,20 +1,25 @@
|
|||||||
#include "../../common/bootinfo.h"
|
#include "../../common/bootinfo.h"
|
||||||
#include "console.h"
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
#include "shitgui.h"
|
#include "shitgui.h"
|
||||||
#include "serial.h"
|
#include "serial.h"
|
||||||
|
#include "console.h"
|
||||||
#include "panic.h" // IWYU pragma: keep
|
#include "panic.h" // IWYU pragma: keep
|
||||||
#include "../data/logo.h"
|
|
||||||
|
|
||||||
#include "gdt.h"
|
#include "gdt.h"
|
||||||
#include "idt.h"
|
#include "idt.h"
|
||||||
|
#include "pmm.h"
|
||||||
|
|
||||||
|
#include "../data/logo.h"
|
||||||
|
|
||||||
|
|
||||||
int rectest(int a) {
|
int rectest(int a) {
|
||||||
volatile int b = a + 1;
|
volatile int b = a + 1;
|
||||||
return rectest(b * 2);
|
return rectest(b * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern u64 _kernel_end;
|
||||||
|
|
||||||
void kmain(Bootinfo* info) {
|
void kmain(Bootinfo* info) {
|
||||||
u32 *fb = (u32*)info->framebuffer.base;
|
u32 *fb = (u32*)info->framebuffer.base;
|
||||||
if (!fb) return;
|
if (!fb) return;
|
||||||
@@ -42,8 +47,13 @@ void kmain(Bootinfo* info) {
|
|||||||
kprintf("Welcome to ^ptermOS^0!!!\n");
|
kprintf("Welcome to ^ptermOS^0!!!\n");
|
||||||
SG_Point text_normal_point = {0, 120}; // not nice to hardcode nums like that but we have what we have
|
SG_Point text_normal_point = {0, 120}; // not nice to hardcode nums like that but we have what we have
|
||||||
console_set_cursor_pos(&text_normal_point);
|
console_set_cursor_pos(&text_normal_point);
|
||||||
|
|
||||||
|
pmm_init(info->mem);
|
||||||
|
|
||||||
kprintf("MemoryMap located at ^g%x^0; \nMemory map size is ^g%x^0\n", (u64)info->mem.map, (u64)info->mem.map_size);
|
kprintf("MemoryMap located at ^g%x^0 (^r%X^0); \
|
||||||
|
\nMemory map size is ^g%x^0\
|
||||||
|
\nKernel ends at ^g%x^0\
|
||||||
|
\nBITMAP located at ^g%x^0", (u64)info->mem.map, (u64)info->mem.map,(u64)info->mem.map_size, &_kernel_end, get_bitmap());
|
||||||
|
|
||||||
// kfetch();
|
// kfetch();
|
||||||
|
|
||||||
@@ -52,7 +62,7 @@ void kmain(Bootinfo* info) {
|
|||||||
|
|
||||||
// rectest(0);
|
// rectest(0);
|
||||||
|
|
||||||
// __asm__("ud2"); // panic :(
|
// __asm__("ud2"); // panic :(
|
||||||
|
|
||||||
while (1) { __asm__("hlt"); }
|
while (1) { __asm__("hlt"); }
|
||||||
}
|
}
|
||||||
@@ -7,8 +7,13 @@
|
|||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
|
||||||
#define COLOR_RED 0xFF5555
|
#define COLOR_RED 0xFF5555
|
||||||
|
#define COLOR_VERYRED 0xFF0000
|
||||||
#define COLOR_GREEN 0x08bf39
|
#define COLOR_GREEN 0x08bf39
|
||||||
|
#define COLOR_VERYGREEN 0x00FF00
|
||||||
|
#define COLOR_TURQUOISE 0x5effaf
|
||||||
#define COLOR_BLUE 0x5555FF
|
#define COLOR_BLUE 0x5555FF
|
||||||
|
#define COLOR_VERYBLUE 0x0000FF
|
||||||
|
#define COLOR_LIGHTBLUE 0x3890e8
|
||||||
#define COLOR_YELLOW 0xFFFF55
|
#define COLOR_YELLOW 0xFFFF55
|
||||||
#define COLOR_CYAN 0x55FFFF
|
#define COLOR_CYAN 0x55FFFF
|
||||||
#define COLOR_MAGENTA 0xFF55FF
|
#define COLOR_MAGENTA 0xFF55FF
|
||||||
@@ -98,24 +103,29 @@ static void print_dec(const i64 n) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void print_hex(u64 u) {
|
static void print_hex(u64 u, u8 padding) {
|
||||||
console_putc('0');
|
console_putc('0');
|
||||||
console_putc('x');
|
console_putc('x');
|
||||||
|
|
||||||
if (u == 0) {
|
if (u == 0) {
|
||||||
console_putc('0');
|
console_putc('0');
|
||||||
|
for (i32 i = 1; i < padding; i++) console_putc('0');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
char buffer[16];
|
char buffer[16] = {0};
|
||||||
i32 i = 0;
|
i32 i = 0;
|
||||||
|
|
||||||
while (u > 0) {
|
do {
|
||||||
i32 digit = u % 16;
|
i32 digit = u % 16;
|
||||||
if (digit < 10) { buffer[i] = digit + '0'; }
|
if (digit < 10) buffer[i++] = digit + '0';
|
||||||
else { buffer[i] = digit - 10 + 'A'; }
|
else buffer[i++] = digit - 10 + 'A';
|
||||||
u /= 16;
|
u /= 16;
|
||||||
i++;
|
} while (u > 0);
|
||||||
|
|
||||||
|
while(i < padding) {
|
||||||
|
console_putc('0');
|
||||||
|
padding--;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (--i >= 0) {
|
while (--i >= 0) {
|
||||||
@@ -123,6 +133,7 @@ static void print_hex(u64 u) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void kprintf(const char *fmt, ...) {
|
void kprintf(const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
@@ -149,9 +160,14 @@ void kprintf(const char *fmt, ...) {
|
|||||||
}
|
}
|
||||||
case 'x': {
|
case 'x': {
|
||||||
u64 num = va_arg(args, u64);
|
u64 num = va_arg(args, u64);
|
||||||
print_hex(num);
|
print_hex(num, 0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case 'X' : {
|
||||||
|
u64 num = va_arg(args, u64);
|
||||||
|
print_hex(num, 16);
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
console_putc(fmt[i]);
|
console_putc(fmt[i]);
|
||||||
break;
|
break;
|
||||||
@@ -161,8 +177,13 @@ void kprintf(const char *fmt, ...) {
|
|||||||
i++;
|
i++;
|
||||||
switch (fmt[i]) {
|
switch (fmt[i]) {
|
||||||
case 'r': console_set_color(COLOR_RED); break;
|
case 'r': console_set_color(COLOR_RED); break;
|
||||||
|
case 'R': console_set_color(COLOR_VERYRED); break;
|
||||||
case 'g': console_set_color(COLOR_GREEN); break;
|
case 'g': console_set_color(COLOR_GREEN); break;
|
||||||
|
case 'G': console_set_color(COLOR_VERYGREEN); break;
|
||||||
|
case 't': console_set_color(COLOR_TURQUOISE); break;
|
||||||
case 'b': console_set_color(COLOR_BLUE); break;
|
case 'b': console_set_color(COLOR_BLUE); break;
|
||||||
|
case 'B': console_set_color(COLOR_VERYBLUE); break;
|
||||||
|
case 'l': console_set_color(COLOR_LIGHTBLUE); break;
|
||||||
case 'y': console_set_color(COLOR_YELLOW); break;
|
case 'y': console_set_color(COLOR_YELLOW); break;
|
||||||
case 'c': console_set_color(COLOR_CYAN); break;
|
case 'c': console_set_color(COLOR_CYAN); break;
|
||||||
case 'm': console_set_color(COLOR_MAGENTA); break;
|
case 'm': console_set_color(COLOR_MAGENTA); break;
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
void isr_handler_c(Registers *regs) {
|
void isr_handler_c(Registers *regs) {
|
||||||
panic(regs);
|
panic_exception(regs);
|
||||||
}
|
}
|
||||||
+47
-25
@@ -5,7 +5,6 @@
|
|||||||
#include "shitgui.h"
|
#include "shitgui.h"
|
||||||
|
|
||||||
const char* fun_messages[] = {
|
const char* fun_messages[] = {
|
||||||
"Ooops! All red!",
|
|
||||||
"Execution finished abnormally with code: 0x_x",
|
"Execution finished abnormally with code: 0x_x",
|
||||||
"It's definitely your fault.",
|
"It's definitely your fault.",
|
||||||
"No more Roblox!",
|
"No more Roblox!",
|
||||||
@@ -28,12 +27,12 @@ const char* fun_messages[] = {
|
|||||||
"Code have been eaten by Aliens",
|
"Code have been eaten by Aliens",
|
||||||
"That's all, folks!",
|
"That's all, folks!",
|
||||||
"Raiden, answer me, Raiden, respond! Raiden?! RAIDEEEEEEEEEN!",
|
"Raiden, answer me, Raiden, respond! Raiden?! RAIDEEEEEEEEEN!",
|
||||||
"Fatal error has been occurred. Your device will be terminated in 30 seconds.",
|
"Fatal error has been occurred.\n\t\t\t\t Your device will be terminated in 30 seconds.",
|
||||||
"I'll be back",
|
"I'll be back",
|
||||||
"Hastla la vista, baby",
|
"Hastla la vista, baby",
|
||||||
"Ti chego mne tut nagovoril...",
|
"Ti chego mne tut nagovoril...",
|
||||||
"Your access has been denied because of your region. Please, use Chultem VPN and try again later.",
|
"Your access has been denied because of your region.\n\t\t\t\tPlease, use Chultem VPN and try again later.",
|
||||||
"Fatal error has been occurred. Your device will be transformed into Niva in a few seconds.",
|
"Fatal error has been occurred. \n\t\t\t\tYour device will be transformed into Niva in a few seconds.",
|
||||||
"Have you tried turning it off and on again?",
|
"Have you tried turning it off and on again?",
|
||||||
"Put it in rice maybe?",
|
"Put it in rice maybe?",
|
||||||
"Just hit the monitor, it usually helps",
|
"Just hit the monitor, it usually helps",
|
||||||
@@ -82,8 +81,14 @@ const char* exception_messages[] = {
|
|||||||
"Reserved"
|
"Reserved"
|
||||||
};
|
};
|
||||||
|
|
||||||
__attribute__((noreturn)) void panic(Registers *regs) {
|
__attribute__((noreturn)) void die() {
|
||||||
console_clear(0xFF0000);
|
while (1) {
|
||||||
|
__asm__ volatile ("cli; hlt");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_panic_bg() {
|
||||||
|
console_clear(0x101010);
|
||||||
console_set_color(0xFFFFFF);
|
console_set_color(0xFFFFFF);
|
||||||
|
|
||||||
SG_Point p = console_get_dimensions();
|
SG_Point p = console_get_dimensions();
|
||||||
@@ -97,32 +102,49 @@ __attribute__((noreturn)) void panic(Registers *regs) {
|
|||||||
u8 rand_num = shitrand() % msg_count;
|
u8 rand_num = shitrand() % msg_count;
|
||||||
|
|
||||||
kprintf("\n\n");
|
kprintf("\n\n");
|
||||||
kprintf("\t\t\t\tKERNEL PANIC :( \n");
|
kprintf("\t\t\t\t^tKERNEL PANIC^w :( \n");
|
||||||
kprintf("\t\t--------------------------------\n");
|
kprintf("\t\t--------------------------------\n");
|
||||||
kprintf("\t\t\t\t%s\n", fun_messages[rand_num]);
|
kprintf("\t\t\t\t^r%s^w\n", fun_messages[rand_num]);
|
||||||
kprintf("\t\t--------------------------------\n");
|
kprintf("\t\t--------------------------------\n");
|
||||||
kprintf("\t\tCPU EXCEPTION: %s (%d)\n", exception_messages[regs->int_no], regs->int_no);
|
}
|
||||||
if (regs->err_code) kprintf("\t\tError Code: %x\n", regs->err_code);
|
|
||||||
kprintf("\t\tInstruction Pointer (RIP): %x\n", regs->rip);
|
__attribute__((noreturn)) void panic_exception(Registers *regs) {
|
||||||
kprintf("\t\tCode Segment (CS): %x\n", regs->cs);
|
draw_panic_bg();
|
||||||
kprintf("\t\tFlags (RFLAGS): %x\n", regs->rflags);
|
|
||||||
kprintf("\t\tStack Pointer (RSP): %x\n", regs->rsp);
|
kprintf("\t\t^yCPU EXCEPTION^w: ^m%s^w (%d)\n", exception_messages[regs->int_no], regs->int_no);
|
||||||
|
if (regs->err_code) kprintf("\t\t^yError Code^w: %X\n", regs->err_code);
|
||||||
|
kprintf("\t\t^yInstruction Pointer^w (^yRIP^w): %X\n", regs->rip);
|
||||||
|
kprintf("\t\t^yCode Segment^w (^yCS^w): %X\n", regs->cs);
|
||||||
|
kprintf("\t\t^yFlags^w (^yRFLAGS^w): %X\n", regs->rflags);
|
||||||
|
kprintf("\t\t^yStack Pointer^w (^yRSP^w): %X\n", regs->rsp);
|
||||||
if (regs->int_no == 14) {
|
if (regs->int_no == 14) {
|
||||||
u64 cr2;
|
u64 cr2;
|
||||||
__asm__ volatile("mov %%cr2, %0" : "=r"(cr2));
|
__asm__ volatile("mov %%cr2, %0" : "=r"(cr2));
|
||||||
kprintf("\t\tFaulting Address (CR2): %x\n", cr2);
|
kprintf("\t\t^yFaulting Address^w (^yCR2^w): %X\n", cr2);
|
||||||
}
|
}
|
||||||
kprintf("\t\t--------------------------------\n");
|
kprintf("\t\t--------------------------------\n");
|
||||||
kprintf("\t\t\t\tREGSISTERS\n");
|
kprintf("\t\t\t\t^yREGSISTERS^w\n");
|
||||||
kprintf("\t\t--------------------------------\n");
|
kprintf("\t\t--------------------------------\n");
|
||||||
kprintf("\t\tRAX=%x, RBX=%x, RCX=%x, RDX=%x\n", regs->rax, regs->rbx, regs->rcx, regs->rdx);
|
kprintf("\t\t^yRAX^w=%X, ^yRBX^w=%X\n", regs->rax, regs->rbx);
|
||||||
kprintf("\t\tRSI=%x, RDI=%x, RBP=%x, R8=%x\n", regs->rsi, regs->rdi, regs->rbp, regs->r8);
|
kprintf("\t\t^yRCX^w=%X, ^yRDX^w=%X\n", regs->rcx, regs->rdx);
|
||||||
kprintf("\t\tR9=%x, R10=%x, R11=%x, R12=%x\n", regs->r9, regs->r10, regs->r11, regs->r12);
|
kprintf("\t\t^yRSI^w=%X, ^yRDI^w=%X\n", regs->rsi, regs->rdi);
|
||||||
kprintf("\t\tR13=%x, R14=%x, R15=%x\n", regs->r13, regs->r14, regs->r15);
|
kprintf("\t\t^yRBP^w=%X, ^yR8^w =%X\n", regs->rbp, regs->r8);
|
||||||
|
kprintf("\t\t^yR9^w =%X, ^yR10^w=%X \n", regs->r9, regs->r10);
|
||||||
|
kprintf("\t\t^yR11^w=%X, ^yR12^w=%X\n", regs->r11, regs->r12);
|
||||||
|
kprintf("\t\t^yR13^w=%X, ^yR14^w=%X\n", regs->r13, regs->r14);
|
||||||
|
kprintf("\t\t^yR15^w=%X\n",regs->r15);
|
||||||
kprintf("\t\t--------------------------------\n");
|
kprintf("\t\t--------------------------------\n");
|
||||||
kprintf("\t\t\t\tSystem halted.\n");
|
kprintf("\t\t\t\t^tSystem halted.^w\n");
|
||||||
|
|
||||||
|
die();
|
||||||
|
}
|
||||||
|
|
||||||
while (1) {
|
__attribute__((noreturn)) void panic(const char* msg) {
|
||||||
__asm__ volatile ("cli; hlt");
|
draw_panic_bg();
|
||||||
}
|
|
||||||
}
|
kprintf("\t\t^yReason^w: %s\n", msg);
|
||||||
|
kprintf("\t\t--------------------------------\n");
|
||||||
|
kprintf("\t\t\t\t^tSystem halted.^w\n");
|
||||||
|
|
||||||
|
die();
|
||||||
|
}
|
||||||
@@ -0,0 +1,89 @@
|
|||||||
|
#include "pmm.h"
|
||||||
|
#include "bootinfo.h"
|
||||||
|
#include "panic.h"
|
||||||
|
#include "types.h"
|
||||||
|
#include "memory.h" // IWYU pragma: keep // clangd is stupid af
|
||||||
|
#include "math.h"
|
||||||
|
|
||||||
|
#define SAFE_SPACE_START_ADDR 0x100000
|
||||||
|
|
||||||
|
extern u64 _kernel_start;
|
||||||
|
extern u64 _kernel_end;
|
||||||
|
|
||||||
|
u8* bitmap = nullptr;
|
||||||
|
u64 bitmap_size_g = 0;
|
||||||
|
|
||||||
|
void pmm_init(BI_MemoryMap mmap) {
|
||||||
|
u64 descriptors_count = mmap.map_size / mmap.descriptor_size;
|
||||||
|
u64 max_physical_address = 0;
|
||||||
|
|
||||||
|
for (u64 i = 0; i < descriptors_count; i++) {
|
||||||
|
efi_memory_descriptor_k* descriptor = (efi_memory_descriptor_k*)((u8*)mmap.map + (i * mmap.descriptor_size));
|
||||||
|
u64 nominee = descriptor->physical_start + descriptor->number_of_pages * PAGE_SIZE;
|
||||||
|
max_physical_address = MAX(nominee, max_physical_address);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 pages_count = max_physical_address / PAGE_SIZE;
|
||||||
|
u64 bitmap_size = (pages_count + 7) / 8;
|
||||||
|
efi_memory_descriptor_k* desc_to_save = nullptr;
|
||||||
|
|
||||||
|
for (u64 i = 0; i < descriptors_count; i++) {
|
||||||
|
efi_memory_descriptor_k* descriptor = (efi_memory_descriptor_k*)((u8*)mmap.map + (i * mmap.descriptor_size));
|
||||||
|
// scary
|
||||||
|
if ((descriptor->type == EfiConventionalMemory) && \
|
||||||
|
((descriptor->number_of_pages * PAGE_SIZE) >= bitmap_size) && \
|
||||||
|
(descriptor->physical_start >= SAFE_SPACE_START_ADDR)) {
|
||||||
|
desc_to_save = descriptor;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (desc_to_save == nullptr) {
|
||||||
|
panic("Not enough RAM for bitmap!");
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap = (u8*)desc_to_save->physical_start;
|
||||||
|
bitmap_size_g = bitmap_size;
|
||||||
|
|
||||||
|
memset(bitmap, 0xFF, bitmap_size);
|
||||||
|
|
||||||
|
for (u64 i = 0; i < descriptors_count; i++) {
|
||||||
|
efi_memory_descriptor_k* descriptor = (efi_memory_descriptor_k*)((u8*)mmap.map + (i * mmap.descriptor_size));// this shit will haunt my dreams
|
||||||
|
if (descriptor->type != EfiConventionalMemory) continue;
|
||||||
|
u64 start_addr = descriptor->physical_start;
|
||||||
|
u64 end_addr = start_addr + (descriptor->number_of_pages * PAGE_SIZE);
|
||||||
|
for (u64 j = start_addr; j < end_addr; j += PAGE_SIZE) BITMAP_UNSET(bitmap, j);
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 k_start = (u64)&_kernel_start;
|
||||||
|
u64 k_end = (u64)&_kernel_end;
|
||||||
|
|
||||||
|
u64 bitmap_start = (u64)bitmap;
|
||||||
|
u64 bitmap_end = bitmap_start + bitmap_size_g;
|
||||||
|
|
||||||
|
for (u64 i = 0; i < SAFE_SPACE_START_ADDR; i += PAGE_SIZE) BITMAP_SET(bitmap, i); // mem, that addr < 1MB is NOT safe to use on x86
|
||||||
|
for (u64 i = k_start; i < k_end; i += PAGE_SIZE) BITMAP_SET(bitmap, i);
|
||||||
|
for (u64 i = bitmap_start; i < bitmap_end; i += PAGE_SIZE) BITMAP_SET(bitmap, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* pmm_alloc_page() {
|
||||||
|
for (u64 i = 0; i < bitmap_size_g; i++) {
|
||||||
|
if (bitmap[i] == 0xFF) continue;
|
||||||
|
for (u64 j = 0; j < 8; j++) {
|
||||||
|
u64 addr = (i * 8 + j) * PAGE_SIZE;
|
||||||
|
if ((bitmap[i] & (1 << j)) == 0) {
|
||||||
|
BITMAP_SET(bitmap, addr);
|
||||||
|
return (void*)addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
void pmm_free_page(void* addr) {
|
||||||
|
BITMAP_UNSET(bitmap, (u64)addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
u8* get_bitmap() {
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user