Skip to content
kwrxPublic

About

A hobby operating system built mostly from scratch

Topics

Resources

Stars

9 stars

Watchers

3 watching

Forks

Repository files navigation

aplus #os

release GitHub release (latest by date) License: GPL

aplus is a Unix-like operating system built almost entirely from scratch — a hybrid kernel with loadable kernel modules, its own drivers, and a small userspace on top. The kernel is written in C, with assembly for the architecture-specific parts; the cross toolchain builds C and C++ programs to run on it.

It started in September 2013 as a way to learn low-level and systems programming, and it is still a hobby project rather than a production system. Today it boots on x86_64 and provides a Linux-like syscall layer, a VFS with several filesystems, an lwIP TCP/IP stack, SMP multitasking and an early graphical stack — with a good deal still unimplemented.

🔥 Features

  • Hybrid kernel: modular design with loadable kernel objects, see drivers/*
  • Cross-platform: arch/*, designed for cross-platform environment targets. x86_64 is the target that boots and runs today; i686 and aarch64 are placeholders
  • Multitasking: processes and threads (fork, vfork, clone, execve) with SMP support
  • Virtual memory: on-demand paging with mmap, mprotect and brk
  • Filesystems: kernel/fs/, a VFS with ext2, ISO 9660, tmpfs, procfs and bindfs
  • Network: kernel/network/, almost full TCP/IP Network Stack by lwIP, reachable through BSD sockets — ordinary file descriptors, so dup2, fork inheritance and poll work on them like any other, with getsockname, getpeername and get/setsockopt translating the Linux option numbers lwIP does not share
  • Unix-like: Signals, Pipes, Futex, Unix domain sockets, TTY and PTY
  • I/O Multiplexing: poll, ppoll, select and pselect
  • ELF: static executables; dynamic linking is not supported yet
  • Linux Syscalls: Linux-like syscall layer, see SYSCALLS.md
  • Linux Framebuffer: Linux-like framebuffer support, with damage-based flushing and a hardware cursor plane on adapters that provide one
  • Virtio: Virtio devices (gpu, net, input, console, random) over Virtio PCI
  • GUI: a display server that owns the framebuffer and the input devices, draws window decorations itself, and hands out windows to clients over a Unix socket

See FEATURES.md for more information about features.


aplus v0.7 - desktop running on Qemu

:electron: Kernel

The kernel provides a basic unix environment with a minimal subset of posix stuff. It is a hybrid kernel: core subsystems are built in, while drivers are loadable kernel objects linked and started at runtime by the module loader.

  • Tasking, per-CPU run queues with SMP support, signal delivery and futex-based sleeping
  • Memory, kernel/mm/, physical memory manager and kernel heap on top of on-demand paging
  • IPC, kernel/ipc/, spinlocks, semaphores, futexes and Unix domain sockets
  • VFS, kernel/fs/, inode-based virtual filesystem with a dentry cache, and a /proc that exposes per-process state down to the open descriptors in /proc/<pid>/fd
  • Network, kernel/network/, the lwIP stack wired up to the socket syscalls
  • Syscalls, kernel/syscalls/, one file per entry, numbered from syscalls.json

It currently boots and runs on x86_64; support for other architectures such as i686 and aarch64 is still to be written.

🤖 Userspace

Userspace is still under development, and is assembled from two sources: the programs built from this repository, and prebuilt packages fetched at ./configure time from aplus-packages.

Built here: the init system and its init.sh boot script, a display server with its client library, a terminal emulator on top of libtsm and cairo, a file manager, a calculator, an image viewer that draws PNG, JPEG and WebP through cairo-ext, an application launcher on Super+Space that searches the installed .desktop files, the aplus-xopen opener that hands a path to whichever of them handles it, the kilo editor, nyancat, an IRC client, three MesaGL demos (gears, a shaded triangle and a raymarched scene), and a set of test programs — guest-side integration tests, run from the shell, covering signals, pipes, pseudo-terminals, sockets, select, the virtual memory manager and the virtio device nodes.

Pulled in as packages, all of them, on every ./configure: BusyBox, the dash and bash shells, system fonts, cursors, keymaps and sample pictures, the zlib, libpng, libjpeg-turbo, libwebp, freetype, pixman, cairo, expat, libtsm, LibreSSL and cURL libraries, MesaGL, the NetSurf web browser, and gcc and binutils with the arithmetic libraries they need — a native toolchain, so the guest compiles programs for itself. Doom and a NES emulator are the only optional ones left, off by default and toggled from the Kconfig menu.

Furthermore, userspace has a multi-user environment with superuser (root) and a unix-like filesystem with /proc and /dev implementation.

Graphical programs are windowed rather than each taking over the screen: aplus-wm owns /dev/fb0 and the input devices, draws every titlebar and border itself, and hands clients a buffer to draw into through libui. The terminal emulator, the sysutils applications and the MesaGL demos are ordinary clients of it. Where the adapter composites a cursor plane of its own — virtio-gpu does — the pointer moves without touching the framebuffer at all. Below, the gl-gears demo draws into a window of its own, stacked above the terminal that launched it — both frames drawn by the server rather than by the programs inside them.

Networked programs work end to end: below, BusyBox httpd is serving /var/www from inside the guest to a browser on the host, over the port 8080 forwarded to the guest's 80 by run-qemu and by the run.sh shipped with the releases.


aplus v0.7 - BusyBox httpd serving a page to a browser on the host

🔌 Drivers

Drivers are loadable kernel objects: one directory with a main.c per module, each declaring its identity and dependencies through MODULE_NAME()/MODULE_DEPS() and exporting init/dnit entry points. The tree currently builds 32 of them, covering device-class interfaces, char and block devices, terminals, input, network, video and virtio.

Notable modules


⚡ Getting Started

Run a release:

Every push to main is built by the release workflow and published as the latest development release.

  1. Download the latest release: release-aplus-<commit>-x86_64 holds the disk image and run.sh
  2. Requirements: qemu-system-x86_64 and UEFI firmware (ovmf or edk2-ovmf)
tar xf release-aplus-*-x86_64.tar.xz
cd release-aplus-*-x86_64
./run.sh

First run prompts for:

  • Architecture, disk image, UEFI firmware
  • CPUs, RAM
  • Virtio or emulated devices
  • KVM support
  • Display mode (local window or VNC)

Settings are saved to config.txt. Edit the file or run ./run.sh --reconfigure to change settings; ./run.sh --defaults skips the questions, ./run.sh --dry-run prints the QEMU command line without running it. Use ./run.sh --help for all available options.

The guest console is written to console.log, the QEMU monitor listens on telnet 127.0.0.1:4444, and the host port 8080 is forwarded to the guest's 80.

Build from Linux:

Clone this repository and change working directory.

$ git clone https://github.com/kwrx/aplus
$ cd aplus

NOTE: It's recommended you use a recent Linux host environment with this method.

Some packages are required for the build system; ./configure checks for all of them but xz and QEMU:

  • git, make, autoconf, automake (or build-essential on Ubuntu/Debian)
  • gcc, ld to compile sources and link objects
  • python3, with pip and venv: ./configure creates a .venv and installs requirements.txt into it
  • mke2fs, mkfs.vfat, mcopy, mmd, sgdisk, grub-mkstandalone, fakeroot, dd, truncate, fc-scan to generate the hdd image — grub-mkstandalone also needs its x86_64-efi modules, packaged apart on some distributions (grub-efi-amd64-bin on Ubuntu/Debian)
  • tar, gzip, zip, find, awk, od for the remaining build steps, and xz for the archives made by ./makew dist
  • qemu-system-x86_64 with UEFI firmware (ovmf or edk2-ovmf) to run it

On Ubuntu/Debian, you can install all of them with:

$ sudo apt install -y \
    git \
    build-essential \
    automake \
    autoconf \
    dosfstools \
    e2fsprogs \
    mtools \
    gdisk \
    fakeroot \
    grub-common \
    grub-efi-amd64-bin \
    fontconfig \
    gzip \
    tar \
    zip \
    xz-utils \
    python3 \
    python3-pip \
    python3-venv \
    qemu-system-x86 \
    ovmf

Then:

  1. Configure and check environment
$ ./configure

This opens the Kconfig menu. To build a preset from build/setup without it:

$ ./configure --kconfig x86_64
  1. Build it
$ ./makew all
  1. Run it
$ ./makew run

Use ./makew run-headless to run without a graphical display, which is handy to capture console output.


📚 Documentation

  • FEATURES.md — per-architecture and per-subsystem feature matrix
  • SYSCALLS.md — the syscall table
  • REPORT.md — outstanding TODO/FIXME markers in the tree
  • docs/ui/ — the display server, the wire protocol, and writing a graphical application against libui

🌐 Third-Party Software

aplus uses and depends on a large number of third-party open-source tools and libraries which are outside of this repository.

📃 License

This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.

About

A hobby operating system built mostly from scratch

Topics

Resources

Stars

9 stars

Watchers

3 watching

Forks

Releases

Used by

Contributors

Languages