From: Tulio A M Mendes Date: Thu, 12 Feb 2026 04:18:08 +0000 (-0300) Subject: feat: vDSO shared page — kernel-updated tick_count mapped read-only into user address... X-Git-Url: https://projects.tadryanom.me/docs/static/gitweb.css?a=commitdiff_plain;h=72d2f05b6cf5f845cce1138b15211b44d925d5f2;p=AdrOS.git feat: vDSO shared page — kernel-updated tick_count mapped read-only into user address space at 0x007FE000 --- diff --git a/include/vdso.h b/include/vdso.h new file mode 100644 index 0000000..9048ef1 --- /dev/null +++ b/include/vdso.h @@ -0,0 +1,20 @@ +#ifndef VDSO_H +#define VDSO_H + +#include + +/* Shared page layout — mapped read-only at VDSO_USER_ADDR in every process */ +#define VDSO_USER_ADDR 0x007FE000U /* one page below stack guard */ + +struct vdso_data { + volatile uint32_t tick_count; /* updated by kernel timer ISR */ + uint32_t tick_hz; /* ticks per second (e.g. 50) */ +}; + +void vdso_init(void); +void vdso_update_tick(uint32_t tick); + +/* Returns the physical address of the vDSO page (for mapping into user AS) */ +uintptr_t vdso_get_phys(void); + +#endif diff --git a/src/arch/x86/elf.c b/src/arch/x86/elf.c index ebe9fa2..9eacc64 100644 --- a/src/arch/x86/elf.c +++ b/src/arch/x86/elf.c @@ -292,6 +292,16 @@ int elf32_load_user_from_initrd(const char* filename, uintptr_t* entry_out, uint return src2; } + /* Map vDSO shared page read-only into user address space */ + { + extern uintptr_t vdso_get_phys(void); + uintptr_t vp = vdso_get_phys(); + if (vp) { + vmm_map_page((uint64_t)vp, (uint64_t)0x007FE000U, + VMM_FLAG_PRESENT | VMM_FLAG_USER); + } + } + *entry_out = real_entry; *user_stack_top_out = user_stack_base + user_stack_size; *addr_space_out = new_as; diff --git a/src/drivers/timer.c b/src/drivers/timer.c index be453eb..d6bd59b 100644 --- a/src/drivers/timer.c +++ b/src/drivers/timer.c @@ -1,6 +1,7 @@ #include "timer.h" #include "uart_console.h" #include "process.h" +#include "vdso.h" #include "hal/timer.h" @@ -12,6 +13,7 @@ uint32_t get_tick_count(void) { static void hal_tick_bridge(void) { tick++; + vdso_update_tick(tick); process_wake_check(tick); schedule(); } diff --git a/src/kernel/main.c b/src/kernel/main.c index bab32ee..b0f5dd0 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -63,6 +63,12 @@ void kernel_main(const struct boot_info* bi) { kprintf("[AdrOS] Initializing Scheduler...\n"); process_init(); + // 7b. Initialize vDSO shared page + { + extern void vdso_init(void); + vdso_init(); + } + // 8. Start Timer (Preemption!) - 50Hz timer_init(50); diff --git a/src/kernel/vdso.c b/src/kernel/vdso.c new file mode 100644 index 0000000..5c09a33 --- /dev/null +++ b/src/kernel/vdso.c @@ -0,0 +1,48 @@ +#include "vdso.h" +#include "pmm.h" +#include "vmm.h" +#include "utils.h" +#include "uart_console.h" + +static uintptr_t vdso_phys = 0; +static volatile struct vdso_data* vdso_kptr = 0; + +void vdso_init(void) { + void* page = pmm_alloc_page(); + if (!page) { + uart_print("[VDSO] OOM\n"); + return; + } + vdso_phys = (uintptr_t)page; + + /* Map into kernel space at a fixed VA so we can write to it. + * Use 0xC0230000 (above ATA DMA bounce at 0xC0221000). */ + uintptr_t kva = 0xC0230000U; + vmm_map_page((uint64_t)vdso_phys, (uint64_t)kva, + VMM_FLAG_PRESENT | VMM_FLAG_RW); + + vdso_kptr = (volatile struct vdso_data*)kva; + memset((void*)vdso_kptr, 0, PAGE_SIZE); + vdso_kptr->tick_hz = 50; + + uart_print("[VDSO] Initialized at phys=0x"); + /* Simple hex print */ + char hex[9]; + for (int i = 7; i >= 0; i--) { + uint8_t nib = (uint8_t)((vdso_phys >> (i * 4)) & 0xF); + hex[7 - i] = (char)(nib < 10 ? '0' + nib : 'a' + nib - 10); + } + hex[8] = '\0'; + uart_print(hex); + uart_print("\n"); +} + +void vdso_update_tick(uint32_t tick) { + if (vdso_kptr) { + vdso_kptr->tick_count = tick; + } +} + +uintptr_t vdso_get_phys(void) { + return vdso_phys; +}