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:
parent
b524a73522
commit
65617710fa
4 changed files with 253 additions and 4 deletions
53
include/ldls/ldls.h
Normal file
53
include/ldls/ldls.h
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#pragma once
|
||||
|
||||
// /dev/ldls -- Linux drivers, in the kernel. docs/architecture/ldls.md.
|
||||
//
|
||||
// The device is a control channel and nothing else: a module is handed over
|
||||
// whole, as bytes, together with the BTF of the kernel it was built for, and
|
||||
// the kernel does the rest -- loading, linking, init_module, probe, and
|
||||
// bringing the interface up -- on a thread of its own. What happened comes
|
||||
// back as text, because the useful answer to "did it work" is the driver's
|
||||
// own account of what it found.
|
||||
//
|
||||
// ldls load /lib/modules/e1000.ko
|
||||
// ldls list
|
||||
// ldls unload e1000
|
||||
//
|
||||
// Shared with userland (cmd/ldls), so it is spelled in plain C types.
|
||||
|
||||
#define LDLS_MAJOR 13
|
||||
|
||||
// Take the device even if a kernel driver holds it, provided that driver can
|
||||
// be asked to let go. Without this LDLS only takes devices nothing else
|
||||
// drives, which is the right default at boot: the kernel's own driver is on
|
||||
// the path to a shell, and the hosted one is the better one only when someone
|
||||
// says so.
|
||||
#define LDLS_TAKE 0x1
|
||||
// Load and link, run init_module, and stop: no device is probed. For a
|
||||
// library module (mii, libphy) whose job is to export symbols to the next.
|
||||
#define LDLS_NOPROBE 0x2
|
||||
|
||||
struct ldls_load {
|
||||
unsigned long long ko; // in: the module image
|
||||
unsigned long long kolen;
|
||||
unsigned long long btf; // in: the kernel's BTF, /sys/kernel/btf/vmlinux
|
||||
unsigned long long btflen;
|
||||
unsigned long long msg; // out: what happened, NUL-terminated
|
||||
unsigned int msgcap;
|
||||
unsigned int flags; // LDLS_*
|
||||
int bus, slot, func; // -1 for "whichever matches"
|
||||
unsigned int hz; // CONFIG_HZ of that kernel; 0 means 1000
|
||||
int id; // out: the module's id, for unload
|
||||
};
|
||||
|
||||
struct ldls_text {
|
||||
unsigned long long buf; // out
|
||||
unsigned int cap;
|
||||
unsigned int pad;
|
||||
};
|
||||
|
||||
#define LDLSIOC_LOAD 0xD000 // struct ldls_load
|
||||
#define LDLSIOC_UNLOAD 0xD001 // in: int id
|
||||
#define LDLSIOC_LIST 0xD002 // struct ldls_text
|
||||
#define LDLSIOC_LOG 0xD003 // struct ldls_text, in: pad = id
|
||||
Loading…
Reference in a new issue