# NaOS v0.2.0 (in development)

A usable x86_64 UEFI operating system built **from scratch (0), in C** — no GRUB, no Limine, no gnu-efi, no prebuilt bootloader or kernel. See [IDEA.md](IDEA.md) for the full vision, tree, flow and workflow.

Status: **v0.2.0 in development** — everything in v0.1.0, plus a TCP server (`listen`/`accept`, serve files over HTTP), NaOS-FS writes (`file-system write`/`delete`), an own TLS 1.2 client (`get-page-tls`, suite `ECDHE_RSA_AES_128_GCM_SHA256`), disk install (`show-drives`, `install-system`), and file seek (`SYS_SEEK`). `BOOTX64.EFI` loads `KERNEL.ELF`, and the kernel runs
a `NaOS>` shell on a black GOP console with PS/2 and USB-HID keyboard input
(`help show-version about-system clear-screen print-text show-memory run-tests force-crash show-files open-folder read-file make-folder make-file copy-file move-file rename-file edit-file delete-file run-program show-tasks stop-task show-time show-date show-uptime play-beep show-pci show-settings set-font find-keyboard show-nvme show-drives install-system file-system show-network get-address find-address get-page get-page-tls serve-file system-update ping-address reboot-system shut-down`), own paging (PML4),
a `kmalloc`/`kfree` heap, an AHCI/NVMe/ATA+FAT32 filesystem (read+write, long filenames), and preemptive multitasking
(ring-3 tasks with private address spaces, syscalls, `fork()` with copy-on-write, round-robin scheduler,
disk-loaded ELF programs with file I/O (`open`/`read`/`write`/`close`/`seek`, stdout on fd 1)). Command output redirects with `<cmd> > <file>`, and `/SETTINGS.TXT`
styles the prompt and console colors. Networking (E1000 or virtio-net: ARP + ICMP ping, UDP sockets, DHCP client,
TCP client with HTTP `fetch`, TCP server with `serve`, own TLS 1.2 client with `get-page-tls`, default 10.0.2.15/24)
works under QEMU user-net out of the box (q35 defaults to an E1000 on user-net, same as `make run`),
then `show-network`, `get-address`, `ping-address 10.0.2.2`, and `get-page 10.0.2.2 8099 /path` (needs an HTTP server on the host).

## Download & website

