Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 28 additions & 24 deletions arch/x86_64/boot.asm
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

section .multiboot2
bits 32

Expand All @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
41 changes: 36 additions & 5 deletions mm/pmm.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@

#include "pmm.h"
#include "../lib/string.h"
#include <stdint.h>
#include <stdbool.h>

#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;
Expand All @@ -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)

Expand All @@ -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; }
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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 *
Expand All @@ -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; }