// 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