• Stars
    star
    100
  • Rank 338,630 (Top 7 %)
  • Language
    C
  • License
    MIT License
  • Created about 6 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Home-made almost operating system

SOS (Stephen's OS)

builds.sr.ht status

This is my personal operating system project. It targets the 32-bit ARMv7-A architecture. The main target board is qemu, but progress is being made on the Raspberry Pi 4B target! Despite being very imited, this one-person project has actually made a great deal of progress and continues to improve.

Instructions

To build and run this, you need two important pieces of software: QEMU 4.2+, and an ARM cross compiler. These dependencies are straightforward on Arch Linux, but Ubuntu users should see more detailed setup instructions in Ubuntu.md.

Some additional dependencies which get installed by the following command:

  • pytest: a python testing framework, used to implement integration tests. You can skip this if you're not planning to run integration tests.
  • mtools: tools which create and manage MS-DOS FAT12/16/32 volumes. These are automatically used by the integration test framework, but also are useful for creating your own filesystem image. However, a few dummy FS images are included in this repo, so it is not strictly necessary.
# Arch Linux
$ sudo pacman -Sy arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-gdb \
      qemu qemu-arch-extra python-pytest mtools

With these dependencies satisfied, you can do the following:

# First, configure SOS to run in a VM:
make config_qemu

# Then, either build & run the OS in a VM:
make run
# or...

# Run in debug mode, which allows stepping through code in GDB:
make debug
# (in another terminal)
make gdb
# or...

# Run unit tests (which exercise just the C code) plus integration tests
# (which start SOS in a VM and then test command functionality)
make test

Raspberry Pi 4B

This OS is growing support for the Raspberry Pi 4B. So far, SOS can boot into a simple kernel shell (which is not backed by kernel threads or a scheduler yet). For more information on setup and running, see [docs/RaspberryPi.md][].

Demo

After starting up the VM, you should see something like this:

SOS: Startup
Stephen's OS (user shell, pid=2)
ush>

This is a shell running as a user-space process. It has very few features, except to launch rudimentary processes. The best demonstration of what the OS can do is to look at the output of the "demo" command. The "demo" command starts up 10 instances of the same program, which looks like this:

int main()
{
        uint32_t i, j;
        int pid = getpid();

        for (i = 0; i < 8; i++) {
                printf("[pid=%u] Hello world, via system call, #%u\n", pid, i);

                /* do some busy waiting so we see more context switching */
                for (j = 0; j < 300000; j++) {
                        asm("nop");
                }
        }

        return 0;
}

In other words, each process starts up, prints a message (including it's identifier), and busy-waits a while. This is the (partial) output of the demo:

[pid=11] Hello world, via system call, #0
[pid=11] Hello world, via system call, #1
[pid=10] Hello world, via system call, #0
[pid=10] Hello world, via system call, #1
[pid=10] Hello world, via system call, #2
[pid=9] Hello world, via system call, #0
[pid=9] Hello world, via system call, #1
[pid=9] Hello world, via system call, #2
[pid=8] Hello world, via system call, #0
[pid=8] Hello world, via system call, #1
[pid=8] Hello world, via system call, #2
[pid=8] Hello world, via system call, #3

As each process executes, occasionally the operating system's timer interrupt will trigger a context switch to a different process. We see this by the fact that messages from multiple processes are interleaved. This demonstrates, at a high level, that this OS can do pre-emptive multi-tasking.

Some Features

Here is a longer list of things my OS can do:

  • Text I/O over PL011 UART. (see kernel/uart.c)
    • Input is interrupt driven, to avoid polling & busy waiting
  • A small, limited printf implementation. (see lib/format.c)
  • ARM MMU configured to provide separate address space for each process. (see both kernel/startup.s and kernel/kmem.c)
  • A simple first-fit memory allocator for allocating pages of memory (see lib/alloc.c)
  • A few system calls: display(), getchar(), getpid(), exit(). (see kernel/syscall.c)
  • Driver for ARM generic timer, with a tick configured at 100Hz (kernel/timer.c)
  • Driver for ARM generic interrupt controller, and interrupt handling supported. (see kernel/gic.c)
  • Processes (if that wasn't already clear), with the following attributes:
    • Run in ARM user mode
    • Memory layout:
      • 0x0-0x40000000 - kernel space - no access
      • 0x40000000+ - userspace
      • Each process has a separate user address space
    • Interact with the world via system calls
    • Pre-emptive multi tasking (thanks to timer interrupt)
    • Scheduled via a round-robin scheduler
  • Driver for a virtio block device (see kernel/virtio-net.c) and some very basic functionality which uses it.
  • Driver for a virtio network device (see kernel/virtio-net.c) and some very basic functionality which uses it.
  • FAT filesystem driver (currently only supports FAT12)

Some Limitations

Here are some odd limitations:

  • Only one process can read from the UART at a time. If two processes try to read and are put in the waiting state, the first one will be put to sleep and never re-scheduled.
  • Most memory aborts are handled by some form of kernel panic, so a userspace segfault will bring down the whole system.
  • There's no filesystem, so every possible program is compiled into the kernel, and copied into userspace.
  • Processes cannot expand their address space.

Here are a bunch of things to add support for, or improve:

  • Implement a filesystem
  • Dynamic memory for processes
  • ELF parsing
  • Better DTB parsing, use it to determine peripherals
  • Decent networking subsystem
  • Implement UDP sockets
  • Implement TCP?

Editor config

For editing code, I would recommend running the following periodically to generate a compile_commands.json file:

pip install --user compiledb  # do this just once
compiledb -n make all

With this done, you should be able to use a C language server (e.g. clangd, which I've verified to work) and client (e.g. vim-lsp, emacs, vscode). This will enable things like jump-to-definition, code completion, and renaming.

Resources

Here are some non-official resources I have found useful during this project:

  • Baking Pi is a series of tutorials about writing bare metal programs for Raspberry Pi. I followed this for a while before starting this project, so it influenced me a lot. It's a lot of fun and has lots of great information.
  • This Stanford course website has a lot of labs and references. For some of my earlier questions, it just kept popping up on Google, and it's really good.
  • Bare-metal programming for ARM helped a me get interrupts working. This book has a fairly narrow focus, but I found it quite well-written and helpful for the topics it did cover.

Here are some of the official standards and specifications I've relied on:

License

All told, this isn't a particularly functional or useful operating system yet, but there may be pieces that are interesting or useful on their own. You're free to use and modify the code as you'd like, under the terms of the MIT License, provided in LICENSE.txt.

More Repositories

1

lsh

Simple shell implementation. Tutorial here ->
C
1,320
star
2

tetris

Tetris in C and NCURSES.
C
204
star
3

alien-console

A ncurses based clone of the Alien: Isolation console interfaces.
C
55
star
4

tswift

MetroLyrics API for Python
Python
51
star
5

pywall

Python firewall.
Python
36
star
6

userspace_cooperative_multitasking

A simple example of cooperative multitasking in C in userspace
C
33
star
7

alien-iso

An Alien themed Linux "greeting card" ISO image
Shell
24
star
8

cbot

IRC chatbot written in C.
C
24
star
9

libstephen

My own C library. Probably don't use it.
C
24
star
10

minesweeper

Minesweeper in C!
C
21
star
11

kchat

Kernel based chat system.
C
18
star
12

yams

YAMS: Awesome MIPS Server
Assembly
18
star
13

nosj

Simple JSON parsing in C.
C
11
star
14

funlisp

Simple, embeddable lisp interpreter
C
11
star
15

last-makefile

The last makefile you'll ever need.
Makefile
11
star
16

hashchain

C hash chain implementation.
C
10
star
17

bart

BART fare reduction
JavaScript
10
star
18

notes

Org-mode course notes.
CSS
8
star
19

lisp

An old lisp implementation of mine --- see funlisp for a more recent and maintained implementation
C
8
star
20

notifyme

Email notifications for task completion in Python.
Python
7
star
21

pypie15int

Python & Pie 2015 - Create a Twitter Bot!
Python
7
star
22

cky

Not actually anything right now...
C
6
star
23

dotfiles

configuration files and such
Vim Script
5
star
24

plymouth-theme-nostromo

Nostromo Plymouth boot screen
4
star
25

groupme-slackbot

A SlackBot for GroupMe
Python
4
star
26

aproxymate

It's a proxy, mate!
C
4
star
27

brennan.io

Personal/professional website and blog.
SCSS
4
star
28

sudoku

wip sudoku solver that visualizes each step it makes
JavaScript
3
star
29

slacksoc

Slack bot framework. Runs on YAML and procrastination.
Go
3
star
30

gochat

Toy chat protocol in go.
Go
3
star
31

emacs

My old emacs configuration directory (.emacs.d) - I now use Spacemacs!
Emacs Lisp
3
star
32

dpath

EECS 433 Project - Directory Querying using XPath
Go
3
star
33

pybingo

Oldham Bingo 2.0
JavaScript
2
star
34

homework

LaTeX class for homework assignments.
TeX
2
star
35

pathmand

User space MPTCP path manager prototype
C
2
star
36

slackview

Slack log viewing and metrics
Python
2
star
37

evolve

A ridiculously simple evolutionary algorithm in C.
Makefile
2
star
38

sitebuilder

Build my website
Python
2
star
39

compiler

c compiler?
Yacc
2
star
40

smbio

Badly named library containing reusable bioinformatics code.
Python
2
star
41

vmtools

Tools for making my life happier in my kernel hacking vm
Python
2
star
42

stevix

what a terrible name
C
2
star
43

talks

Jekyll site that tags onto my main site and hosts reveal.js presentations, written in Markdown. Simple, really!
Python
1
star
44

h99

Ninety Nine Haskell Problems
Haskell
1
star
45

proxy

A proxy in Java (again)
Java
1
star
46

eecs477

EECS 477: Advanced Algorithms homework.
TeX
1
star
47

thesis

Master's Thesis
XProc
1
star
48

eecs440

EECS 440: Machine Learning Homework
TeX
1
star
49

resume

My LaTeX resume.
TeX
1
star
50

whiskeybot

let me know when i can buy new whiskey
Python
1
star
51

superfreq

Automatic frequency analysis tools for simple ciphers
Python
1
star
52

troubleshoot

Linux troubleshooting wizard!
Python
1
star
53

markov

Markov chain implementation in Python.
Python
1
star
54

caseid

Python interface to useful Case ID utilities.
Python
1
star
55

social

Social Network Expander
Python
1
star
56

c-from-java

Code examples to go with my OpenHacks session, "C from Java".
Makefile
1
star
57

hello-world

I wonder how to use github?
1
star
58

person_simulator

Python person simulator API/program/game.
Python
1
star