diff --git a/.github/scripts/check_boot.py b/.github/scripts/check_boot.py index d6e7122..162094a 100644 --- a/.github/scripts/check_boot.py +++ b/.github/scripts/check_boot.py @@ -18,7 +18,7 @@ import sys import termios import time -IMAGE = sys.argv[1] if len(sys.argv) > 1 else "os.img" +IMAGE = sys.argv[1] if len(sys.argv) > 1 else "nadir.img" NEEDLE = b"64-bit" BOOT_WAIT_S = 8 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 079be16..6788b3d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,6 @@ # Nadir Kernel CI. Runs on every pull request and every push to main. # -# Builds os.img with make, verifies the image, then boots it headless in +# Builds nadir.img with make, verifies the image, then boots it headless in # QEMU and asserts the kernel's welcome message reaches the screen. name: CI @@ -29,16 +29,20 @@ jobs: run: make - name: Verify image + # Every check prints what it saw: a silent bare `test` once hid a + # failure here, so each assertion reports and names its own failure. run: | set -euo pipefail - test -f os.img - size=$(stat -c %s os.img) - test "$size" -ge 1024 - test $(( (size - 512) % 512 )) -eq 0 - sig=$(dd if=os.img bs=1 skip=510 count=2 2>/dev/null | od -A n -t x1 | tr -d ' \n') - test "$sig" = "55aa" || { echo "missing 0xAA55 boot signature"; exit 1; } - grep -q "Nadir" os.img || { echo "kernel payload missing from os.img"; exit 1; } - echo "os.img: $size bytes, boot signature and payload present" + ls -l nadir.img + size=$(stat -c %s nadir.img) + echo "image size: $size bytes" + test "$size" -ge 1024 || { echo "FAIL: image smaller than sector+kernel minimum"; exit 1; } + test $(( (size - 512) % 512 )) -eq 0 || { echo "FAIL: kernel part is not sector-aligned"; exit 1; } + sig=$(dd if=nadir.img bs=1 skip=510 count=2 2>/dev/null | od -A n -t x1 | tr -d ' \n') + echo "boot signature: $sig" + test "$sig" = "55aa" || { echo "FAIL: missing 0xAA55 boot signature"; exit 1; } + grep -q "Nadir" nadir.img || { echo "FAIL: kernel payload missing from image"; exit 1; } + echo "OK: nadir.img valid, boot signature and payload present" - name: Boot and check welcome message in QEMU - run: python3 .github/scripts/check_boot.py os.img + run: python3 .github/scripts/check_boot.py nadir.img diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a85bb64..f8451b8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,7 +36,7 @@ Please stick to the following rules if you plan to use AI in your contributions: Build from the repository root. See the [README](README.md) for prerequisites and troubleshooting: ``` -make # builds os.img (boot sector + kernel) +make # builds nadir.img (boot sector + kernel) make run # boots it in QEMU ``` diff --git a/README.md b/README.md index b063a60..da1e34f 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ I can only recommend using Linux distribution, but the Windows Subsystem for Lin From the repository root: ```bash -make # builds os.img +make # builds nadir.img make run # boots it in QEMU ``` @@ -73,7 +73,7 @@ Notes: |---|---| | `Boot failed: not a bootable disk` | The first 512 bytes of `nadir.img` are not a valid boot sector (they must end with the `0xAA55` signature). Re-run `make` and check it completes without errors. | | Black screen / blinking cursor | The boot sector only speaks legacy BIOS (`int 0x10` text mode). This works out of the box with QEMU's default SeaBIOS firmware but will not boot under UEFI-only firmware (or UEFI-only real hardware) unless legacy/CSM boot is enabled. | -| QEMU reboots in a loop after `entering protected mode` (or before any C output) | A triple fault in the boot chain: the CPU crashed with no IDT installed and reset itself. Boot with `qemu-system-x86_64 -fda os.img -d int -no-reboot` and read the fault (`v=...`) plus registers from the log. | +| QEMU reboots in a loop after `entering protected mode` (or before any C output) | A triple fault in the boot chain: the CPU crashed with no IDT installed and reset itself. Boot with `qemu-system-x86_64 -fda nadir.img -d int -no-reboot` and read the fault (`v=...`) plus registers from the log. | | No window appears under WSL2 | Use the `-display curses` variant above. It should work in any terminal. | ## How booting works