Operating System in 1,000 Lines – Intro

2 years ago (operating-system-in-1000-lines.vercel.app)

Author here.

I wrote this book so you can spend a boring weekend writing an operating system from scratch. You don’t have to write it in C - you can use your favorite programming language, like Rust or Zig.

I intentionally made it not UNIX-like and kept only the essential parts. Thinking about how the OS differs from Linux or Windows can also be fun. Designing an OS is like creating your own world—you can make it however you like!

BTW, you might notice some paragraphs feel machine-translated because, to some extent, they are. If you have some time to spare, please send me a PR. The content is written in plain Markdown [1].

Hope you enjoy :)

[1] https://github.com/nuta/operating-system-in-1000-lines/tree/...

  • Are you planning to also provide an English translation of your microkernel book? That sounds very interesting...

    • Unfortunately not. Maybe I'll write another online book like this in English, after building a more practical microkernel-based OS. It's a very interesting topic indeed :D

  • "Designing an OS is like creating your own world"

    Making video game is also like creating your own world!

    And it's order of magnitude less hard than making an OS...

    Bonus point, you have a chance to make a living from it!

  • How does your book compare with the classic "Operating systems design and implementation" by Andrew S. Tanenbaum and Albert S. Woodhull implementing MINIX?

    • I thinks this 1,000 OS book is a good start for beginners before diving into the MINIX book.

      MINIX book describes more practical designs, with a more feature-rich implementation. However, UNIX features such fork, brk, and tty are not intuitive for beginners. By writing a toy OS first, readers can compare the toy OS with MINIX, and understand that UNIX-like is just one of many possible designs. That's an important perspective IMO.

      Also, readers can actually implement better algorithms described in the MINIX book. It makes the MINIX book more interesting to read.

    • This is so much easier. You are implementing printf on page 5 and it can handle formatted output to the screen for integers, hexadecimals, and strings. Minix eventually gets around to the write system call but even then it is actually just a way of sending bytes from a buffer to a file descriptor. To a what? That is a lot more complexity for, in some ways, less functionality. For write, you still have to write printf on top.

      The Tanenbaum book is great but it is a particle physics textbook compered to this OS cookbook.

  • Hi OP, this looks super cool. I remember hearing about this (https://www.linuxfromscratch.org/) many years ago but have never done it.

    Curious, what are the prerequisites for this? Do I have to know about how kernels work? How memory management, protection rings or processes are queued? Some I'd like to definitely learn about.

    • LFS is about building a Linux distribution from scratch (i.e. using the Linux kernel.)

      The book in question is about how to build your own operating system (i.e. a non-Linux) kernel from scratch.

      > We'll implement basic context switching, paging, user mode, a command-line shell, a disk device driver, and file read/write operations in C. Sounds like a lot, however, it's only 1,000 lines of code!

    • Thank you! If you've written some programs (ideally in C), you're good to go. You might stuck on some concepts, but you can learn one by one. IMO, implementing it makes you to understand the concepts more deeply, and learn more that you won't notice when you just read textbooks.

      Also, because the implementation in this book is very naive, it would stimulate your curiosity.

  • Great resource, thanks for sharing.

    I thought the written text was very high quality and didn't show many of the usual tells of a non-native writer. Could you share some details of how you used AI tools to help write it?

    • Copy-and-pasting to ChatGPT. Machine translation (JP to EN) before this LLM era was already high quality, but LLM does a really great job. It does not translate as is, but understands the context, drops unnecessary expressions (important!), and outputs a more natural translation.

      That said, LLM is ofc not perfect, especially when the original text (or Japanese itself) is ambiguous. So I've heavily modified the text too. That's why there are some typos :cry:

  • Nice project, short and concise enough for an undergrad to learn basic os concept and implementation.

  • I almost feel tempted to use your book to both learn about OS and improve my shitty Japanese. :)

    • Thank you. My efforts on preparing both EN/JP translations paid off :D

  • Could you port this to riscv64 please?

    • Porting to any platform is trivial after understanding the basics as described in these articles

      The author explicitly describes why they chose riscv32

      Why would you want the author to use riscv64 instead?

      1 reply →

    • No it's "left as an exercise to the reader" ;)

      But seriously, it's not that hard. Change build options to generate 64-bit ELF, replace all 32-bit-wide parts (e.g. uint32_t, lw/sw instructions), and implement a slightly more complicated page table (e.g. Sv48).

Very delightful article. Based on my experience in "hobby" OS programming, I would add setting up GDB debugging as early as possible. It was a great help in my projects and an improvement over debugging with the QEMU monitor only.

