Skip to content

OS-DEV v1908 — real CSS box model, USB 3.0 block devices, I/O APIC, and a test suite that catches things

Choose a tag to compare

@milescoviello milescoviello released this 30 Jul 22:55
· 689 commits to main since this release

A from-scratch x86_64 operating system — kernel, SMP scheduler, its own TCP/IP
stack + TLS 1.3, a JavaScript engine, a sandboxed ring-3 web browser, a
crash-consistent journaling filesystem, and a graphical desktop — all written
from scratch. 20 milestones past v1888 (M1889 → M1908).

This release is mostly about making the browser's box model real and
making the test suite actually able to catch things. Several of the bugs
below had been sitting in a fully green test run.

Try it now

Download os-dev-tryit.zip, unzip, and follow RUN_ME.md for a one-line
qemu-system-x86_64 command (only QEMU required) — boots to the graphical
desktop in about 1.5 seconds and runs a live HTTP + HTTPS-over-TLS-1.3 fetch
with real certificate-chain validation over the from-scratch network stack. A
standalone BOOTX64.EFI is included to boot real hardware over UEFI.

Highlights since v1888

  • USB disks are real block devices on USB 2.0 and 3.0. A disk behind EHCI or
    xHCI used to be enumerated, read once at LBA 0 inside a self-test, and then
    forgotten — no capacity, no arbitrary LBA, no writes, not mountable. Since real
    hardware has no UHCI controller at all, USB storage was effectively unusable
    off QEMU. The Bulk-Only Transport protocol now lives once in a pure,
    host-tested layer instead of three hand-copied transcriptions, and a 64 MiB
    FAT32 filesystem on a USB 3.0 disk mounts and lists its files.

  • A real CSS box model. width, height, min-height, margin:0 auto,
    asymmetric auto margins, horizontal and vertical padding, box-sizing: border-box, margin-bottom, and borders that stroke the border box. Built on
    a new pure layout engine implementing the CSS 2.1 §10.3.3 width constraint and
    §8.3.1 margin collapsing, with 95 mutation-tested known-answer checks.

  • Every live IRQ now runs through the I/O APIC, including the NIC's PCI line
    — which needed level-triggered/active-low routing and the ACPI MADT's
    polarity/trigger flags, both of which were previously being discarded.

  • The test suite can now catch rendering bugs. Three box-model bugs coexisted
    in a passing suite because nothing asserted rendered geometry. There is now a
    colour-keyed framebuffer check (28 assertions) that finds each block's box by
    exact RGB and asserts solved widths, centring, padding insets and border
    enclosure — and it is mutation-tested against the very bugs it exists to catch.

  • ~2,700 previously unasserted lines of POSIX IPC now have 89 in-guest checks
    — message queues (priority ordering), named semaphores (O_CREAT/O_EXCL,
    non-blocking trywait), shared memory (frames genuinely shared, size cap
    enforced), ptys, flock exclusion/sharing/pid-release, inotify filtering,
    eventfd, tmpfs, unix sockets, SysV IPC (all-or-nothing semop, mtype
    selection) and procfs.

Bugs fixed that a green test run had been hiding

  • A permanent-hang race in the PIC→I/O APIC handover. An interrupt arriving
    mid-handover got a PIC EOI instead of a LAPIC one, leaving the vector's
    in-service bit set forever. On the PIT that kills the scheduler's clock
    outright. Proven by widening the window until it reproduced deterministically.
  • TCP was destroying other connections' packets — any frame not matching the
    polling connection's 4-tuple was discarded, including frames owned by another
    live connection, so two concurrent network users starved each other.
  • Two UTF-8 BOM bugs: a BOM-prefixed HTML page was mis-detected as an image
    (a signed-char comparison that could never be true), and then rendered as raw
    markup.
  • A latent EHCI data-toggle desync on short bulk transfers.
  • USB keyboard probing was resetting an already-enumerated mass-storage
    device
    , leaving it registered but dead for the rest of the session.

Known issues

  • httpdtest fails intermittently in a full make check run and the cause is
    unproven. Measurement was repeatedly contaminated by stray QEMU processes
    holding the disk image's write lock, which produces failures indistinguishable
    from real ones. make check is 130/130 green on a clean host.
  • The boot HTTPS self-test can take a very long time after certificate-chain
    validation; the suspect is the bignum CertificateVerify path, which is known
    to be far slower than it should be.
  • float, position, z-index and max-height are not implemented, and
    the reason is architectural rather than effort: a block's painted extent is
    currently its flow advance, so out-of-flow boxes cannot be expressed. The box
    tree that would fix all four exists and is not yet wired in.