Skip to content

feat(arm64): init system, proper heap allocator, TTBR0 and ERET fixes#165

Merged
ryanbreen merged 1 commit intomainfrom
feat/arm64-dup2
Feb 6, 2026
Merged

feat(arm64): init system, proper heap allocator, TTBR0 and ERET fixes#165
ryanbreen merged 1 commit intomainfrom
feat/arm64-dup2

Conversation

@ryanbreen
Copy link
Owner

Summary

  • Init system: New /sbin/init binary that spawns telnetd and init_shell, with zombie reaping and service respawn
  • Heap allocator: Replace bump allocator with linked_list_allocator — the bump allocator never reclaimed freed memory, causing OOM within seconds of boot
  • Box::leak removal: Remove unnecessary Box::leak of ELF data and program names in exec syscall paths (ARM64 + x86_64)
  • TTBR0 restoration: Fix stale page table after blocking syscall resume and after exec, preventing instruction abort permission faults
  • ERET register safety: Use per-CPU scratch field to save/restore registers across SP switches in syscall and IRQ return paths

Test plan

  • ARM64 boot test passes (init → telnetd + init_shell → breenix> prompt)
  • 30-second ARM64 stability test — no OOM, no instruction aborts
  • x86_64 build clean (zero warnings)
  • x86_64 boot test passes (1/1)

🤖 Generated with Claude Code

…0 on syscall resume

Implement ARM64 init system (/sbin/init) that spawns telnetd and init_shell,
replacing direct init_shell boot. Fix three critical bugs discovered during
testing:

1. Heap exhaustion (OOM): Replace bump allocator with linked_list_allocator.
   The bump allocator never reclaimed freed memory, exhausting the 32MB heap
   within seconds of boot as temporary Vec/String/BTreeMap allocations
   permanently consumed space. Also remove unnecessary Box::leak calls in
   exec syscall paths (ARM64 and x86_64) that leaked entire ELF binaries.

2. TTBR0 stale after blocking syscall: When a userspace thread blocked in
   a syscall (e.g., read() on stdin) was context-switched back in,
   setup_kernel_thread_return_arm64 did not restore the process's page table.
   TTBR0 retained the previously-running process's value, causing instruction
   abort permission faults when the thread returned to EL0 with the wrong
   address space.

3. Register clobber fixes in ERET paths: Use per-CPU eret_scratch field to
   save/restore registers across SP switches in both syscall and IRQ return
   paths, preventing x0/x1 corruption (syscall) and x16 corruption (IRQ).

4. TTBR0 restoration after exec: Update saved_process_cr3 after exec switches
   to the new program's page table, preventing the assembly ERET path from
   restoring the old (freed) page table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@ryanbreen ryanbreen merged commit a540643 into main Feb 6, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant