Compare commits
8 changed files with 28 additions and 166 deletions
50
Makefile
50
Makefile
|
|
@ -38,34 +38,17 @@ KERN_DEV = $(addprefix $(BUILD)/kernel/dev/, \
|
|||
# already eight files with four called usb_something, and each driver added made
|
||||
# the directory harder to read. The compile rule uses `mkdir -p $(dir $@)`, so
|
||||
# the depth costs nothing.
|
||||
# Which of them are compiled in is config/drivers.conf: y or n per driver, y by
|
||||
# default, overridable on the command line (make DRV_E1000=n). Only the drivers
|
||||
# that nothing else calls can be left out; the rest are always linked.
|
||||
-include config/drivers.conf
|
||||
DRV_LIST = VGA_PCI VIRTIO_GPU E1000 RTL8139 R8169 AC97 AHCI NVME
|
||||
DRV_DEFAULT_R8169 = n
|
||||
$(foreach d,$(DRV_LIST),$(eval DRV_$(d) ?= $(if $(DRV_DEFAULT_$(d)),$(DRV_DEFAULT_$(d)),y)))
|
||||
$(foreach d,$(DRV_LIST),$(if $(filter y n,$(DRV_$(d))),,$(error config/drivers.conf: DRV_$(d) must be y or n, not '$(DRV_$(d))')))
|
||||
DRV_DEFS = $(foreach d,$(DRV_LIST),$(if $(filter y,$(DRV_$(d))),-DCONFIG_DRV_$(d)=1))
|
||||
# Rewritten only when the choice changes, so registry.o is rebuilt then and not otherwise.
|
||||
DRV_STAMP = $(BUILD)/kernel/drivers/.config
|
||||
$(DRV_STAMP): FORCE
|
||||
@mkdir -p $(dir $@)
|
||||
@echo '$(DRV_DEFS)' | cmp -s - $@ || echo '$(DRV_DEFS)' > $@
|
||||
$(BUILD)/kernel/drivers/registry.o: $(DRV_STAMP)
|
||||
$(BUILD)/kernel/drivers/registry.o: CFLAGS += $(DRV_DEFS)
|
||||
|
||||
KERN_DRIVERS = $(BUILD)/kernel/drivers/registry.o
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/gpu/vga/vga_pci.o
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/gpu/vga/vga_fb.o
|
||||
KERN_DRIVERS += $(if $(filter y,$(DRV_VGA_PCI)),$(BUILD)/kernel/drivers/gpu/vga/vga_pci.o)
|
||||
KERN_DRIVERS += $(if $(filter y,$(DRV_VIRTIO_GPU)),$(BUILD)/kernel/drivers/gpu/virtio_gpu/virtio_gpu.o)
|
||||
KERN_DRIVERS += $(if $(filter y,$(DRV_E1000)),$(BUILD)/kernel/drivers/net/e1000/e1000.o)
|
||||
KERN_DRIVERS += $(if $(filter y,$(DRV_R8169)),$(BUILD)/kernel/drivers/net/r8169/r8169.o)
|
||||
KERN_DRIVERS += $(if $(filter y,$(DRV_RTL8139)),$(BUILD)/kernel/drivers/net/rtl8139/rtl8139.o)
|
||||
KERN_DRIVERS += $(if $(filter y,$(DRV_AC97)),$(BUILD)/kernel/drivers/audio/ac97.o)
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/gpu/virtio_gpu/virtio_gpu.o
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/net/e1000/e1000.o
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/net/r8169/r8169.o
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/net/rtl8139/rtl8139.o
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/audio/ac97.o
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/bus/xhci/xhci.o
|
||||
KERN_DRIVERS += $(if $(filter y,$(DRV_AHCI)),$(BUILD)/kernel/drivers/storage/ahci/ahci.o)
|
||||
KERN_DRIVERS += $(if $(filter y,$(DRV_NVME)),$(BUILD)/kernel/drivers/storage/nvme/nvme.o)
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/storage/ahci/ahci.o
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/storage/nvme/nvme.o
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/usb/core/usb.o
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/usb/hid/usb_hid.o
|
||||
KERN_DRIVERS += $(BUILD)/kernel/drivers/usb/storage/usb_storage.o
|
||||
|
|
@ -804,7 +787,6 @@ projects:
|
|||
# CFLAGS and make cannot see that.
|
||||
# -----------------------------------------------------------------------
|
||||
iso:
|
||||
@$(MAKE) --no-print-directory ldls-r8169-if-present
|
||||
$(MAKE) RAMROOT=1 schos.iso
|
||||
|
||||
# One El Torito entry, pointing at a FAT image holding the loader and kernel.
|
||||
|
|
@ -1428,15 +1410,6 @@ ldls-r8169:
|
|||
*) cp $$f $(SYSROOT)/lib/firmware/rtl_nic/;; esac; done
|
||||
@echo "staged Linux r8169 ($(shell uname -r)) into $(SYSROOT)"
|
||||
|
||||
# `make iso` runs this first: the ISO ships Linux's r8169 set (NOTICE), so stage it whenever
|
||||
# this machine has the modules and the BTF to stage it from, and say so when it does not.
|
||||
ldls-r8169-if-present:
|
||||
@if ls $(LDLS_KDIR)/drivers/net/ethernet/realtek/r8169.ko* >/dev/null 2>&1 && [ -r /sys/kernel/btf/vmlinux ]; then \
|
||||
$(MAKE) --no-print-directory ldls-r8169; \
|
||||
else \
|
||||
echo "iso: no Linux r8169 modules or BTF on this machine ($(LDLS_KDIR)) -- this ISO will not carry them"; \
|
||||
fi
|
||||
|
||||
ldls-unstage:
|
||||
rm -rf $(SYSROOT)/lib/modules
|
||||
@echo "removed"
|
||||
|
|
@ -1507,10 +1480,6 @@ etc-install: $(SCHINIT_JOBS) $(ETC_PLAIN) $(ETC_ZSH) $(LOGO_ASCII) $(SRV_FILES)
|
|||
@mkdir -p $(SYSROOT)/usr/share/hwdata
|
||||
@rm -f $(SYSROOT)/usr/share/usb.ids
|
||||
@for f in usb.ids pci.ids; do [ -f dist/$$f ] && cp -p dist/$$f $(SYSROOT)/usr/share/hwdata/; done; true
|
||||
@# The licences travel with the image: SchOS's, xv6's, and NOTICE, which carries the
|
||||
@# third-party ones -- including Linux's r8169 modules, whose source offer it records.
|
||||
@mkdir -p $(SYSROOT)/usr/share/licenses/schos
|
||||
@cp -p LICENSE LICENSE.MIT NOTICE $(SYSROOT)/usr/share/licenses/schos/
|
||||
@echo "installed $(words $(ETC_PLAIN)) /etc file(s), $(words $(ETC_ZSH)) zsh file(s) and $(words $(SCHINIT_JOBS)) schinit manifest(s)"
|
||||
|
||||
# The mount points. Created here rather than by init, because a mkdir on a
|
||||
|
|
@ -1856,6 +1825,3 @@ distclean: clean
|
|||
# build output: Alpine's usr/lib/sysctl.d is a directory, and including it
|
||||
# stopped every make with "Is a directory".
|
||||
-include $(shell find $(BUILD) \( -path $(BUILD)/aroot -o -path $(BUILD)/iso -o -path $(BUILD)/ports \) -prune -o -type f -name '*.d' -print 2>/dev/null)
|
||||
|
||||
FORCE:
|
||||
.PHONY: FORCE ldls-r8169-if-present
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
# Which drivers are compiled into the kernel.
|
||||
#
|
||||
# y compiled in, and enabled: it is offered every device it can drive
|
||||
# n not compiled in: the code is not linked and the kernel never knows it
|
||||
#
|
||||
# Everything is y unless it says otherwise. Change a line, or override one for
|
||||
# a single build:
|
||||
#
|
||||
# make DRV_E1000=n DRV_NVME=n
|
||||
#
|
||||
# A changed value rebuilds only kernel/drivers/registry.o and the link.
|
||||
#
|
||||
# These are the drivers that can be left out cleanly: nothing else in the kernel
|
||||
# calls them, they are only offered a device by the registry
|
||||
# (kernel/drivers/registry.c). The others cannot be, because the rest of the
|
||||
# kernel calls into them directly, and are not listed:
|
||||
#
|
||||
# vga_fb the boot framebuffer: the console and the crash screen draw on it
|
||||
# xhci, usb core, usb hid / storage / hub
|
||||
# the keyboard and the root disk can arrive over USB, bio.c and
|
||||
# the hotplug thread call in, and so does the I2C-HID touchpad
|
||||
# PS/2, IDE, the 16550 UART
|
||||
# fixed-address legacy devices (kernel/dev/)
|
||||
#
|
||||
# Linux's own drivers, run in a process by ldlsd, are not here: they are files in
|
||||
# the image (make ldls-r8169), not code in the kernel.
|
||||
|
||||
# --- display --------------------------------------------------------------
|
||||
DRV_VGA_PCI = y # the stdvga/Bochs card (the framebuffer driver stays regardless)
|
||||
DRV_VIRTIO_GPU = y # QEMU's virtio-gpu: mode setting and an explicit flush
|
||||
|
||||
# --- network ----------------------------------------------------------------
|
||||
DRV_E1000 = y # Intel 8254x and 8257x
|
||||
DRV_RTL8139 = y # Realtek 8139 (the one Realtek part QEMU emulates)
|
||||
# The native RTL8168/8111 driver. Off by default because the laptop's NIC is
|
||||
# driven by Linux's r8169 under LDLS (etc/schinit/ldls-r8169.job), and a driver
|
||||
# here would claim the device first. Turn it on for a machine without that job.
|
||||
DRV_R8169 = n
|
||||
|
||||
# --- storage ----------------------------------------------------------------
|
||||
DRV_AHCI = y # SATA
|
||||
DRV_NVME = y # NVMe SSDs
|
||||
|
||||
# --- audio ------------------------------------------------------------------
|
||||
DRV_AC97 = y # Intel AC'97 (QEMU's and old boards')
|
||||
|
|
@ -40,12 +40,11 @@ the real program is for.
|
|||
## The four files
|
||||
|
||||
- **`/root/.xserverrc`** starts `X` on the VT `startx` was started from (startx works that
|
||||
out only when `uname -s` says Linux, and SchOS's says SchIFT). It used to add **`-dumbSched`**,
|
||||
Xorg's switch for reading input on the main loop, because Xorg normally reads input on a
|
||||
thread of its own and, when SchOS had no threads, the server crashed the first time a client
|
||||
disconnected, in `pthread_join` on a thread that was never made. Threads exist now and the switch
|
||||
is gone: under QEMU, X starts with Window Maker, `xclock` and `xeyes` connect and disconnect, an
|
||||
`xterm` runs and exits, and the server stays up.
|
||||
out only when `uname -s` says Linux, and SchOS's says SchIFT) with **`-dumbSched`**. Xorg
|
||||
normally reads input on a thread of its own; when SchOS had no threads the server crashed
|
||||
the first time a client disconnected, in `pthread_join` on a thread that was never made, and
|
||||
`-dumbSched` is Xorg's own switch for input on the main loop. Threads exist now; the switch
|
||||
is still on, and nobody has run the server without it since.
|
||||
- **`/root/.xinitrc`** is `exec wmaker`. Without it xinit falls back to twm and an xterm, which
|
||||
are not in the image.
|
||||
- **`/etc/X11/xorg.conf.d/10-schos.conf`** names the input devices. Alpine's Xorg asks udev for
|
||||
|
|
|
|||
|
|
@ -9,17 +9,6 @@ Drivers that live in a process rather than in the kernel are described below
|
|||
|
||||
---
|
||||
|
||||
## Which drivers are compiled in
|
||||
|
||||
`config/drivers.conf` lists the drivers that can be left out of a kernel, `y` (compiled in and offered every device it can
|
||||
drive) or `n` (not linked at all), all `y` unless a line says otherwise — the one exception is the native `r8169`, `n`
|
||||
because Linux's runs in its place under LDLS. Override one for a build with `make DRV_E1000=n DRV_NVME=n`. A changed
|
||||
choice rebuilds only `registry.o` and the link. The list is short on purpose: a driver is optional only if nothing else in
|
||||
the kernel calls it (display: `vga_pci`, `virtio_gpu`; network: `e1000`, `rtl8139`, `r8169`; storage: `ahci`, `nvme`;
|
||||
audio: `ac97`). `vga_fb`, the USB stack and the legacy PS/2, IDE and UART devices are always there, because the console, the
|
||||
keyboard and the root disk can depend on them. A kernel with every optional driver off builds and links; whether such a
|
||||
kernel is useful on any particular machine is the person who turned them off to say.
|
||||
|
||||
## What stays in the kernel, and what may leave
|
||||
|
||||
"Hybrid" is used to mean everything from "a monolith with a nice device model" to
|
||||
|
|
|
|||
|
|
@ -61,10 +61,6 @@ ours.
|
|||
|
||||
2. Declare it in `kernel/drivers/registry.c` and add it to the array.
|
||||
3. Add the object to `KERN_DRIVERS` in the `Makefile`.
|
||||
3½. If nothing else in the kernel calls it, make it optional: a `DRV_<NAME>` line in
|
||||
`config/drivers.conf`, the name in `DRV_LIST` in the Makefile, the object behind
|
||||
`$(filter y,$(DRV_<NAME>))`, and an `#ifdef CONFIG_DRV_<NAME>` around its line in `registry.c`.
|
||||
A driver other code calls (`vga_fb`, the USB stack) cannot be optional.
|
||||
4. Fill in the **class vtable** for what it is, and point `.ops` at it. That is
|
||||
the whole of what the rest of the kernel sees:
|
||||
|
||||
|
|
@ -117,7 +113,7 @@ That is data; the logic stays ours.
|
|||
- [ ] One directory under `kernel/drivers/<class>/<name>/`
|
||||
- [ ] Exports a `struct pci_driver` or `struct usb_driver`
|
||||
- [ ] Declared in `kernel/drivers/registry.c` **and** added to its array
|
||||
- [ ] Object added to `KERN_DRIVERS` in the `Makefile`, and an option in `config/drivers.conf` if it can be left out
|
||||
- [ ] Object added to `KERN_DRIVERS` in the `Makefile`
|
||||
- [ ] Class vtable filled in and `.ops` pointed at it
|
||||
- [ ] `.attached` implemented if it can drive more than one card
|
||||
- [ ] `devclass` set, if it is a USB driver
|
||||
|
|
|
|||
|
|
@ -17,9 +17,6 @@ hundred megabytes, kept in `dist/`) and compiles Xorg's dependencies not at all:
|
|||
packages are Alpine's binaries, pinned in `ports/alpine/world.lock`. See
|
||||
[packages](../architecture/packages.md).
|
||||
|
||||
Which drivers go into the kernel is `config/drivers.conf` (all of the optional ones by default);
|
||||
`make DRV_E1000=n` leaves one out for a build. See [devices](../architecture/devices.md).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
| Need | Why | Windows | Linux | macOS | BSD |
|
||||
|
|
|
|||
|
|
@ -12,10 +12,9 @@
|
|||
// a driver silently dropped by the linker looks exactly like one that was
|
||||
// never written. At this size, being able to read the list wins.
|
||||
//
|
||||
// To add a driver: write kernel/drivers/<class>/<name>/<name>.c exporting a
|
||||
// struct pci_driver, declare it here, add it to the array and to the Makefile's
|
||||
// KERN_DRIVERS -- and, if nothing else in the kernel calls it, give it a
|
||||
// DRV_<NAME> option in config/drivers.conf so it can be left out.
|
||||
// To add a driver: write kernel/drivers/<name>.c exporting a struct
|
||||
// pci_driver, declare it here, and add it to the array and to the Makefile's
|
||||
// KERN_DRIVERS.
|
||||
|
||||
#include "core/types.h"
|
||||
#include "core/defs.h"
|
||||
|
|
@ -29,34 +28,14 @@
|
|||
#include "dev/usb.h"
|
||||
#include "dev/device.h"
|
||||
|
||||
// Which of these exist in this kernel is config/drivers.conf: the Makefile
|
||||
// leaves a disabled driver's object out and defines CONFIG_DRV_<NAME> for the
|
||||
// ones it keeps. The ones with no option (xHCI) are always here.
|
||||
#ifdef CONFIG_DRV_VGA_PCI
|
||||
extern const struct pci_driver vga_pci_driver;
|
||||
#endif
|
||||
extern const struct pci_driver xhci_driver;
|
||||
#ifdef CONFIG_DRV_VIRTIO_GPU
|
||||
extern const struct pci_driver virtio_gpu_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_DRV_E1000
|
||||
extern const struct pci_driver e1000_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_DRV_AC97
|
||||
extern const struct pci_driver ac97_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_DRV_RTL8139
|
||||
extern const struct pci_driver rtl8139_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_DRV_R8169
|
||||
extern const struct pci_driver r8169_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_DRV_AHCI
|
||||
extern const struct pci_driver ahci_driver;
|
||||
#endif
|
||||
#ifdef CONFIG_DRV_NVME
|
||||
extern const struct pci_driver nvme_driver;
|
||||
#endif
|
||||
|
||||
// Order matters here in one respect: virtio-gpu is offered the bus before the
|
||||
// VBE framebuffer driver, so that on a machine with both, the device with real
|
||||
|
|
@ -64,42 +43,23 @@ extern const struct pci_driver nvme_driver;
|
|||
// claims the stdvga card underneath, which is what the boot splash and the
|
||||
// text console are drawn on.
|
||||
static const struct pci_driver *drivers[] = {
|
||||
#ifdef CONFIG_DRV_VIRTIO_GPU
|
||||
&virtio_gpu_driver,
|
||||
#endif
|
||||
#ifdef CONFIG_DRV_VGA_PCI
|
||||
&vga_pci_driver,
|
||||
#endif
|
||||
#ifdef CONFIG_DRV_E1000
|
||||
&e1000_driver,
|
||||
#endif
|
||||
// The RTL8168 is driven by Linux's own r8169 through LDLS
|
||||
// (etc/schinit/ldls-r8169.job), which a kernel driver here would claim
|
||||
// first -- so DRV_R8169 is off by default. The native driver stays in the
|
||||
// tree as the fallback for a machine without that job.
|
||||
#ifdef CONFIG_DRV_R8169
|
||||
&r8169_driver,
|
||||
#endif
|
||||
#ifdef CONFIG_DRV_RTL8139
|
||||
// &r8169_driver -- the RTL8168 is driven by Linux's own r8169 through
|
||||
// LDLS (etc/schinit/ldls-r8169.job), which a kernel driver here would
|
||||
// claim first. The native driver stays in the tree as the fallback.
|
||||
&rtl8139_driver,
|
||||
#endif
|
||||
&xhci_driver,
|
||||
#ifdef CONFIG_DRV_AHCI
|
||||
&ahci_driver,
|
||||
#endif
|
||||
#ifdef CONFIG_DRV_NVME
|
||||
&nvme_driver,
|
||||
#endif
|
||||
#ifdef CONFIG_DRV_AC97
|
||||
&ac97_driver,
|
||||
#endif
|
||||
0, // keeps the array non-empty when everything optional is off
|
||||
};
|
||||
|
||||
void
|
||||
pci_bind_all(void)
|
||||
{
|
||||
for (unsigned i = 0; drivers[i]; i++)
|
||||
for (unsigned i = 0; i < sizeof(drivers) / sizeof(drivers[0]); i++)
|
||||
pci_bind(drivers[i]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -97,12 +97,12 @@ mkdir -p "$P/etc/profile.d"
|
|||
grep -v '^export \(PATH\|HOME\|TERM\)=' "$P/etc/profile" > "$P/etc/profile.d/schos.sh"
|
||||
rm -f "$P/etc/profile"
|
||||
|
||||
# How startx starts the X server for root: Alpine's xserverrc. (It used to add
|
||||
# -dumbSched, Xorg's switch for reading input on the main loop, because when SchOS
|
||||
# had no threads the server crashed on its way out the first time a client
|
||||
# disconnected, in pthread_join on a thread that was never made. SchOS has threads
|
||||
# now; X was run without the switch under QEMU -- clients connecting and
|
||||
# disconnecting, an xterm starting and exiting -- and it stays up.) The file is
|
||||
# How startx starts the X server for root: Alpine's xserverrc, plus
|
||||
# -dumbSched. Xorg reads input on a thread of its own; when SchOS had no threads
|
||||
# the server crashed on its way out the first time a client disconnected, in
|
||||
# pthread_join on a thread that was never made. -dumbSched is Xorg's own switch
|
||||
# for input on the main loop. SchOS has threads now (clone, futex), so this may
|
||||
# no longer be needed -- it has simply not been tried without it. The file is
|
||||
# root's own rather than /etc/X11/xinit/xserverrc, which belongs to the xinit
|
||||
# package.
|
||||
mkdir -p "$P/root"
|
||||
|
|
@ -111,7 +111,7 @@ cat > "$P/root/.xserverrc" <<'XEOF'
|
|||
# The VT X runs on is the one startx was started from. startx works that out
|
||||
# only when `uname -s` says Linux, and SchOS's says SchIFT.
|
||||
vt=$(tty | sed -n 's|^/dev/tty\([0-9][0-9]*\)$|vt\1|p')
|
||||
exec /usr/bin/X -nolisten tcp $vt "$@"
|
||||
exec /usr/bin/X -nolisten tcp -dumbSched $vt "$@"
|
||||
XEOF
|
||||
|
||||
# What startx runs inside it: Window Maker, which world installs. Without this
|
||||
|
|
|
|||
Loading…
Reference in a new issue