Sixty-five headers sat side by side in include/, so `#include "irq.h"` said nothing about where irq.h was or what it belonged to, and errno.h, stat.h and fcntl.h at the top shadowed the system's for any host tool built with -I./include. They are in folders now -- arch/ core/ fs/ dev/ gfx/ net/ uapi/ (and ldls/ for the Linux driver layer) -- and every include names the folder, as Linux's do: "core/proc.h". Done mechanically and checked the hard way: the kernel built from this tree disassembles identically to the one built from the tree before it. The full image boots, and userland is the same set of programs. Paths in docs and comments follow; docs/guides/layout.md has a table of what is where, and tools/fix-includes.py rewrites old-style includes from the folders in the tree, for code written before this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01S1giNvrHTrPMPw7V6x1kQ4
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/arch/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.
|