Forest OS

A free and open source operating system, written from scratch. A Bluethefox project, hosted by Enclica.

Docs

This page is the short path from a fresh clone to a booting system. The full guide — including UEFI, self-hosting, initrd contents and the complete troubleshooting list — is MAKE_AN_OS.md in the repository, and it is the authoritative version.

How it fits together

Forest-OS is assembled from separately named components rather than one tree:

ComponentNameRole
fern/FernThe kernel. The build system lives here too.
foreboots/foreboots (ForeB)Bootloader — raw MBR/BIOS and UEFI. Loads Fern.
libs/libc/forestlibsThe POSIX-oriented C library the ABI targets.
forestos-toolchain/The i686-forestos / x86_64-forestos cross-compilers.

The whole system is Forest-OS (codename ALDER); the kernel alone is Fern; the bootloader alone is foreboots.

What you can turn on

Set these in menuconfig, or with flags to createos.sh:

FeatureWhat it adds
OpenGLSoftware renderer for 3D graphics.
NetworkingTCP/IP stack and drivers.
AudioPC speaker, HDA and virtio-snd.
SMPMulti-core support.
X11Display server in userspace, over UNIX sockets.

Host dependencies

Debian and Ubuntu package names — adjust for your distro. First, what the cross-toolchain build needs:

sudo apt install build-essential gcc g++ make flex bison gawk \
                 texinfo curl wget tar xz-utils \
                 libgmp-dev libmpfr-dev libmpc-dev

Then what building and running the system needs:

sudo apt install nasm clang lld xorriso mtools python3 \
                 qemu-system-x86 ovmf dialog

clang and ld.lld are there for the UEFI application specifically — that is a deliberate split, with BIOS stages on nasm/GCC and the UEFI app on clang/lld. dialog is only needed for the interactive menuconfig screen.

Quick start — BIOS, 32-bit

Set $FOREST to your checkout so the rest is copy-pasteable:

export FOREST="$(git rev-parse --show-toplevel)"
# 1. build the cross-toolchain (slow, but only once)
cd $FOREST/forestos-toolchain
./build-toolchain.sh --arch both
export FORESTOS_TOOLCHAIN_DIR=$FOREST/forestos-toolchain

# 2. configure Fern
cd $FOREST/fern
./conf.sh --defconfig

# 3. build the kernel
make build

# 4. build the userspace apps
cd $FOREST/userspace
make