* **Bootable ISO:** build it here with `make iso` (no v0.2.0 release yet — grab stable [NaOS.v0.1.0.iso](https://github.com/nacer0s/NaOS/releases/download/v0.1.0/NaOS.v0.1.0.iso) meanwhile). CD/USB boot runs a **live RAM session** (files work, writes vanish on reboot); persistence needs a SATA/NVMe/IDE disk.
* **Raw disk image:** build it here with `make esp` (or grab stable [NaOS.v0.1.0.img](https://github.com/nacer0s/NaOS/releases/download/v0.1.0/NaOS.v0.1.0.img)) — attach as a VM hard disk for a boot **with files**, or `dd` to USB.
* **Websites:** [this release page](https://naos.nacer0s.com/versions/v0.2.0/) · [project home](https://naos.nacer0s.com/) · [code viewer](https://naos.nacer0s.com/home/browse/) (read every file online, no install).

## Requirements

| Tool | Version verified | Purpose |
|---|---|---|
| QEMU + OVMF (`edk2-x86_64-code.fd`) | 11.1.0 | Emulator + UEFI firmware |
| NASM | 3.02 | `kernel/entry.asm`, ISR stubs |
| GNU Make | 4.4.1 | Build |
| `x86_64-w64-mingw32-gcc` | 16.2.0 | Bootloader `BOOTX64.EFI` (PE+, correct tool for EFI) |
| `x86_64-elf-gcc` + `ld` | 16.2.0 / 2.47 (`/opt/cross`, Windows) · 7.1.0 / 2.28 (`/opt/cross`, Arch) — both verified | Kernel `KERNEL.ELF` (ELF64) |
| mtools (`mformat/mcopy`) + dosfstools | 4.0.49 / 4.2 | Build FAT ESP image |
| Python + Pillow + DejaVu Sans Mono | 3.14.8 / 12.3.0 / 2.37 | Rasterize console font at build time |
| xorriso | 1.5.8.2-1 | Build bootable ISO (`make iso`) |
| Python | 3.14.8 | Helper scripts |

All on Windows + **MSYS2 UCRT64**. QEMU installed via `winget`, rest via `pacman` + cross-compiler built from source per https://wiki.osdev.org/GCC_Cross-Compiler.
Also verified on **Arch Linux** (QEMU 11.1.2 + `edk2-ovmf`, system mingw/nasm/mtools/xorriso, existing `/opt/cross` 7.1.0 toolchain) — `Makefile`/`check.sh` auto-detect Arch OVMF + font paths, and the link scripts pin explicit `PHDRS` so ld 2.28 and 2.47 agree.

## One-time setup (MSYS2 UCRT64)

```bash
pacman -Syu
pacman -S --needed base-devel mingw-w64-ucrt-x86_64-toolchain
# at "Enter a selection (default=all):" just press Enter
pacman -S --needed nasm make python dosfstools mingw-w64-ucrt-x86_64-mtools mingw-w64-ucrt-x86_64-nasm
pacman -S --needed mingw-w64-ucrt-x86_64-python-pillow mingw-w64-ucrt-x86_64-ttf-dejavu
pacman -S --needed xorriso   # only for `make iso` (real-hardware image)

# cross compiler (already built 2026-10-09 → /opt/cross, ~30min; reference: tools/build-cross.sh)
# binutils-2.47 + gcc-16.2.0, --target=x86_64-elf --prefix=/opt/cross --without-headers
echo 'export PATH=/opt/cross/bin:$PATH' >> ~/.bashrc
export PATH=/opt/cross/bin:$PATH
x86_64-elf-gcc --version
```

## Quickstart (every session)

```bash
export PATH=/opt/cross/bin:$PATH
./tools/check.sh     # verify every tool + OVMF firmware
make all             # build/BOOTX64.EFI + build/KERNEL.ELF
make esp             # build/NaOS.v0.2.0.img — 64M FAT with \EFI\BOOT\BOOTX64.EFI + \NaOS\KERNEL.ELF
make run             # QEMU + OVMF, boots to kernel banner
make clean           # full rebuild (also needed automatically via header deps)
```

QEMU command used by `make run`:

```
qemu-system-x86_64 -machine q35 -drive if=pflash,format=raw,unit=0,file="<...>/edk2-x86_64-code.fd",readonly=on -drive format=raw,file=build/NaOS.v0.2.0.img -m 256M -serial stdio
```

`-machine q35` is required: stock QEMU boots the `pc` machine, whose OVMF drops to the EFI shell instead of auto-booting us.

If OVMF ever drops you to its shell (busy host can lose the disk-discovery race), boot by hand — the disk is fine, only auto-boot missed it:
```
FS0:
cd EFI\BOOT
BOOTX64.EFI
```

## ISO + real hardware

```bash
make iso      # build/NaOS.v0.2.0.iso — El Torito UEFI boot image (needs xorriso)
make run-iso  # boot the ISO itself in QEMU (-cdrom) to verify it
```

Note: a CD/USB-booted system runs a **live RAM session** — `BOOTX64.EFI` copies the whole boot volume into memory via Block I/O and the kernel mounts the copy, so `list`/`read`/`run`/`edit` all work with files. Writes live in RAM and vanish on reboot (give the VM ≥256MB). Full persistence needs a SATA/NVMe/IDE disk (AHCI → NVMe → probed ATA → RAM copy, in that order).

VirtualBox: create the VM as type **Other/Unknown (64-bit)** (a 32-bit type disables Long Mode and no 64-bit OS can boot), enable EFI (Settings → System → Motherboard → **Enable EFI**), attach the ISO as optical drive — BIOS mode reports "no bootable medium" for this UEFI-only image. QEMU needs OVMF (`-drive if=pflash,...,file=edk2-x86_64-code.fd`), same as `make run-iso`.

Flash to USB (Windows: [Rufus](https://rufus.ie) in **DD mode**; Linux: `dd if=build/NaOS.v0.2.0.iso of=/dev/sdX bs=4M status=progress`), then boot the stick as a **UEFI** device.

You must know before trying:

* **Secure Boot OFF.** Our `BOOTX64.EFI` is unsigned (no Microsoft keys); enable setup mode or disable Secure Boot in firmware.
* **UEFI only, 64-bit.** No legacy BIOS/CSM support, by design.
* **Honest hardware limits (v0.2.0):** the disk driver speaks AHCI first (port 0, polling DMA), then NVMe (one I/O queue pair, polled, 512B namespaces), with a legacy IDE PIO fallback; keyboards work over PS/2 and USB HID (XHCI, polled). Any SATA/NVMe disk plus a PS/2 or USB keyboard for input covers most machines.
* Writing files on a real disk install writes that disk's FAT partition — back it up first. (Live USB/CD sessions keep writes in RAM and lose them on reboot.)

## Numbers (all verified on QEMU q35 unless noted)

| What | Value |
|---|---|
| Shell commands | 43 (see `help`; + `PgUp/PgDn` keys, `> file` redirect with 8KB window) |
| Syscalls | 11 via `int 0x80`: 0 exit, 1 print, 2 yield, 3 getpid, 4 sleep, 5 fork, 6 open, 7 read, 8 write, 9 close, 10 seek |
| Tasks / scheduler | 16 slots · 50ms quantum @100Hz · 8 fds per task (opens from 3, 2048B per call, 4KB write buffer) |
| Memory | kernel @`0x100000` · programs @`0x40100000` · PML4 identity 0–1G · ~52K free pages/256M |
| Console | 12x24 + 8x16 cells, scales 1–4 · 256-line ring · history 16 · cursor ~1Hz blink |
| Storage | AHCI port 0 → NVMe (admin depth 64 + IO depth 32, one queue pair) → ATA PIO (LBA0 signature probe) → live RAM copy of the boot volume |
| Network | E1000 + virtio-net (legacy 0.9x, polled) · ARP/ICMP/UDP(68→67 DHCP)/TCP client+server(1460 MSS, 4KB window) · DNS:53 · default 10.0.2.15/24 via 10.0.2.2 |
| Filesystems | FAT32 R/W (LFN reads + LFN-aware writes) · NaOS-FS v1 read/write (512B blocks, 16×32B dirents, depth 8, 128KB image cap) |
| Artifacts | BOOTX64.EFI ~17 KB · KERNEL.ELF ~203 KB · DATA.NAFS 94,720 B · ESP 64MiB · ISO ~64.6 MiB |

## Layout

```
boot/uefi/    own uefi.h + efi_main + ELF/GOP/file/exit-services loader (no gnu-efi)
common/       bootinfo handoff, serial, cstring, io — shared, freestanding
kernel/       entry.asm (MS→SysV RCX shim) + link.ld + kmain + fb/kprintf/font
progs/        user programs (ELF binaries for ring 3) + crt0 + user link script
tools/        check.sh, mkesp.sh, mkiso.sh, mknafs.py, font_render.py, build-cross.sh
build/        generated, gitignored (binaries, ESP image, ISO, font header)
index.html    v0.2.0 website (vanilla HTML/CSS/JS, offline-safe)
```

## Rules

* **Zero prebuilt OS code.** Host toolchain is allowed; OS code is always ours.
* Log **every** change in [CHANGELOG.md](CHANGELOG.md).
* Version stamp: `VERSION` in the Makefile → `build/version.h`; `version` prints it.
* License: [LICENCE.md](../../LICENCE.md) (custom project licence — free for personal/learning use, no commercial use, no re-hosting as your own, credit us everywhere).

## Author — nacer0s

NaOS v0.2.0 is designed, written and tested by **nacer0s**: GitHub <https://github.com/nacer0s> · Web <https://nacer0s.com> · X <https://x.com/nacer0s> · Instagram <https://instagram.com/nacer0s> · TikTok <https://tiktok.com/@nacer0s> · Telegram <https://t.me/nacer0s> · Threads @nacer0s · Mortakaz @nacer0s.
