u/vinothsparrow

▲ 0 r/osdev

My dual-arch AI OS boots on QEMU, VirtualBox and real UEFI hardware. Three bugs that cost me the most.

I've been writing an OS from scratch in Rust for the last few months. x86_64 and

aarch64 from one codebase, no_std, no libc, no POSIX layer. Boots on QEMU,

VirtualBox, real UEFI hardware, and on a Mac mini M2 over m1n1.

What's in it so far: preemptive scheduler, MMU and frame allocator, capabilities

and IPC, SMP on both arches, virtio/NVMe/AHCI block, GPT/MBR with FAT, ext4 and

exFAT, xHCI + HID (keyboard and mouse, driven off the report descriptor), a

TCP/IP stack with TLS, a framebuffer compositor with split panes and tabs, and

in-kernel PNG/JPEG/MP3/AAC/H.264/H.265/VP9 decoders.

Three bugs that cost the most, in case they save anyone else the time.

  1. aarch64 preemption worked exactly once per boot. The x86 context switch saved

RFLAGS. The aarch64 one saved x19-x30 and d8-d15 and left DAIF alone, as if it

were a global CPU property. IRQs are masked on exception entry, so the first

preemptive switch out of the timer handler handed the incoming task a masked DAIF

that nothing ever cleared, and from then on the machine ran with interrupts off.

The interactive shell hid it completely because it yields constantly. I only

found it the day I got the unit suite running on aarch64 — it had been x86-only,

so about 2,400 tests gated every x86 change and nothing gated ARM beyond "it

compiles."

  1. X_DSDT is at FADT offset 140, not 148. I had 148, which is where the PM1a

event block's GAS starts, so I was reading space|width|offset|access|address_lo32

reinterpreted as a u64 — a big plausible number that went straight past my

sanity check. The DSDT was therefore unfindable on every machine with a modern

FADT, so the whole AML layer silently did nothing: no _S5 poweroff, no battery,

no I2C touchpad. No error anywhere, because "no DSDT" is a legitimate state.

  1. The same image booted under HVF and died under TCG. QEMU virt puts its 64-bit

PCIe window at exactly 512 GiB, and my identity map was a 39-bit VA — one L1 of

512 1 GiB blocks — so it couldn't describe 0x8000000000 at all, and the mapping

function just returned without saying anything. A driver then wrote to the

unmapped address it got back. TCG gives the guest enough physical space for

firmware to put a BAR up there and HVF doesn't, so it genuinely did work on my

machine.

It runs an AI agent as the unit of execution instead of loading binaries, which

is why I started it, but the OS underneath is where the time went.

Not stable, research OS, run it in a VM. Apache-2.0, prebuilt images for both

arches.

https://github.com/chittios/chitti

u/vinothsparrow — 5 days ago
▲ 8 r/OSdevAI+1 crossposts

ChittiOS: a no_std OS in Rust where the unit of execution is an agent, not a binary

I've been writing an OS in Rust for the last few months — no_std, one codebase
for x86_64 and aarch64, no libc and no POSIX layer. The unusual part is what it
runs: instead of loading a binary it runs an LLM agent, and every effect the
model asks for goes through a capability-checked ABI in the kernel, so it can
plan anything and only do what it was granted.

The Rust-specific parts that took the longest:

- No ring, since it won't build bare-metal. TLS 1.3 certificate verification is
  hand-rolled on x509-cert + p256/p384, with RSA PKCS#1 v1.5 and PSS on
  crypto-bigint. The crypto ecosystem assumes std in more places than the
  feature flags suggest.

- +strict-align silently scalarizes NEON. The aarch64 target needs it for the
  pre-MMU boot window and device MMIO, and under it LLVM lowers every unaligned
  vector load — intrinsics and auto-vectorized loops alike — into about 25 byte
  ops with a stack spill. The binary still contains fmla, so it looks correct
  until you disassemble the loads. Hot kernels do their memory access through
  inline asm now, and I check with objdump rather than trusting the source.

- The decoders (PNG/JPEG, MP3/AAC, H.264/H.265/VP9) are in-kernel and no_std.
  The untrusted ones run in ring 3 as a userspace tenant that mounts the
  kernel's own source with #[path], so porting one can't fork it into two
  implementations that drift.

Research OS — not stable, run it in a VM. Apache-2.0, prebuilt images for both
arches in Releases

https://github.com/chittios/chitti
u/vinothsparrow — 6 days ago