QEMU contains a built-in GDB server, you'll need a GDB client built for the target architecture (riscv in this case) and connecting to the QEMU GDB server over the network.

https://qemu-project.gitlab.io/qemu/system/gdb.html

  • Agree, and I'll add 3 other really useful QEMU features for osdev:

    1) Record & Replay: Record an execution and replay it back. You can even attach GDB while replaying, and go back in time while debugging with "reverse-next" and "reverse-continue": https://qemu-project.gitlab.io/qemu/system/replay.html

    2) The QEMU monitor, especially the "gva2gpa" and "xp" commands which are very useful to debug stuff with virtual memory

    3) "-d mmu,cpu_reset,guest_errors,unimp": Basically causes QEMU to log when your code does something wrong. Also check "trace:help", there's a bunch of useful stuff to debug drivers

  • > you'll need a GDB client built for the target architecture

    Thankfully, GDB has a multiarch build these days which should work for all well-behaved targets in a single build.

    (the place it is known to fail is for badly-behaved (embedded?) targets where there are configuration differences but no way to identify them)

For any rust enthusiasts, phil-opp's guide is such a fun exercise to try out. It was actually the first thing I tried in Rust (very silly idea) and ended up only understanding ~5% of what I had just typed out.

I tried it again 2-3 years later and took the time to go over each subject. I even planned in advance to make sure I was going to finish it.

Very cool to see someone tackling a small OS for RISC-V.

Shameless plug: I've written hobby OS (well, a kernel actually) in Nim for x86-64[0] and it's all documented as well. I put its development on hold until I create a JetBrains plugin for Nim (in heavy development right now).

[0] https://0xc0ffee.netlify.app/osdev

Very cool! I just started to dvelve into RISC-V, and the book I'm reading (not in English) offers their own emulator[1], which, at a glance, is much simpler than QEMU, and comes with a weird license[2]. I wonder if people actually used it, since it looks like an academic project. Maybe I can also follow this tutorial and test it out.

[1] https://github.com/NJU-ProjectN/nemu/tree/master

[2] https://github.com/NJU-ProjectN/nemu/blob/master/LICENSE

Edit: wrong link

I started a toy OS years ago based on the book Operating System Design by Douglas Comer. Personally I just couldn't get excited about anything that didn't run on real hardware, so I made mine for Raspberry Pi.

Is there any real hardware that this could run on?

Looking through this seems to use a lot of assembly. In the above the amount of assembly is kept to a minimum. Pretty much just bootstrapping and context switching. The rest is done in C.

  • Comer was also my introduction to OS design and I still like the approach used in his Xinu books.

    I had a quick glance at the OS in the linked article. This seems to be based on a 32-bit RISC-V with MMU. However, AFAIK, all available RISC-V SoCs with MMU are 64-bit. The 32-bit cores are only used for embedded controllers (unless you want to start designing an FPGA-based system).

    The 32 and 64 bit versions of RISC-V are _not_ binary compatible, but the differences are rather small. Porting the MMU code from 64 to 32 bit or the other way round is not very complex, see my RV32 port of xv6 at https://github.com/michaelengel/xv6-rv32 (the regular MIT xv6 version only supports RV64).

    The major difference is that virtual address translation on RV32, sv32, uses a two-level page table (10 bit index for the first level, 10 bit index for the second and 12 bit offset) whereas there are several modes of translation for RV64. The most common one, sv39, uses 39 bits of the virtual address split into three 9-bit indexes (so you need a three-level page table for 4 kB pages) plus 12 bit offset.

    If you make the modifications, running the OS on real hardware should not be too difficult. The Allwinner D1 is a relatively simply RV64 single code SoC (boards can be found for $20 upwards from aliexpress) and getting the CPU and a UART to work is not that difficult. You can check out my xv6 port to the D1 as a reference: https://github.com/michaelengel/xv6-d1

Very nice, I always enjoy some low-level discussion like this.

I found a small typo/editing glitch on the "RISC-V 101 page" [1]:

- It's a trending CPU ("Instruction Set Architecture") recent years.

It should probably say "ISA" instead of "CPU", and the word "in" is missing from after the parentheses, right?

Edit: Markdown, don't format the quote as code. Oops.

1: https://operating-system-in-1000-lines.vercel.app/en/02-asse...

  • So do I :D

    I was wondering that too. I'll update it with other examples (x86 and Arm).

> The tricky part of creating your own OS is debugging.