# 5. put them in the initrd
cp $FOREST/userspace/build/bin/* $FOREST/fern/initrd/bin/
ln -sf forest-shell $FOREST/fern/initrd/bin/shell
ln -sf forest-shell $FOREST/fern/initrd/bin/sh

# 6. rebuild the kernel so it picks up the new initrd
cd $FOREST/fern
make build

# 7. assemble the bootable image
make forebo-image

# 8. boot it
make run

The easier path — createos.sh

createos.sh in the repository root does all of the above for you: it checks and installs host packages, builds the toolchain, compiles userspace, assembles the initrd, builds the kernel and bootloader, and packages everything into output/.

cd $FOREST
./createos.sh

That opens a menu where you set architecture, boot mode, build type, features and initrd style, then pick BUILD. If you already know what you want, skip the menu entirely:

./createos.sh --quick                                  # 32-bit BIOS debug
./createos.sh --arch 64 --boot uefi --type release
./createos.sh --no-x11 --initrd full --smp
FlagValues
--arch32, 64, arm, aarch64, riscv64
--bootbios, uefi
--typedebug, release
--initrdminimal, standard, full, custom
--smpEnable multi-core support
--no-opengl, --no-networking, --no-audio, --no-x11Turn features off
--skip-toolchain, --skip-userspaceReuse what's already built

Initrd styles

StyleContents
minimalShell-script builtins only. Smallest image.
standardCompiled userspace apps and shared libraries. The default.
fullApps, libraries, fonts, icons and other resources.
customPick individual programs from a checklist.

The build checks binaries as it copies them, and warns if anything in bin/ turns out to be host-compiled rather than built for Forest-OS.

Everything lands in output/ along with a README.txt recording the exact configuration and the commands to boot it.

The toolchain path trap. build/toolchain.mk looks for the toolchain at fern/forestos-toolchain, but it actually lives one level up. If make aborts with Architecture toolchain not found, either export FORESTOS_TOOLCHAIN_DIR as above, or create the symlink the tree expects:

ln -s ../forestos-toolchain $FOREST/fern/forestos-toolchain

Configuring

conf.sh writes .forestos_config and generates build-config.mk. --defconfig gives you 32-bit, BIOS, debug, with the foreboots bootloader enabled.

CommandWhat it does
./conf.sh --defconfigSane defaults.
./conf.sh --menuconfigInteractive TUI. Needs dialog.
./conf.sh --oldconfigRe-validate an existing config.
make show-configDump the effective ARCH, boot mode, toolchain and output path.

You can also override per run without editing the config:

make ARCH=64 BOOT_MODE=uefi BUILD_TYPE=release all

Building

TargetResult
make buildThe Fern kernel only. No bootable image.
make forebo-imageBuilds foreboots and embeds the current kernel into a disk image.
make allToolchain check, kernel, then image — the three above in one.
make forebo-checkValidates stage sizes and the 0x55AA MBR signature.

Kernel output lands in build/<ARCH>bit-<BOOT_MODE>-<BUILD_TYPE>/boot/fern.bin on BIOS, BOOTX64.EFI plus fern.elf on UEFI. The initrd tarball is built alongside it from the initrd/ tree.

A bare make does nothing. The default goal is help, so it prints the help screen and stops. Always name a target.

Running

make run          # honours the configured boot mode
make run-bios     # force BIOS: boots forebo.img under qemu-system-i386
make run-uefi     # force UEFI: boots esp.img under OVMF
make run32        # 32-bit BIOS
make run64        # 64-bit BIOS
make debug        # same as run, with a GDB stub on :1234

By hand, if you'd rather drive QEMU yourself:

qemu-system-i386 -drive format=raw,file=$FOREST/foreboots/build/forebo.img \
                 -serial stdio -vga std

Note that this is a raw disk image, not a CD — -drive format=raw, not -cdrom. For the hybrid forebo.iso the CD-ROM path applies instead.

Debugging the kernel

make debug starts QEMU with -s -S, so it waits for you. In another terminal:

gdb $FOREST/fern/build/32bit-bios-debug/boot/fern.bin
(gdb) target remote localhost:1234
(gdb) continue

Serial output is usually easier to read than the VGA console — the run targets already pass -serial stdio.

Common problems

64-bit build silently uses the host compiler

If show-config mentions falling back to a host x86_64 toolchain, then install/bin/x86_64-forestos-gcc is missing. It will still compile, but it is not a real cross build — re-run ./build-toolchain.sh --arch 64.

stdio.h or forestos/syscalls.h not found

The sysroot was never populated. Re-run build-toolchain.sh and confirm the headers exist under forestos-toolchain/sysroot/usr/include/.

Programs crash immediately at boot

Almost always host-compiled binaries in initrd/bin/. Everything there must be built with i686-forestos-gcc — the host ABI differs and will not survive. file initrd/bin/forest-shell should report ELF32.

The kernel never starts a shell

The session manager looks for /bin/shell. Create the symlink: ln -sf forest-shell initrd/bin/shell.

ForeB bootloader is disabled

ENABLE_FOREB_BOOTLOADER isn't set. Run ./conf.sh --defconfig, or set it in --menuconfig and regenerate.

UEFI firmware path mismatch

The Fern and foreboots UEFI targets look for OVMF at different paths, and distros ship it at different paths again. If UEFI boot fails on firmware, install OVMF and point the run at the file your distro actually provides.

The full troubleshooting list — initrd size limits, sudo and shadow, nasm, lld, dialog — is in MAKE_AN_OS.md. If something here has drifted from the repository, the repository wins; please open an issue.