ldls: L4 was free after all, and the plan closes
L4 was listed as "free -- H2 built all of this" and never actually tested,
which is a claim rather than a result. Tested now, and it holds:
ldlsd running ping 2/2; holds index 7 and DMA slots 3 and 4
killed interface DOWN, device released, bus mastering
cleared, DMA reclaimed -- back to vgpud's 3 blocks
ping fails honestly: sendto: -5
a second ldlsd ping 3/3, and the arena hands back the same addresses
pciuser_release_all() and netuser_release_all() sit beside each other in
exit() for the same reason, and that they apply unchanged to a foreign driver
is the whole point of having built them against our own.
With that, every milestone on ldls.md is done, so it leaves docs/plan/ for
docs/architecture/ -- the rule docs/plan/README.md states and the one that
keeps the two directories meaning different things. The new document describes
what is, not what was planned: the five rules, the four pieces, what it costs
(polling, no stack protector, locks that are no-ops), that it can be killed,
and a "what it does not do" that leads with one driver, one kernel version,
tried once.
Sixteen source files pointed at docs/plan/ldls.md and would have been dangling
the moment it moved. All repointed, and the milestone references -- which the
architecture doc deliberately does not have -- rewritten to name sections
instead, so a reader lands somewhere real.
The register row closes with it. hybrid.md freed a slot, ldls.md took it, and
it is now free again.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VQ7Qx8E1q1M1bbCq8QLHS2
This commit is contained in:
parent
888c48fd96
commit
f38eb8a7fd
22 changed files with 278 additions and 929 deletions
|
|
@ -3,7 +3,8 @@
|
|||
// Reading BTF: struct layouts and function prototypes, from the kernel that
|
||||
// the driver was built for.
|
||||
//
|
||||
// docs/plan/ldls.md milestone L2, and the thing that makes rule 3 comfortable.
|
||||
// docs/architecture/ldls.md, rule 3½ -- the thing that makes rule 3 comfortable.
|
||||
//
|
||||
// The shim has to agree with a compiled driver about where `pci_driver.probe`
|
||||
// sits, and a compiled driver is not negotiable about it. Writing those
|
||||
// offsets into our source would mean a field-for-field match with Linux's
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// ldls-inspect -- what is in a relocatable object, and what it wants.
|
||||
//
|
||||
// docs/plan/ldls.md milestone L0, run on the machine doing the building rather
|
||||
// docs/architecture/ldls.md, "The loader", run on the machine doing the building rather
|
||||
// than inside SchOS. That is the same arrangement `mkschfs` has with the
|
||||
// kernel, for the same reason: the interesting failures here are format
|
||||
// failures, and a format failure found on the host costs a second instead of a
|
||||
|
|
@ -15,7 +15,7 @@
|
|||
// ldls-inspect 8139too.ko
|
||||
//
|
||||
// **No module is committed to this tree**, and none ever will be; see
|
||||
// docs/plan/ldls.md rule 1. `make ldls-check` runs this against an object
|
||||
// docs/architecture/ldls.md rule 1. `make ldls-check` runs this against an object
|
||||
// built from ldls/test/refmod.c, which is ours.
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// ldls-run -- load a module and call its init, on the build machine.
|
||||
//
|
||||
// docs/plan/ldls.md milestone L1. L0 answered "what does this driver ask
|
||||
// docs/architecture/ldls.md. The loader answered "what does this driver ask
|
||||
// for"; this answers "and in what order does it ask", which is the other thing
|
||||
// that cannot be guessed and falls straight out of running the thing.
|
||||
//
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
// that logs and returns zero, so a driver gets as far as its first real
|
||||
// dependency on the kernel doing something, and then says so.
|
||||
//
|
||||
// **No module is committed to this tree.** See docs/plan/ldls.md rule 1.
|
||||
// **No module is committed to this tree.** See docs/architecture/ldls.md rule 1.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
@ -264,7 +264,7 @@ wr64(unsigned long base, unsigned int off, unsigned long v)
|
|||
// The PCI resource flag bits. These are not layout and BTF does not carry
|
||||
// them -- they are #defines. They are ABI between the kernel and every driver
|
||||
// ever written against it, which makes them facts in the sense of
|
||||
// docs/plan/ldls.md rule 3, and there are two of them.
|
||||
// docs/architecture/ldls.md rule 3, and there are two of them.
|
||||
#define LDLS_IORESOURCE_IO 0x00000100
|
||||
#define LDLS_IORESOURCE_MEM 0x00000200
|
||||
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@
|
|||
//
|
||||
// ldls-types -- ask a kernel's BTF where its fields are.
|
||||
//
|
||||
// docs/plan/ldls.md milestone L2. This is the tool that proves the layouts LDLS
|
||||
// needs can be read from the kernel the user already has, rather than written
|
||||
// into our source from theirs.
|
||||
// docs/architecture/ldls.md, rule 3½. This is the tool that proves the layouts
|
||||
// LDLS needs can be read from the kernel the user already has, rather than
|
||||
// written into our source from theirs.
|
||||
//
|
||||
// ldls-types /sys/kernel/btf/vmlinux pci_driver probe id_table
|
||||
// ldls-types /sys/kernel/btf/vmlinux --need
|
||||
//
|
||||
// `--need` prints every offset the PCI path needs at once, which is both a
|
||||
// test and the thing L2's driver code consumes.
|
||||
// test and the thing cmd/ldlsd consumes.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
|
|
|||
|
|
@ -647,7 +647,7 @@ ko_name(const struct ko *k)
|
|||
|
||||
// The module's `struct module` lives in `.gnu.linkonce.this_module` and its
|
||||
// name is at a fixed offset -- but that offset is a property of the kernel
|
||||
// version, which is exactly the kind of thing docs/plan/ldls.md rule 4 says
|
||||
// version, which is exactly the kind of thing docs/architecture/ldls.md rule 4 says
|
||||
// not to assume. The symbol table has the same information portably: the
|
||||
// object defines `__this_module`, and `.modinfo` carries the rest.
|
||||
for (i = 0; i < k->nsym; i++) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
// SPDX-License-Identifier: Apache-2.0
|
||||
#pragma once
|
||||
|
||||
// Loading a relocatable object. docs/plan/ldls.md milestone L0.
|
||||
// Loading a relocatable object. docs/architecture/ldls.md, "The loader".
|
||||
//
|
||||
// A Linux `.ko` is an ordinary ELF64 relocatable object -- the same thing
|
||||
// `gcc -c` produces -- and loading one is four steps with no mystery in any of
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
// and there is no other way to express that. What each one *does* is written
|
||||
// here from the published behaviour and from what the driver requires of it.
|
||||
// No comment, macro body or implementation has been carried over from
|
||||
// anywhere. docs/plan/ldls.md §3.
|
||||
// anywhere. docs/architecture/ldls.md §3.
|
||||
|
||||
#include "types.h"
|
||||
#include "user.h"
|
||||
|
|
@ -172,7 +172,7 @@ kpi_dma_free_attrs(void *dev, unsigned long size, void *va,
|
|||
// *correct* rather than merely convenient: there is nobody to race with.
|
||||
//
|
||||
// This stops being true the moment a driver has an interrupt thread, and the
|
||||
// note in docs/plan/ldls.md about sleeping-context fidelity is about exactly
|
||||
// note in docs/architecture/ldls.md about sleeping-context fidelity is about exactly
|
||||
// this. It is the deepest unfixed assumption in the whole layer.
|
||||
|
||||
void kpi_nop(void) { }
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// The KPI: the Linux symbols a hosted driver actually calls, implemented.
|
||||
//
|
||||
// docs/plan/ldls.md milestone L3c. L1 and L2 measured what a driver asks for
|
||||
// docs/architecture/ldls.md, "The KPI". The stub passes measured what a driver asks for
|
||||
// and in what order; this is what answers, for real, against `/dev/pci` and
|
||||
// `/dev/netdev`.
|
||||
//
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ kpi_dev_addr_mod(void *dev, unsigned int off, const unsigned char *addr,
|
|||
|
||||
// Become an interface.
|
||||
//
|
||||
// /dev/netdev is the bridge docs/plan/ldls.md calls the class bridge, built
|
||||
// /dev/netdev is the bridge docs/architecture/ldls.md calls the class bridge, built
|
||||
// and proved at L3a by `netecho` with no hardware behind it at all. Here there
|
||||
// is: the same four calls, answered by a Linux driver.
|
||||
int
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// Stubs: giving every undefined symbol an address that says who it was.
|
||||
//
|
||||
// docs/plan/ldls.md milestone L1. L0 measured what a module asks for; this is
|
||||
// docs/architecture/ldls.md, rule 5. The loader measures what a module asks for; this is
|
||||
// what answers. Every name resolves to a small block of generated code, and
|
||||
// when the driver calls it the block says which name it was and what arguments
|
||||
// it came with.
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// The loader's test object. **Ours, on purpose.**
|
||||
//
|
||||
// docs/plan/ldls.md rule 1 says nothing GPL ever enters an image we build, and
|
||||
// docs/architecture/ldls.md rule 1 says nothing GPL ever enters an image we build, and
|
||||
// the same rule applies to the tree itself: there is no `.ko` committed here
|
||||
// and there never will be. So the thing `make ldls-check` loads is this file,
|
||||
// compiled with `-c`, which produces exactly what a `.ko` is -- an ELF64
|
||||
|
|
|
|||
Loading…
Reference in a new issue