This document provides comprehensive information about the PUI PUI Linux codebase for AI assistants working on this project.
PUI PUI Linux is a minimal Linux distribution designed specifically for testing the Apple Virtualization Framework (https://github.com/Code-Hex/vz). The project prioritizes:
- Minimalism: Extremely small kernel and initramfs for fast downloads and testing in CI environments
- Architecture Support: Only aarch64 (arm64) and x86_64 architectures
- Virtualization-First: Built exclusively for virtualized environments using VIRTIO devices
- Tool Version: 1.0.3
- Kernel Version: 6.11.5
- BusyBox Version: 1.36.1
- Dropbear Version: 2024.86
- Socat Version: 1.8.0.1
puipui-linux/
├── .git/ # Git repository metadata
├── .gitignore # Git ignore patterns
├── README.md # User-facing documentation
├── CLAUDE.md # This file
├── puipui-linux-tool # Main build script (Bash)
├── kconfig/ # Kernel configuration files
│ ├── aarch64.config # ARM64 kernel config (defconfig format)
│ └── x86_64.config # x86_64 kernel config (defconfig format)
├── busybox_config/ # BusyBox configuration
│ └── config # BusyBox build configuration
├── fs/ # Initramfs filesystem template
│ ├── init # Init script (runs at boot)
│ ├── alpine-chroot-install # Alpine chroot installer utility
│ ├── etc/ # System configuration files
│ │ ├── inittab # BusyBox init configuration
│ │ ├── passwd # User accounts
│ │ ├── group # Group definitions
│ │ ├── securetty # Secure TTY list
│ │ ├── resolv.conf # DNS configuration
│ │ ├── issue # Login banner
│ │ ├── conf.d/ # Service configurations
│ │ └── init.d/ # Init scripts
│ └── usr/ # User binaries and libraries
└── build-*/ # Build artifacts (gitignored)
├── linux-kernel/ # Kernel build directory
├── busybox/ # BusyBox build directory
├── fs/ # Built filesystem
├── dropbear/ # Dropbear SSH build
├── socat/ # Socat build
├── curl/ # Curl binary download
└── artifact/ # Final build outputs
├── Image.gz (aarch64) or bzImage (x86_64)
└── initramfs.cpio.gz
-
aarch64 (ARM64)
- Kernel output:
arch/arm64/boot/Image.gz - Kernel arch name:
arm64 - Cross-compile prefix:
aarch64-linux-musl-
- Kernel output:
-
x86_64 (AMD64)
- Kernel output:
arch/x86/boot/bzImage - Kernel arch name:
x86 - Cross-compile prefix:
x86_64-linux-musl-
- Kernel output:
- On ARM64 hosts, the build tool downloads musl toolchains from https://github.com/Code-Hex/musl-cross-make-arm64
- On x86_64 hosts, toolchains come from https://musl.cc/
- Native builds use
*-linux-musl-nativedirectories - Cross-compilation uses
*-linux-musl-crossdirectories
The build script is a monolithic Bash script that orchestrates the entire build process.
Usage:
./puipui-linux-tool # Build everything
./puipui-linux-tool -u # Update kernel configs only
./puipui-linux-tool -h # Show help
./puipui-linux-tool -v # Show version-
Download Dependencies (if not present):
- Linux kernel tarball from kernel.org
- BusyBox from busybox.net
- Dropbear from matt.ucc.asn.au
- Socat from dest-unreach.org
- Musl cross-compilation toolchains
-
Build Kernel (
build_kern):- Prepares config for each architecture
- Runs
make olddefconfigto update config - Builds kernel with musl toolchain
- Outputs to
build-{arch}/artifact/
-
Download Curl (
download_curl):- Fetches static curl binaries from moparisthebest/static-curl
- Places in
build-{arch}/curl/
-
Build Initramfs (
build_initramfs):- Copies
fs/template tobuild-{arch}/fs/ - Builds and installs Dropbear SSH server
- Builds and installs Socat
- Installs static curl binary
- Copies CA certificates for HTTPS support
- Builds BusyBox and installs to filesystem
- Creates compressed cpio archive:
initramfs.cpio.gz
- Copies
-
Pack Artifacts (
pack_artifacts):- Creates
puipui_linux_v{version}_{arch}.tar.gz - Contains kernel image and initramfs
- Creates
All build artifacts go into build-{arch}/ directories:
build-aarch64/build-x86_64/
These are gitignored along with downloaded source tarballs.
Features Enabled:
- Networking (TCP/IP stack)
- VIRTIO drivers:
virtio_blk- Block devicesvirtio_console- Console via hvc driversvirtio_fs- Filesystem sharing (virtfs)virtio_vsock- AF_VSOCK socket familyvirtio_gpu- GPU support (recent addition)
- CONFIG_IKCONFIG - Kernel configuration in /proc/config.gz
- CONFIG_NO_HZ - Tickless kernel
- CONFIG_HIGH_RES_TIMERS - High-resolution timers
- CONFIG_CC_OPTIMIZE_FOR_SIZE - Size optimization
- ACPI support (x86_64)
- GPIO support (aarch64 for power events)
Kernel Configuration Management:
- Configs stored as defconfig format in
kconfig/{arch}.config - Use
./puipui-linux-tool -uto update configs - Process:
listnewconfig→oldconfig→savedefconfig - Always use
olddefconfigfor non-interactive updates
Init Script: fs/init
- Written in BusyBox sh
- Runs as PID 1
- Responsibilities:
- Install BusyBox applets (
busybox --install -s) - Mount pseudo-filesystems (proc, sysfs, devtmpfs)
- Setup device nodes with mdev
- Create essential devices (/dev/null, /dev/kmsg, /dev/ptmx)
- Mount devpts for PTY support
- Mount tmpfs for /dev/shm
- Parse kernel command line for parameters
- Setup console devices in /etc/inittab and /etc/securetty
- Set hostname to "localhost"
- Set root password to "passwd"
- Handle
vsock_port=kernel parameter (defaults to 2222) - Execute
/linuxrc(BusyBox init)
- Install BusyBox applets (
Kernel Command Line Parsing:
vsock_port=N- Sets VSOCK_PORT environment variable
Console Setup:
- Automatically detects console devices from kernel
- Dynamically adds getty entries to
/etc/inittab - Updates
/etc/securettyfor root login
BusyBox:
- Provides core Unix utilities
- Configuration in
busybox_config/config - Built statically with musl libc
- Installed to
/bin/busyboxwith symlinks
Dropbear SSH:
- Lightweight SSH server
- Built statically without zlib
- Login and wtmp disabled
- Configuration goes to
/etc/dropbear/
Socat:
- Multi-purpose relay tool
- Built statically without OpenSSL, readline, libwrap
- Workaround for getprotobynumber_r issue (Alpine Linux patch)
Curl:
- Pre-built static binary (not compiled from source)
- HTTPS support with CA certificates from host
- CA certs copied to
/etc/ssl/certs/ca-certificates.crt
For aarch64:
# Edit kconfig/aarch64.config manually or use menuconfig
./puipui-linux-tool -u
# Review changes in kconfig/aarch64.config
git add kconfig/aarch64.config
git commit -m "updated aarch64 kconfig to enable FEATURE_X"For x86_64:
# Edit kconfig/x86_64.config manually or use menuconfig
./puipui-linux-tool -u
# Review changes in kconfig/x86_64.config
git add kconfig/x86_64.config
git commit -m "enabled CONFIG_FEATURE_X for x86_64"Interactive menuconfig:
# After running build once to download kernel sources
cd build-aarch64/linux-kernel # or build-x86_64/linux-kernel
make menuconfig
# Save and exit
cd ../..
./puipui-linux-tool -u # Update defconfig-
Edit files in
fs/directory:fs/init- Boot initialization scriptfs/etc/inittab- Init configurationfs/etc/passwd,fs/etc/group- User/group setup- Add new files/directories as needed
-
Rebuild:
./puipui-linux-tool
-
The
fs/directory is copied tobuild-{arch}/fs/during build -
Additional components installed during build:
- Dropbear (built from source)
- Socat (built from source)
- Curl (downloaded binary)
- CA certificates (copied from host)
- BusyBox (built and symlinks created)
- Edit
busybox_config/config - Or use menuconfig:
cd build-aarch64/busybox # After first build make menuconfig cp .config ../../busybox_config/config
- Rebuild with
./puipui-linux-tool
The build produces:
build-{arch}/artifact/Image.gzorbzImagebuild-{arch}/artifact/initramfs.cpio.gzpuipui_linux_v{version}_{arch}.tar.gz
Use these with the vz framework for testing.
- Feature branches:
claude/feature-name-{sessionId} - Example:
claude/add-claude-documentation-bBPid - CRITICAL: Branches must start with
claude/and end with matching session ID for successful push
Based on recent history, commits follow these patterns:
Good examples:
"fixed x86_64 config and enabled VIRTIO_GPU in both""allow specifing vsock port on cmdline""use v6.11.5 kernel and updated some config""enabled CONFIG_ACPI_PCI_SLOT and CONFIG_ACPI_APEI for x86_64"
Conventions:
- Use lowercase imperative mood ("fixed", "enabled", "added", "updated")
- Be specific about what changed
- Reference architecture if change is arch-specific
- For config changes, mention the CONFIG_ symbol
- Keep messages concise but descriptive
git push -u origin <branch-name>Important: If push fails due to network errors, retry up to 4 times with exponential backoff (2s, 4s, 8s, 16s).
- Always test with
./puipui-linux-toolbefore committing - Kernel config changes must be validated with
-uflag - Never commit broken configs or syntax errors in scripts
- Changes must work for BOTH aarch64 and x86_64
- Test both architectures when modifying kernel configs
- Architecture-specific changes must be clearly documented
- This is a minimal Linux distribution
- Don't add unnecessary features or bloat
- Consider size impact of any additions
- Question whether a feature is needed for virtualization testing
- All userspace is built against musl libc, not glibc
- Some features may not be available
- Prefer static linking for reliability
- Be aware of musl vs glibc differences
- Init is a simple BusyBox-based system
- No systemd, no complex init systems
- Keep init script simple and readable
- Changes to boot process go in
fs/init
- Kernel configs: defconfig format (minimal, not full .config)
- BusyBox config: full .config format
- Never commit generated configs from build directories
- Only commit configs from
kconfig/andbusybox_config/
- Builds use
SOURCE_DATE_EPOCHfor reproducibility KBUILD_BUILD_HOST="molbuilder"KBUILD_BUILD_USER="codehex"- Don't modify these unless necessary
- All external dependencies are downloaded during build
- Never commit downloaded sources (gitignored)
- URL changes should be rare and carefully considered
- Verify download URLs are stable
- Root password is hardcoded: "passwd" (this is for testing only)
- No security hardening (this is a test environment)
- SSH via Dropbear is for convenience, not production use
- CA certificates included only for testing HTTPS in curl
- Never use relative paths in scripts
- Build script maintains working directory carefully
- All paths calculated from
$srcdirvariable - Use helper functions:
_builddir,_artifact,_kconfig, etc.
- Edit
puipui-linux-tool: changekernver=6.11.5to new version - Run
./puipui-linux-tool- it will download new kernel - May need to update configs:
./puipui-linux-tool -u - Test both architectures
- Commit with message like:
"use v6.12.0 kernel and updated some config"
- Edit
kconfig/{arch}.configto addCONFIG_FEATURE=y - Run
./puipui-linux-tool -uto validate - Review changes to ensure only intended options changed
- If multiple architectures: repeat for each
- Commit:
"enabled CONFIG_FEATURE for {arch}"
- Decide: compile from source or download binary?
- If compiling: add fetch, build, and install functions (like
install_dropbear) - If binary: add download and install (like
download_curl) - Modify
build_initramfsto call your install function - Test the build
- Commit changes with clear description
- Edit
fs/init - Follow BusyBox sh syntax (limited compared to bash)
- Test in actual VM environment
- Consider backward compatibility
- Document any new kernel parameters
- Check
build-{arch}/directories for logs - Kernel build logs in
build-{arch}/linux-kernel/ - BusyBox logs in
build-{arch}/busybox/ - Component builds in respective directories
- Use
make V=1for verbose output if needed
rm -rf build-* linux-* busybox-* dropbear-* socat-* *-linux-musl-* *.tar.gz *.tar.xz *.tgz
./puipui-linux-tool # Fresh build- Musl cross-compilers used for deterministic, static builds
CROSS_COMPILEenvironment variable set for makeCC,AR,RANLIB,STRIPexplicitly set for configure scriptsARCHvariable maps to kernel arch names (arm64, x86)
- All binaries statically linked against musl
LDFLAGS="-static"for BusyBox- Configure flags for Dropbear and Socat
- Ensures initramfs has no external dependencies
- Created with:
find . | cpio -o -H newc | gzip -9 - Format: newc (new ASCII format)
- Compression: gzip -9 (maximum compression)
- Kernel loads via CONFIG_BLK_DEV_INITRD
The system relies entirely on VIRTIO for I/O:
- No native disk drivers (only virtio_blk)
- No native network drivers (virtio_net via networking stack)
- Console via hvc (virtio_console)
- File sharing via virtfs (virtio_fs, 9p filesystem)
- Sockets via vsock (virtio_vsock, AF_VSOCK)
This means the system ONLY works in virtualized environments with VIRTIO support.
| What | Where |
|---|---|
| Main build script | ./puipui-linux-tool |
| ARM64 kernel config | kconfig/aarch64.config |
| x86_64 kernel config | kconfig/x86_64.config |
| BusyBox config | busybox_config/config |
| Init script | fs/init |
| Init configuration | fs/etc/inittab |
| User accounts | fs/etc/passwd, fs/etc/group |
| Build artifacts | build-{arch}/artifact/ |
| Final tarballs | puipui_linux_v{version}_{arch}.tar.gz |
- Clean build: remove
build-*directories - Re-run
./puipui-linux-tool
- Kernel config dependencies may enable/disable related options
- Review with
git diff kconfig/ - This is normal for defconfig format
- Ensure internet connectivity
- Check GitHub/musl.cc availability
- Verify architecture matches uname -m
- Check syntax with
sh -n fs/init - Verify BusyBox applets are available
- Check for missing dependencies in initramfs
- Review kernel config for bloat (modules, debugging)
- Check if unnecessary features enabled
- Consider CONFIG_CC_OPTIMIZE_FOR_SIZE (already enabled)
a74100f fixed x86_64 config and enabled VIRTIO_GPU in both
7c10926 allow specifing vsock port on cmdline
96c1436 revert login settings in busybox config
83d66c9 use v6.11.5 kernel and updated some config
51a0147 bump 0.0.2
5c0c20e updated curl and dropbear
e6fcf91 enabled /dev/input/event* in x86_64
888abb7 updated aarch64 kconfig to handle poweroff GPIO event
0b77236 added event handler for request stop
Notable recent developments:
- Added VIRTIO_GPU support
- Added vsock_port kernel parameter
- Updated to kernel 6.11.5
- Improved GPIO event handling for power management
- Input event support for x86_64
Last Updated: 2026-01-05 Document Version: 1.0 For: PUI PUI Linux v1.0.3
This document should be updated whenever significant architectural changes are made to the project.