From 05540924a2c7020b3a2cc57f9c0b8ef49cdca18f Mon Sep 17 00:00:00 2001 From: Tulio A M Mendes Date: Thu, 12 Feb 2026 01:18:08 -0300 Subject: [PATCH] =?utf8?q?feat:=20vDSO=20shared=20page=20=E2=80=94=20kerne?= =?utf8?q?l-updated=20tick=5Fcount=20mapped=20read-only=20into=20user=20ad?= =?utf8?q?dress=20space=20at=200x007FE000?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- include/vdso.h | 29 +++++++++++++++++++++++ src/arch/x86/elf.c | 10 ++++++++ src/drivers/timer.c | 2 ++ src/kernel/main.c | 6 +++++ src/kernel/vdso.c | 57 +++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 104 insertions(+) create mode 100644 include/vdso.h create mode 100644 src/kernel/vdso.c diff --git a/include/vdso.h b/include/vdso.h new file mode 100644 index 00000000..810b6abc --- /dev/null +++ b/include/vdso.h @@ -0,0 +1,29 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2018, Tulio A M Mendes + * All rights reserved. + * See LICENSE for details. + * + * Source: https://github.com/tadryanom/AdrOS + */ + +#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 bf0f989d..2243ce9b 100644 --- a/src/arch/x86/elf.c +++ b/src/arch/x86/elf.c @@ -301,6 +301,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 935755c5..f789de1a 100644 --- a/src/drivers/timer.c +++ b/src/drivers/timer.c @@ -10,6 +10,7 @@ #include "timer.h" #include "uart_console.h" #include "process.h" +#include "vdso.h" #include "hal/timer.h" @@ -21,6 +22,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 46bb2ad0..75a80ecb 100644 --- a/src/kernel/main.c +++ b/src/kernel/main.c @@ -72,6 +72,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 00000000..ec41b1c9 --- /dev/null +++ b/src/kernel/vdso.c @@ -0,0 +1,57 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2018, Tulio A M Mendes + * All rights reserved. + * See LICENSE for details. + * + * Source: https://github.com/tadryanom/AdrOS + */ + +#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; +} -- 2.43.0