ldls: the top-2 GB window Linux modules link against

A Linux module is built with -mcmodel=kernel and can only reach addresses
in the top 2 GB, where this kernel is not linked. So the kernel image is
mapped a second time at LDLS_KALIAS, with a vmemmap area and a module area
beside it, in one PDPT shared by every address space. Nothing loads a
module yet; this is the address-space groundwork, set up at every boot,
and include/ldls/ is the interface the loader will use.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
This commit is contained in:
Nexoniarz 2026-10-24 22:12:40 +02:00
commit 65617710fa
4 changed files with 253 additions and 4 deletions

View file

@ -91,6 +91,22 @@ extern uint64 lowtop;
#define KERNPHYS 0x1000000
#define KERNLINK (KERNBASE+KERNPHYS) // Address where kernel is linked
// The LDLS window, in the top 2 GB, where a Linux module expects to live. See
// ldls_vm_init() in kernel/arch/x86_64/vm.c.
//
// LDLS_VMEMMAP 1 GB Linux's `struct page` array, 64 bytes per frame --
// enough for 64 GB, not for all of PHYSTOP_MAX; a
// frame above that has no struct page. Backed on demand.
// LDLS_KALIAS 512 MB the kernel image again, from physical zero
// LDLS_MODBASE 512 MB modules, their stacks and their vmalloc
#define LDLS_VMEMMAP 0xFFFFFFFF40000000ULL
#define LDLS_KALIAS 0xFFFFFFFF80000000ULL
#define LDLS_MODBASE 0xFFFFFFFFA0000000ULL
#define LDLS_MODEND 0xFFFFFFFFC0000000ULL
// A kernel address, as a module sees it.
#define LDLS_ALIAS(a) ((uint64)(a) - KERNBASE + LDLS_KALIAS)
#ifndef __ASSEMBLER__
static inline addr_t v2p(void *a) {
return ((addr_t)(a)) - ((addr_t)KERNBASE);