Open-source project
ozkl/soso avatar
ozkl/soso

soso: a 32-bit Unix-like operating system built with Nasm and C

A Simple Unix-like operating system

997 stars53 forksCBSD-2-Clause

At a glance

What is it?
soso is a hobby operating system written in Nasm assembly and mostly C, booting through Grub in multiboot mode and running 32-bit static Linux binaries in userspace. Version 0.4 is the one worth looking at, since it introduced the higher half kernel and the 32-bit binary contract, and the repository was pushed to on 2026-07-26.
Who is it for?
soso is a good project to read if you want a whole operating system in a repository small enough to hold in your head, because the feature list is short and the source is a couple of directories of C and assembly. It is not something to run on real hardware, and it is not a base for a product, since the userspace contract is 32-bit static Linux ELF and the newest tag is v0.4 from 2025-09-20.
Can I use it commercially?
Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 89 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Ring 0 and ring 3 are separated by a higher half kernel

The architectural claim in this project is the privilege separation, not the multitasking. The kernelspace runs in ring 0 and the userspace runs in ring 3, and as of version 0.4 the kernel itself sits in the higher half of the address space, which is the arrangement where kernel code and data are mapped above the point where user space is allowed to reach. Everything below that boundary is where a userspace program lives.

That separation is what makes the rest of the feature list possible rather than decorative. If user code cannot address the kernel's page tables, then the system call entry points and the page fault handling have to be real boundaries rather than conventions. The feature list also includes paging, mmap support, and shared memory, and those three only make sense once the two rings are genuinely separated.

The system is 32-bit x86 throughout, and it supports multiboot, so a bootloader such as Grub starts it. It can be built with Nasm and Clang, and the tested build environments are Linux and FreeBSD.

The userspace contract is 32-bit static Linux ELF

Version 0.4 changed what a userspace program is. The executables are 32-bit static Linux binaries, and the README says plainly that you do not need a special compiler to build them, just build 32-bit static executables for Linux. That means an ordinary Linux toolchain can produce programs for soso, which removes the usual objection to hobby kernels where you need a purpose-built cross compiler and a matching libc.

The cost of that convenience is that the programs have to be statically linked and 32-bit. Anything dynamically linked will not run, and there is no mention of a dynamic linker, a shared library ABI or a C library inside the kernel. The system calls are the only interface, and userspace programs are ELF files in the sense the README describes: 32-bit static Linux ELF executables.

The same constraint runs through the rest of the design. The file system is FAT32, handled with FatFs, reached through a Virtual File System layer, and the graphics are framebuffer based with mmap used by userspace to access the screen. The hardware surface is small and explicit: a serial port, a PS/2 mouse, a TTY driver and Unix sockets.

make produces kernel.bin from a freestanding compile

Building the kernel is a single make invocation, and the Makefile is short enough to read in one pass. The compiler is Clang, the linker is ld, and the assembler is nasm, with the flags that make the output freestanding and 32-bit.

bash
CC=clang
LD=ld
CFLAGS=-nostdlib -nostdinc -fno-builtin -m32 -c
LDFLAGS=-Tlink.ld -m elf_i386
ASFLAGS=-felf

The -nostdlib and -nostdinc flags are the interesting ones, because they mean no standard library and no standard headers are available inside the kernel, and -m32 fixes the target to 32-bit. The link step uses a linker script of your own, link.ld, and the output format is elf_i386.

Assembly objects are built with nasm and the -felf flag, and the kernel and its font are linked into kernel.bin.

bash
nasm $(ASFLAGS) $< -o $@

The repository layout supports the same picture: a kernel/ directory holding the C and assembly sources, a font/ directory whose object file is linked in, a userspace/ directory, and shell scripts such as create-cd-image.sh, create-initrd.sh and create-image.sh for producing bootable images, plus run.sh and runkvm.sh for launching the result.

Booting the ISO in QEMU and running doom from a terminal

You do not need to build anything to see the system work. A CD image in ISO form is downloadable from the releases, and the README points at a PC emulator such as QEMU for running it. The command for that is short.

bash
qemu-system-i386 -cdrom soso.iso