The older I get, the more I think I can figure out most problems that don't require some really gnarly domain expertise if I have a good way to iterate on them: code something, try it, see the results, see how they compare with what I wanted. It's when pieces of that are difficult or impossible, or very slow, things get more difficult.

This looks nice! I would love to have an ebook version to read on my ereader. I wonder how much effort it would take to use the markdown files in the GH repo and convert those.

[0] https://github.com/nuta/operating-system-in-1000-lines

I never counted, but my first professional software project was an operating system (firmware) for an RF switching box. It was written in 8085 ASM, and was probably in the neighborhood of 1,000 lines.

Apples to oranges, though. It was a specialized firmware system. Probably the biggest part was the IEEE-488 communications handler.

Two projects mentioned by this one:

  https://github.com/nuta/microkernel-book/
  https://github.com/mit-pdos/xv6-riscv

Just a small typo in the RISC-V 101 chapter. It says "it's a trending CPU (ISA) recent years." I believe it should read "in recent years."

This is on my to do list of things to learn but I also don't know yet the purpose other than it being your own. Maybe security since most of what I work with is on top of the OS eg. programming languages. Maybe for RTOS applications at any rate this and OS Dev good resources.

  • I find this kind of thing most useful for microcontrollers and real-time embedded systems that don't require full networking. I've used many of these concepts but maybe not all at once on what many would call "bare metal" systems with no OS. Audio gizmos like cheap synths, LED nodes, things you want booting really fast with well-bounded functionality. An OS can get in the way with this kind of system if all you really need is some timers and simple I/O. You may still want a primitive scheduler, sane interrupt dispatching, and filesystems.

    • Interesting. Yeah for me it's like RISCV, at the end of the day if it runs windows/Linux do I care what's underneath. I gotta get there to know why it matters. Other than the challenge of doing it.

This looks nice. Thank you! Been considering something like that for quite a while now (Since my own risc-v CPU, written in VHDL, is working actually). I might get this as inspiration and rewrite it in Rust (tm) - Because I wnat to learn Rust, too

