From fdee46a0bd9e2cab566c4063526757bf6ae25cb8 Mon Sep 17 00:00:00 2001 From: amirh Date: Tue, 30 Jun 2026 18:26:01 +0330 Subject: [PATCH] enable framebuffer with multiboot2 and reserve frambuffer memory in pmm --- arch/x86_64/boot.asm | 52 ++++++++++++++++++++++++-------------------- mm/pmm.c | 41 +++++++++++++++++++++++++++++----- 2 files changed, 64 insertions(+), 29 deletions(-) diff --git a/arch/x86_64/boot.asm b/arch/x86_64/boot.asm index ca15ef8..f92349e 100644 --- a/arch/x86_64/boot.asm +++ b/arch/x86_64/boot.asm @@ -1,4 +1,3 @@ - section .multiboot2 bits 32 @@ -13,6 +12,20 @@ mb2_start: dd MB2_ARCH dd MB2_LEN dd MB2_CHECKSUM + + ; ---- framebuffer tag ---- + align 8 +fb_tag_start: + dw 5 ; type = 5 (framebuffer) + dw 0 ; flags = 0 (required) + dd fb_tag_end - fb_tag_start ; size = کل تگ (20 بایت) + dd 1024 ; width + dd 768 ; height + dd 32 ; depth +fb_tag_end: + + ; ---- end tag ---- + align 8 dw 0 dw 0 dd 8 @@ -279,11 +292,9 @@ section .text global syscall_asm_entry syscall_asm_entry: - - ; Capture user state BEFORE any stack changes — fork() reads these - mov [user_ctx_rip], rcx ; user RIP (SYSCALL saves RIP → RCX) - mov [user_ctx_rflags], r11 ; user RFLAGS (SYSCALL saves RFLAGS → R11) - mov [user_ctx_rsp], rsp ; user RSP (unchanged at SYSCALL entry) + mov [user_ctx_rip], rcx + mov [user_ctx_rflags], r11 + mov [user_ctx_rsp], rsp push rcx push r11 @@ -298,36 +309,29 @@ syscall_asm_entry: pop rcx o64 sysret -; ── fork child trampoline ─────────────────────────────────────────── -; Called by arch_switch when the forked child is first scheduled. -; arch_switch restores: r15, r14, r13, r12, rbp, rbx -; We encode: r12 = user RIP -; r13 = user RSP -; r14 = user RFLAGS global fork_child_stub fork_child_stub: - mov ax, 0x23 ; restore user data segments + mov ax, 0x23 mov ds, ax mov es, ax - xor rax, rax ; child returns 0 from fork() - mov rcx, r12 ; user RIP → sysretq reads rcx - mov r11, r14 ; user RFLAGS → sysretq reads r11 - mov rsp, r13 ; switch back to user stack (pre-syscall RSP) + xor rax, rax + mov rcx, r12 + mov r11, r14 + mov rsp, r13 o64 sysret global _enter_usermode _enter_usermode: cli - mov ax, 0x23 mov ds, ax mov es, ax mov fs, ax mov gs, ax - push qword 0x23 ; SS (user data selector | RPL3) - push rsi ; RSP (user stack) - push qword 0x202 ; RFLAGS (IF=1, reserved bit 1) - push qword 0x1B ; CS (user code selector | RPL3) - push rdi ; RIP (entry point) - iretq + push qword 0x23 + push rsi + push qword 0x202 + push qword 0x1B + push rdi + iretq \ No newline at end of file diff --git a/mm/pmm.c b/mm/pmm.c index 39e08ac..d7e0a2c 100644 --- a/mm/pmm.c +++ b/mm/pmm.c @@ -1,12 +1,12 @@ - #include "pmm.h" #include "../lib/string.h" #include #include -#define MB2_MAGIC_VAL 0x36D76289u -#define TAG_END 0u -#define TAG_MMAP 6u +#define MB2_MAGIC_VAL 0x36D76289u +#define TAG_END 0u +#define TAG_MMAP 6u +#define TAG_FRAMEBUFFER 8u typedef struct __attribute__((packed)) { uint32_t total, reserved; } mb2_hdr_t; typedef struct __attribute__((packed)) { uint32_t type, size; } mb2_tag_t; @@ -17,6 +17,16 @@ typedef struct __attribute__((packed)) { uint64_t base, len; uint32_t type, _res; } mb2_mmap_entry_t; +typedef struct __attribute__((packed)) { + uint32_t type, size; + uint64_t fb_addr; + uint32_t fb_pitch; + uint32_t fb_width; + uint32_t fb_height; + uint8_t fb_bpp; + uint8_t fb_type; + uint16_t reserved; +} mb2_fb_tag_t; #define BITMAP_MAX_PAGES (16 * 1024 * 1024) @@ -25,6 +35,9 @@ static size_t total_pages = 0; static size_t free_pages = 0; static size_t bitmap_size = 0; +static uint64_t fb_addr = 0; +static uint64_t fb_len = 0; + static void bm_set (size_t idx) { bitmap[idx/8] |= (uint8_t)(1u << (idx%8)); } static void bm_clear(size_t idx) { bitmap[idx/8] &= (uint8_t)~(1u << (idx%8)); } static bool bm_test (size_t idx) { return (bitmap[idx/8] >> (idx%8)) & 1u; } @@ -52,6 +65,12 @@ pmm_init(uint32_t magic, uint64_t info_addr) if (e->type == 1 && top > max_addr) max_addr = top; ep += mt->entry_size; } + } else if (tag->type == TAG_FRAMEBUFFER) { + mb2_fb_tag_t *fb = (mb2_fb_tag_t *)ptr; + fb_addr = fb->fb_addr; + fb_len = (uint64_t)fb->fb_pitch * fb->fb_height; + uint64_t fb_top = fb_addr + fb_len; + if (fb_top > max_addr) max_addr = fb_top; } ptr += (tag->size + 7) & ~7u; } @@ -117,6 +136,18 @@ pmm_init(uint32_t magic, uint64_t info_addr) free_pages--; } } + + if (fb_addr != 0 && fb_len != 0) { + uint64_t start = fb_addr & ~(uint64_t)(PAGE_SIZE - 1); + uint64_t stop = (fb_addr + fb_len + PAGE_SIZE - 1) & ~(uint64_t)(PAGE_SIZE - 1); + for (uint64_t a = start; a < stop; a += PAGE_SIZE) { + size_t idx = (size_t)(a / PAGE_SIZE); + if (idx < total_pages && !bm_test(idx)) { + bm_set(idx); + free_pages--; + } + } + } } void * @@ -143,4 +174,4 @@ pmm_free(void *page) } size_t pmm_free_pages(void) { return free_pages; } -size_t pmm_total_pages(void) { return total_pages; } +size_t pmm_total_pages(void) { return total_pages; } \ No newline at end of file