The i386 target is not incidental, since the whole system is 32-bit x86 and the image contains a multiboot kernel that a bootloader such as Grub loads.

Once the system is up, a terminal window is available, and two programs are available to run there, doom and lua. Doom is launched from the initrd directory, so the sequence is a change of directory followed by the program name.

bash
cd /initrd
doom

A Lua interpreter sitting next to a playable Doom in a hobby kernel tells you something about the scope of the userspace work, and it is also the clearest hint of what a porting effort costs. The system calls, the ELF loader and the file system all have to line up before a third party program runs at all.

FAT32 under a virtual file system, with a TTY and Unix sockets

The file system story starts at the hardware abstraction. The Virtual File System layer sits on top of FAT32, which is handled with FatFs, a library for embedded flash file systems. That combination is a pragmatic choice: FAT32 is what an SD card or a USB stick usually carries, so the same image can be mounted and inspected from a host operating system, and FatFs is designed for constrained environments where a full disk file system would be wasteful.

The rest of the user facing surface is small and Unix shaped. There is a TTY driver, so a terminal window is a real device rather than a debug console, and there are Unix sockets, which is the interesting one because it is the only part of the interface that lets two processes on the system talk to each other. A serial port and a PS/2 mouse cover the input and output hardware, and framebuffer graphics with mmap gives userspace direct access to the screen.

Taken together the list describes a small but complete userland: a kernel, a loader, a file system, a terminal and a couple of running programs. That completeness is the appeal for a reader, and also the reason the project is a learning artifact rather than a product.

Version 0.4 dates from 2025, and the commits continue after it

The release history is sparse and uneven. Version 0.2 was tagged on 2019-09-07, version 0.3 on 2021-03-14, and version 0.4 on 2025-09-20, a gap of more than four years between the second and third tags. The repository was pushed to on 2026-07-26, so work is landing on master well after the newest tag, which means the ISO you can download from the releases is not necessarily the code currently in the tree.

The licence is BSD-2-Clause, which is permissive and short: you can use, modify and redistribute the code, including in closed source products, as long as you keep the copyright notice and the disclaimer. For a kernel, that makes the code easy to read, copy and learn from, which is the main reason an operating system like this ends up in a study curriculum.

The topic tags are kernel, osdev and unix-like, and the default branch is master. With no schema compatibility, no drivers to speak of beyond the ones listed, and no package manager, the honest framing is that soso is a research and teaching project with a working end to end path from multiboot to a running program, not a system to build a product on.

Editorial conclusion

soso is a good project to read if you want a whole operating system in a repository small enough to hold in your head, because the feature list is short and the source is a couple of directories of C and assembly. It is not something to run on real hardware, and it is not a base for a product, since the userspace contract is 32-bit static Linux ELF and the newest tag is v0.4 from 2025-09-20. Before you start, build it with make and boot the released ISO under qemu-system-i386, and check that your toolchain has Nasm and Clang available, since the Makefile compiles with -nostdlib and -m32.

Frequently asked questions

How do I run the soso operating system?

Download the CD image in ISO form from the GitHub releases and start it in a PC emulator with qemu-system-i386 -cdrom soso.iso. The README notes that a terminal window is available where you can run doom or lua.

How do I build the soso kernel?

Run make in the repository root, which builds the kernel into kernel.bin. The build needs Nasm and Clang, with the Makefile compiling freestanding 32-bit objects and linking with a custom link.ld script. Tested build environments are Linux and FreeBSD.

What architecture does soso target?

soso is a 32-bit x86 system that supports multiboot and is started by Grub. From version 0.4 it has a higher half kernel, separates kernelspace in ring 0 from userspace in ring 3, and runs 32-bit static Linux ELF executables.

What licence is soso released under?

The repository is under the BSD-2-Clause licence. The newest release is v0.4, tagged on 2025-09-20, and the last push to the repository was on 2026-07-26.

Official sources

  1. Issues
  2. License: BSD-2-Clause
  3. ozkl/soso on GitHub
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/ozkl-soso.svg)](https://hysenlabs.com/projects/ozkl-soso)

Was this useful?