The article nicely explains how to build a minimalist OS — works great as an intro material. I think understanding basic OS concepts is essential for performance tuning and debugging.

  • Notice a bunch of downvotes -- Apologies for being unfamiliar with the rules here (I've always been reading HN, but I'm new to commenting). I should've added a lot more details to my previous comment and been more specific. Any other guides would be helpful too. I'll be careful in the future.

    When I learned OS, I followed MIT 6.828 (https://pdos.csail.mit.edu/6.828/2017/overview.html) and implemented a small OS called JOS based on Xv6. So if you're looking for some teaching OS in x86, check it out.

    • I suspect you were downvoted because your comment sounded like it was generated by an LLM.

I’m interested in the use of things like virtio instead of real hardware.

Are there other virtualisation-driven designs for hardware devices out there rather than the qemu stuff?

Ah yes, I have a few (too many as always, but I think that's good, especially when getting older; need to not get complacent) resolutions for 2025, one of them is to write a OS/DB with a development environment. Just to see how far I can take it. So these kind of tutorials are great. I was already going to make it RISC-V first because i'm interested.

A noble idea, but Github is literally littered with hobbyist home-grown Unix-like kernels in C.

As an industry are we not supposed to be trying to move away from hoary old unsafe C?

Could we not have a hobbyist educational OSes in more of the C replacements?

Drew DeVault wrote Bunnix in Hare, in one month. There's the proof of concept.

How about tiny toy Unix-likes in Zig, Nim, Crystal, Odin, D, Rust, Circle, Carbon, Austral?

How about ones that aren't ostensibly suitable for such tasks, such as Go or Ada?

Yes I know Ada is not a good fit, but there has already been a Unix-like OS entirely implemented in a derivative of Pascal: TUNIS.

https://en.wikipedia.org/wiki/TUNIS

This might need work from skilled expert practitioners first. That's good. That's what experts are for: teaching, and uplifting newbies.

There was a project to do C# on the bare metal.

https://migeel.sk/blog/2023/12/08/building-bare-metal-bootab...

How about a Unix-like in C#? Get the Unix and .NET folks interested in this stuff.

Even if the OS never leads to anything, maybe the tooling might prove useful. I am sure someone somewhere would have uses for bare-metal GoLang.

Saying that, I really don't think we need any more Unix-like OSes. There are far far too many of those already. There is a huge problem space to be explored here, and there used to be fascinating OSes that did things no Unix-like ever did.

OSes that are by modern standards tiny and simple but explored interesting areas of OS design, and are FOSS, with code out there under permissive licenses:

* Plan 9 https://github.com/plan9foundation/plan9

* Inferno https://github.com/inferno-os/inferno-os

* Symbian https://github.com/SymbianSource

* Parhelion HeliOS https://archive.org/details/Heliosukernel

There is already an effort at Plan 9 in Rust:

https://github.com/dancrossnyc/r9

Why not Plan 9 in Zig, or Hare, or even D?

Plan 9 imposes and enforces considerably more simplicity on C as it is: you can't #include stuff that already has #include statements of its own. The result is a compilation speedup of around 3 orders of magnitude. That would be a benefit to the would-be C replacements too, wouldn't it?

  • > Yes I know Ada is not a good fit, but there has already been a Unix-like OS entirely implemented in a derivative of Pascal: TUNIS.

    Isn't it? There is a very well-developed kernel written in ADA with SPARK and formally verified at that: https://ironclad.nongnu.org

    And PASCAL-derived languages were very popular for operating systems in the 80s. To name a few: Apple's LISA OS, DEC's VAXELN, and OBERON. There were others as well that didn't quite make it, like DEC's MICA and Acorn's ARX.

    • Thanks for this!

      I did not realise VAXELN was in Pascal. The others I did know of, yes, although Ironclad only from another comment in this thread.

  • Dijkstra famously said that programmers who started with BASIC are "mentally mutilated". But I think this applies a lot more to C and UNIX.

    Most of them don't seem to understand how anything substantially different could exist in the world of computing - every other language and operating system is seen as either an inferior copy, or as another layer of abstraction building on top of C and UNIX.

  • There are very good kernels written in Ada, like Ironclad[1].

    Besides, what's the point of this comment? What if people wanted to write a million more Unix-like kernels in C? Do you think this is bad? Why do you care? If you want, just write your own in whatever language you want, with whatever design you want.

    > Why not Plan 9 in Zig, or Hare, or even D?

    Because nobody to this point was interested in doing this. It's really that simple.

    [1] https://ironclad.nongnu.org/

    • I agree. the GP's comment has a flavour of "people shouldn't like the things I don't like".

      "Make your own kernel" is a thing-in-itself, and "runs on <X> hardware/VM" + "provides <Y>-like API for programs" are tangible, concrete goals to aim for, even if you personally don't like the <Y> API or the architectural choices it implies.

      To give an analogy: https://www.nand2tetris.org/ is an amazing learning experience, even though games other than Tetris should and do exist

      Personally, I like the AROS project, aiming to provide an operating system that implements the AmigaOS APIs and runs on many architectures, but lots of users are interested in running it on 680x0 Amigas and spiritually-related PowerPC devices: https://en.wikipedia.org/wiki/AROS_Research_Operating_System

      It's OK for programmers to write a thing just for the learning experience. If it gains adoptees, that's a happy accident.

    • > There are very good kernels written in Ada, like Ironclad[1].

      Interesting. Thanks.

      > Besides, what's the point of this comment? What if people wanted to write a million more Unix-like kernels in C? Do you think this is bad? Why do you care?

      Because it seems to me that modern OS design is caught in a deep deep rut, and the "OS in 1000 lines" article that we are discussing is digging that rut even deeper.

      Don't repeat the mistakes of the past. Make interesting new mistakes. It's more fun.

      1 reply →

  • OS’s written in Ada included MaRTE OS (open source), Intel’s BiiN system, and the Army Secure Operating System (ASOS) (IIRC).

    The Muen Seperation Kernel (muen.sk) is a secure hypervisor written in SPARK Ada.

    Ada was designed for low-level programming. It makes sense it does operating systems fairly easily. Parts of them will break its safety features. They can be validated with external tools, though.

    Another trick, used in House with H layer, is to wrap the lowest-level parts which you might do in assembly. Build the GC or whatever, too. Then, everything else is in the higher-level language. These data, the lowest-level portions can be specified, verified, and implemented.

    • Fair point.

      I was slightly more getting at it being not a natural fit for a Unix-like OS but I accept your point.

      AFAIK, sadly, Intel BiiN is lost to history now. A Register reader wrote in to me to tell me that he was one of the developers.

      5 replies →

This article brilliantly demonstrates the elegance of simplicity in systems design, proving that even complex concepts like operating systems can be demystified with clarity and minimalism. It's a reminder that understanding fundamentals often unlocks deeper innovation. How might this inspire rethinking other "big" systems?