Claude Code keeps per-project memory at <home>/.claude/projects/<key>/,
where <key> is the project's absolute path with every separator and the
drive colon turned into a dash. That makes it both rename-fragile and
machine-specific, and this project has hit each of those once:
- D:\DEV\Schunix -> D:\DEV\SchOS changed the key, and 43 memories were
invisible until moved across by hand.
- Development happens from Windows and from Linux, and each looks in a
different place for the same checkout.
Committing .claude/memory/ fixes both -- git carries it across renames
and between hosts -- and `import` puts it wherever the local machine
expects. .claude/settings.local.json stays ignored: those are per-machine
permissions.
The colon maps to a dash rather than being dropped. Deleting it gives
D-DEV-SchOS, which matches nothing and silently finds zero memories; that
was the first attempt. On Git Bash the key comes from `cygpath -w`,
because Claude Code is a Windows program and sees D:\DEV\SchOS, not
/d/DEV/SchOS.
45 lines
2.4 KiB
Markdown
45 lines
2.4 KiB
Markdown
---
|
|
name: schunix-pci-drivers
|
|
description: PCI enumeration lives in kernel/dev/pci.c; drivers that find their own hardware go in kernel/drivers/ and are listed in registry.c
|
|
metadata:
|
|
node_type: memory
|
|
type: project
|
|
originSessionId: a665e14b-86bd-4b41-a228-51377f3e9225
|
|
modified: 2026-08-04T17:28:31.246Z
|
|
---
|
|
|
|
**`kernel/dev/pci.c` enumerates the PCI bus** (added 2026-08-04), through the
|
|
old 0xCF8/0xCFC config mechanism — the one that works without first finding an
|
|
ACPI table. The scan recurses through bridges rather than sweeping all 256
|
|
buses flat, so it also knows what sits behind what.
|
|
|
|
BAR sizes are found by writing all ones and reading back the bits the device
|
|
does not decode; **the original value must be restored**, since that briefly
|
|
points a live device's decoder at the top of the address space. 64-bit BARs
|
|
consume the following slot. Only header type 0 has six BARs — a bridge is
|
|
type 1 with a completely different layout.
|
|
|
|
**`kernel/drivers/` is the folder for drivers that have to *find* their
|
|
hardware.** Fixed-address legacy devices (console, keyboard, the IDE ports)
|
|
stay in `kernel/dev/`. To add one: write `kernel/drivers/<name>.c` exporting a
|
|
`struct pci_driver`, declare it in `kernel/drivers/registry.c`, add it to the
|
|
array there, and add the object to `KERN_DRIVERS` in the Makefile.
|
|
|
|
The registry is a plain array rather than the linker-section trick, on
|
|
purpose: it keeps the list of what is in the kernel somewhere you can read.
|
|
A driver silently dropped by the linker looks identical to one never written.
|
|
|
|
`kernel/drivers/vga_pci.c` is the first driver and the template. It draws
|
|
nothing — vga.c still owns the framebuffer — but it cross-checks the aperture
|
|
it finds on the bus against the address VBE reported. That disagreement is
|
|
exactly the symptom that would have surfaced first on hardware where the old
|
|
hardcoded `0xfd000000` was wrong. See [[schunix-framebuffer-device]].
|
|
|
|
**`cat /proc/pci`** lists everything found, lspci-shaped, with the binding
|
|
driver in brackets (`[-]` when unclaimed). Under QEMU's default i440fx it
|
|
should show six devices; `tools/bootcheck.ps1` asserts on the host bridge and
|
|
the IDE controller by ID, and on `[vga]` having bound.
|
|
|
|
`inl`/`outl` were added to include/x86.h for this — config space is only
|
|
reachable in dwords, so `pci_read16`/`pci_read8` shift and mask the containing
|
|
dword rather than doing a narrower bus cycle.
|