{"id":18557545,"url":"https://github.com/brenns10/sos","last_synced_at":"2026-02-24T07:33:17.519Z","repository":{"id":58178139,"uuid":"146952495","full_name":"brenns10/sos","owner":"brenns10","description":"Home-made almost operating system","archived":false,"fork":false,"pushed_at":"2022-10-07T06:26:44.000Z","size":553,"stargazers_count":145,"open_issues_count":0,"forks_count":11,"subscribers_count":7,"default_branch":"master","last_synced_at":"2026-02-16T14:52:26.212Z","etag":null,"topics":["arm","assembly","os","qemu"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/brenns10.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-08-31T23:52:35.000Z","updated_at":"2026-01-23T10:20:16.000Z","dependencies_parsed_at":"2022-09-07T01:22:05.506Z","dependency_job_id":null,"html_url":"https://github.com/brenns10/sos","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/brenns10/sos","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brenns10%2Fsos","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brenns10%2Fsos/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brenns10%2Fsos/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brenns10%2Fsos/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/brenns10","download_url":"https://codeload.github.com/brenns10/sos/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/brenns10%2Fsos/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29774927,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-24T04:54:30.205Z","status":"ssl_error","status_checked_at":"2026-02-24T04:53:58.628Z","response_time":75,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["arm","assembly","os","qemu"],"created_at":"2024-11-06T21:37:22.271Z","updated_at":"2026-02-24T07:33:17.479Z","avatar_url":"https://github.com/brenns10.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"SOS (Stephen's OS)\n==================\n\n[![builds.sr.ht status](https://builds.sr.ht/~brenns10/sos.svg)](https://builds.sr.ht/~brenns10/sos?)\n\nThis is my personal operating system project. It targets the 32-bit ARMv7-A\narchitecture. The main target board is qemu, but progress is being made on the\nRaspberry Pi 4B target! Despite being very imited, this one-person project has\nactually made a great deal of progress and continues to improve.\n\nInstructions\n------------\n\nTo build and run this, you need two important pieces of software: QEMU 4.2+, and\nan ARM cross compiler. These dependencies are straightforward on Arch Linux, but\nUbuntu users should see more detailed setup instructions in\n[Ubuntu.md](Ubuntu.md).\n\nSome additional dependencies which get installed by the following command:\n\n- pytest: a python testing framework, used to implement integration tests. You\n  can skip this if you're not planning to run integration tests.\n- mtools: tools which create and manage MS-DOS FAT12/16/32 volumes. These are\n  automatically used by the integration test framework, but also are useful for\n  creating your own filesystem image. However, a few dummy FS images are\n  included in this repo, so it is not strictly necessary.\n\n```\n# Arch Linux\n$ sudo pacman -Sy arm-none-eabi-gcc arm-none-eabi-binutils arm-none-eabi-gdb \\\n      qemu qemu-arch-extra python-pytest mtools\n```\n\nWith these dependencies satisfied, you can do the following:\n\n    # First, configure SOS to run in a VM:\n    make config_qemu\n\n    # Then, either build \u0026 run the OS in a VM:\n    make run\n    # or...\n\n    # Run in debug mode, which allows stepping through code in GDB:\n    make debug\n    # (in another terminal)\n    make gdb\n    # or...\n\n    # Run unit tests (which exercise just the C code) plus integration tests\n    # (which start SOS in a VM and then test command functionality)\n    make test\n\n\nRaspberry Pi 4B\n---------------\n\nThis OS is growing support for the Raspberry Pi 4B. So far, SOS can boot into a\nsimple kernel shell (which is not backed by kernel threads or a scheduler yet).\nFor more information on setup and running, see [docs/RaspberryPi.md][].\n\nDemo\n----\n\nAfter starting up the VM, you should see something like this:\n\n```\nSOS: Startup\nStephen's OS (user shell, pid=2)\nush\u003e\n```\n\nThis is a shell running as a user-space process. It has very few features,\nexcept to launch rudimentary processes. The best demonstration of what the OS\ncan do is to look at the output of the \"demo\" command. The \"demo\" command starts\nup 10 instances of the same program, which looks like this:\n\n```c\nint main()\n{\n        uint32_t i, j;\n        int pid = getpid();\n\n        for (i = 0; i \u003c 8; i++) {\n                printf(\"[pid=%u] Hello world, via system call, #%u\\n\", pid, i);\n\n                /* do some busy waiting so we see more context switching */\n                for (j = 0; j \u003c 300000; j++) {\n                        asm(\"nop\");\n                }\n        }\n\n        return 0;\n}\n```\n\nIn other words, each process starts up, prints a message (including it's\nidentifier), and busy-waits a while. This is the (partial) output of the demo:\n\n```\n[pid=11] Hello world, via system call, #0\n[pid=11] Hello world, via system call, #1\n[pid=10] Hello world, via system call, #0\n[pid=10] Hello world, via system call, #1\n[pid=10] Hello world, via system call, #2\n[pid=9] Hello world, via system call, #0\n[pid=9] Hello world, via system call, #1\n[pid=9] Hello world, via system call, #2\n[pid=8] Hello world, via system call, #0\n[pid=8] Hello world, via system call, #1\n[pid=8] Hello world, via system call, #2\n[pid=8] Hello world, via system call, #3\n```\n\nAs each process executes, occasionally the operating system's timer interrupt\nwill trigger a context switch to a different process. We see this by the fact\nthat messages from multiple processes are interleaved. This demonstrates, at a\nhigh level, that this OS can do pre-emptive multi-tasking.\n\nSome Features\n-------------\n\nHere is a longer list of things my OS can do:\n\n* Text I/O over PL011 UART. (see `kernel/uart.c`)\n  - Input is interrupt driven, to avoid polling \u0026 busy waiting\n* A small, limited `printf` implementation. (see `lib/format.c`)\n* ARM MMU configured to provide separate address space for each process. (see\n  both `kernel/startup.s` and `kernel/kmem.c`)\n* A simple first-fit memory allocator for allocating pages of memory (see\n  `lib/alloc.c`)\n* A few system calls: display(), getchar(), getpid(), exit(). (see\n  `kernel/syscall.c`)\n* Driver for ARM generic timer, with a tick configured at 100Hz\n  (`kernel/timer.c`)\n* Driver for ARM generic interrupt controller, and interrupt handling supported.\n  (see `kernel/gic.c`)\n* Processes (if that wasn't already clear), with the following attributes:\n  - Run in ARM user mode\n  - Memory layout:\n    - 0x0-0x40000000 - kernel space - no access\n    - 0x40000000+ - userspace\n    - Each process has a separate user address space\n  - Interact with the world via system calls\n  - Pre-emptive multi tasking (thanks to timer interrupt)\n  - Scheduled via a round-robin scheduler\n* Driver for a virtio block device (see `kernel/virtio-net.c`) and some very\n  basic functionality which uses it.\n* Driver for a virtio network device (see `kernel/virtio-net.c`) and some very\n  basic functionality which uses it.\n* FAT filesystem driver (currently only supports FAT12)\n\nSome Limitations\n----------------\n\nHere are some odd limitations:\n\n* Only one process can read from the UART at a time. If two processes try to\n  read and are put in the waiting state, the first one will be put to sleep and\n  never re-scheduled.\n* Most memory aborts are handled by some form of kernel panic, so a userspace\n  segfault will bring down the whole system.\n* There's no filesystem, so every possible program is compiled into the kernel,\n  and copied into userspace.\n* Processes cannot expand their address space.\n\nHere are a bunch of things to add support for, or improve:\n\n* Implement a filesystem\n* Dynamic memory for processes\n* ELF parsing\n* Better DTB parsing, use it to determine peripherals\n* Decent networking subsystem\n* Implement UDP sockets\n* Implement TCP?\n\nEditor config\n-------------\n\nFor editing code, I would recommend running the following periodically to\ngenerate a `compile_commands.json` file:\n\n    pip install --user compiledb  # do this just once\n    compiledb -n make all\n\nWith this done, you should be able to use a C language server (e.g. clangd,\nwhich I've verified to work) and client (e.g. vim-lsp, emacs, vscode). This will\nenable things like jump-to-definition, code completion, and renaming.\n\nResources\n---------\n\nHere are some non-official resources I have found useful during this project:\n\n- [Baking Pi][baking-pi] is a series of tutorials about writing bare metal\n  programs for Raspberry Pi. I followed this for a while before starting this\n  project, so it influenced me a lot. It's a lot of fun and has lots of great\n  information.\n- [This Stanford course website][course] has a lot of labs and references. For\n  some of my earlier questions, it just kept popping up on Google, and it's\n  really good.\n- [Bare-metal programming for ARM][ebook] helped a me get interrupts working.\n  This book has a fairly narrow focus, but I found it quite well-written and\n  helpful for the topics it did cover.\n\n[baking-pi]: https://www.cl.cam.ac.uk/projects/raspberrypi/tutorials/os/ok05.html\n[course]: http://cs107e.github.io/\n[ebook]: http://umanovskis.se/files/arm-baremetal-ebook.pdf\n\nHere are some of the official standards and specifications I've relied on:\n\n- [ARMv7-A Architecture Reference Manual][arm-arm]: the authoritative reference\n  for ARM assembly, and other architecture topics like the Virtual Memory System\n  Architecture (VMSA), the Generic Timer, exception and interrupt handling, and\n  more.\n- [ARM Generic Interrupt Controller Architecture Specification][arm-gic]:\n  specifies how the GIC works, which is crucial for being able to handle,\n  enable, and route interrupts.\n- [PrimeCell PL011 UART Manual][pl011]\n- [DeviceTree Specification][dtree]: This specifies the data structures which\n  store information about the devices in a system. I've partially implemented\n  this and will be revisiting it soon. When I last looked the spec was at\n  version 0.2 but now there's a 0.3!\n- [Virtio Specification][virtio]: This specifies how virtio devices work. This\n  underlies my block and network devices.\n- [RFC791][rfc791]: Internet Protocol!\n- [RFC768][rfc768]: User Datagram Protocol.\n- [RFC2131][rfc2131]: Dynamic Host Configuration Protocol. Also the [Wikipedia\n  page][dhcp-wiki] and the [options spec (RFC1533)][rfc1533].\n- [Microsoft FAT Specification][fat]\n\n[arm-arm]: https://static.docs.arm.com/ddi0406/c/DDI0406C_C_arm_architecture_reference_manual.pdf\n[arm-gic]: https://static.docs.arm.com/ihi0069/d/IHI0069D_gic_architecture_specification.pdf\n[pl011]: http://infocenter.arm.com/help/topic/com.arm.doc.ddi0183f/DDI0183.pdf\n[dtree]: https://www.devicetree.org/specifications/\n[virtio]: http://docs.oasis-open.org/virtio/virtio/v1.0/cs04/virtio-v1.0-cs04.html\n[rfc791]: https://tools.ietf.org/html/rfc791\n[rfc768]: https://tools.ietf.org/html/rfc768\n[rfc2131]: https://tools.ietf.org/html/rfc2131\n[rfc1533]: https://tools.ietf.org/html/rfc1533\n[fat]: http://read.pudn.com/downloads77/ebook/294884/FAT32%20Spec%20%28SDA%20Contribution%29.pdf\n[dhcp-wiki]: https://en.wikipedia.org/wiki/Dynamic_Host_Configuration_Protocol\n\nLicense\n-------\n\nAll told, this isn't a particularly functional or useful operating system yet,\nbut there may be pieces that are interesting or useful on their own. You're free\nto use and modify the code as you'd like, under the terms of the MIT License,\nprovided in `LICENSE.txt`.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrenns10%2Fsos","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbrenns10%2Fsos","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbrenns10%2Fsos/lists"}