Hacker News new | comments | ask | show | jobs | submit login
Xv6, a simple Unix-like teaching operating system (mit.edu)
354 points by rspivak 7 months ago | hide | past | web | favorite | 79 comments

A great (and free) companion textbook to any introductory OS class is Three Easy Pieces:


This book rocks! I took the OS class with Remzi’s wife my junior year and it was the one that made everything “click”, bridging the gap between the computer engineering/circuits and higher-level C code we otherwise did. OSTEP and Xv6 were really integral for understanding things inside and out because we had to implement what we learned about in class.

Isn't Andrea (Remzi's wife) a co-author of OSTEP?

Yeah, I probably should have referred to her by name. Remzi seems to be the best-known professor in the CS department here.


This is a really great book for anyone interested. My professor used this in place of the more traditional book by Tanenbaum. It's easy to read and provides good citations if you want to read more in-depth about a specific chapter.

While its available completely free online, I highly recommend anyone who plans on using the book in detail to purchase a printed copy on lulu, its pretty cheap and looks really nice

+1 for 3 easy pieces. To me it felt the most natural book on operating systems.

Such a great book! As someone who came from a non-traditional background, this book was very key in helping me understand operating systems.

It's incredibly helpful to learn by example, in my opinion. My university course taught using Xv6 as well, and the exams often included a problem where you were asked to modify a portion of the code to change behavior in a particular way (we were also asked to have the entire code printed out for reference during the exam). Probably one of my favorite courses.

Yikes, what a waste of paper. Hopefully you could borrow it from the library or buy a used copy at the bookstore.

Indeed, speaking of many other OS this could be a real problem. The PDF containing the Xv6 source code, on the other hand, is about 100 pages long.

It is linked from the page and is precisely 99 pages: https://pdos.csail.mit.edu/6.828/2017/xv6/xv6-rev10.pdf

If the style looks familiar, it's because it mimics the famous Lions UNIX v6 source code book: http://v6.cuzuco.com/v6.pdf

100 pages doesn't seem like a waste of paper to you?

It is basically a textbook. If they were trying to limit access to electronic devices to minimize the chance of cheating, this makes sense.

I think it should have been provided for you so you didn't blow through your personal ink or have to pay student services to do it.

There's also OS/161, which was written for Harvard's CS161 course and is used by a bunch of other places also: http://os161.eecs.harvard.edu/

How does OS/161 compare to xv6?

MINIX was also created for teaching. Is there a comparison of Xv6 vs. MINIX pros and cons for teaching?

Aside from being small, Xv6 is a normal OS. MINIX was designed to chase the gravely ill-advised microkernel fad that took over academia. You can lump Xv6 in with Linux and BSD, while lumping MINIX in with GNU HURD. The trouble is that glue isn't free: breaking an OS down into simple parts doesn't make the OS simple; the resulting interactions between simple parts become complex.

Xv6 is also written in a more modern coding style, using stuff like C99 initializers. It runs on modern hardware, even supporting SMP.

The jury is still out on microkernels being "gravely ill-advised". Fuchsia, for example, is a modern microkernel that works quite well.

The performance concerns that famously killed the microkernel hype are very old at this point. Modern hardware significantly reduces IPC overhead. And lots of the modern application stack (e.g. multiprocess browsers) essentially cobble together microkernel primitives out of comparatively-clunky OS features (e.g. cmsg on Unix).

I think most of Linux's success relative to microkernel designs was due to being in the right place at the right time, not due to any fundamental technical factors.

> Modern hardware significantly reduces IPC overhead.

In case you see this comment 5 days later, can you elaborate? And do the benefits of modern hardware in this area automatically apply to IPC on existing mainstream systems, or does the OS have to specifically use the new support?

It might be for some things like performance but they're very successful for small, reliable OS's in embedded scene. Tanenbaum cited a bunch in round 2 of the debate with Torvalds:


> The jury is still out on microkernels being "gravely ill-advised". Fuchsia, for example, is a modern microkernel that works quite well.

They could have said "gravely ill-adopted". You know what they meant and are grinding your personal axe here... Microkernels for all their promise aren't in widespread use. Engineers with a resume headline "I build monolithic kernel operating systems for fun" vs "I build microkernel operating systems for fun" will have significant hiring delta biased towards the monolithic specialists.

> Microkernels for all their promise aren't in widespread use.

Ah, you haven't heard about MINIX, the operating system used in the ME in modern Intel chipsets and possibly now one of the most widely deployed operating systems on the planet.

* https://news.ycombinator.com/item?id=15642116

* https://news.ycombinator.com/item?id=15634014

* https://news.ycombinator.com/item?id=15697888

* https://news.ycombinator.com/item?id=15641592

The thing that everyone hates and wishes wasn't there?

It would be worse if it were a monolithic kernel. If you're going to deploy an always-on OS in the firmware, you should at least use an OS that obeys a sensible principle of least privilege.

I think if you have the title "I build X kernel operating systems for fun" as a resume headline, you are in high demand regardless of X.

Practically every modern phone platform happens to include a microkernel. Pretty widespread.

> Engineers with a resume headline "I build monolithic kernel operating systems for fun" vs "I build microkernel operating systems for fun" will have significant hiring delta biased towards the monolithic specialists.

No, they won't.

>the gravely ill-advised microkernel fad

What?! Linus, is that you?

You can lump Xv6 in with Linux and BSD

In fact, Xv6 was derived from the UNIX v6. You can think of it as an x86 port of UNIX v6.

I'd like to see any comparison extended to include Pintos as well: https://en.m.wikipedia.org/wiki/Pintos

MINIX is much, much closer to being a fully working OS. Hell, you can run X11 on it, it can recompile itself, it has a package manager.

xv6, on the other hand, is just bare kernel with no functional purpose.

Minix is microkernel based while Xv6 appears to be monolithic.

One of the people, Frans Kaashoek, has been involved in Minix as well, an OS from the 80s, also created for educational purposes at the time.

[1] https://en.wikipedia.org/wiki/MINIX

And another of the people, Robert Morris, helped found ycombinator

The NSA Robert Morris, or his son the Internet Worm Robert Morris?

His son; Morris Senior passed away in 2011.

I thought he passed on, but wasn't in a position to easily confirm.

They're both brilliant.

Can't wait for Intel to put this onto every one of their processors!

Intel’s already put Minix on every one of their modern processors as the embedded ME OS.

That's the joke...

OSes aside, the only good thing Intel can do is to throw ME out of the window. This monster MUST die!

Ah, I have fond memories of staring at pages of Xv6 code. I took the OS class, 6.828, which uses Xv6 as a reference, while an undergrad at MIT. While relatively simple compared to most anything else you could think up, it gave great insight and intuition into code style and idiomatic OS patterns for working on JOS, the more substantial OS you end up writing in that class.

My school used Pintos from Stanford, which is also a great introduction to operating systems: https://web.stanford.edu/class/cs140/projects/pintos/pintos_...

Does anyone know how to extend xv6 with copy-on-write? I was implementing a multiprocessing lib based on xv6 but noticed a fork copied the entire parent page table.

I think it’s a matter of extending the page fault routine to check whether the missing page is flagged copy on write, but I wasn’t sure how to correctly track which source page it should be copied from. Every process has its own clone of the page table hierarchy, so how do you know which one to grab during the fault?

When you fork, your forked process get a copy of the parent's page table i.e. at this point it points to the same physical page for xyz address as the parent. There can be a metadata bit in the final PTE that says this page is COW (Copy on Write). For context, in a 32-bit system 2 Level page table with 4KB pages means only 20 bits are used in the final page table to get the page frame. There are 12 bits free for some metadata.

Your forked process already has the physical page frame number and the COW bit. If it's a write/modify on that page and the COW is set, your code should allocate a new physical page, copy the raw contents of the currently mapped physical page and then finally update the page table entry with this new physical page frame number. If you want an example with some numbers, I can reply further. Let me know :)

Thanks! This was very helpful.

If you want an example with some numbers, I can reply further.

I appreciate that. I learn best from working models. But in this case, the solution after you pointed it out is extremely obvious: if the COW bit is set, unset it and alloc+copy the page. No other information is needed.

Perhaps you know of a similarly elegant solution to the other half of what I’ve been struggling with: xv6 is 32 bit, and gives little insight on how to do paging on a 64 bit architecture. So I have two questions.

1. I notice that although pages are 4KB, xv6 uses 4MB (large paging support). How does this impact the two-level page table design? Does it simply mean that fewer entries are required, but the design is unchanged?

2. On a 64 bit architecture, what are the fundamental differences between the 2 level page table design and whatever people do in practice? This is phrased poorly. What I mean is: I am trying to blindly extend xv6’s design for a 64bit environment, but I am concerned the design might need to change. Is that true, or do people do the same thing on 64 bit? I haven’t had time to think this through yet.

To put it more simply, is there anything I should watch out for on 64 bit when doing this? Or perhaps some overall simplification / better design for 64 bit that can’t be done on 32 bit?

These are mostly speculative questions, so perhaps I should wait until I’m stuck before asking. But your answer was insightful.

I’m trying to make something people will use, and xv6 has been my only model to learn from. Any advice or references about 64 bit design for multiprocess scheduling would be useful. Especially in contexts where performance and parallelism is the concern, not necessarily security. (Anything to do with GPU design would be a delightful bonus. But I do still need traditional function calls + lexical closures.)

What a pity that lots of people seem to want to create (often small) enhancements to xv6

> https://github.com/mit-pdos/xv6-public/pulls

but the authors (probably because of lack of time and/or academic obligations) seem to ignore them.

I mean, it's basically licensed under MIT. If somebody really wants to do something with the OS, they can just go and fork it, then get everybody else to hack on that instead. Given upstream is dead, it shouldn't be too hard to gain traction.

Some "basic" (actually very involved, but the modern-day PC is hell) requirement to get it to run on physical hardware past 2020[1] is UEFI support. USB keyboard support is probably also a hard requirement nowadays and would basically require a full USB stack.

[1] https://arstechnica.com/gadgets/2017/11/intel-to-kill-off-th...

Rather than incorporate them into the software, small enhancements are the sort of thing the authors of the project would prefer to leave as exercises for students, I'm sure.

If you read through the comments of the closed pull requests you will get some idea of the type of enhancements that the maintainers expect.

Look at the open pull requests.

If I have read through the closed PRs, then obviously I have looked at the open PRs too: Makefile trivialities, homework solutions, and duplicates. Not a whole lot there.


Optimization: https://github.com/mit-pdos/xv6-public/pull/24/files

Improvement in build system: https://github.com/mit-pdos/xv6-public/pull/33

Bugfix in build system: https://github.com/mit-pdos/xv6-public/pull/34/files

Making code more standard compliant (assigning a function pointer to a void pointer is undefined behavior): https://github.com/mit-pdos/xv6-public/pull/43

Enable building on FreeBSD: https://github.com/mit-pdos/xv6-public/pull/50

Bugfix: https://github.com/mit-pdos/xv6-public/pull/51/files

Improvement in console system: https://github.com/mit-pdos/xv6-public/pull/62/files


Also concerning your "homework solutions" argument: The fact that these PRs are not closed is also a strong point for my argument.

Any tips for understanding the lowest level code like the bootloader? It seems to be pretty opaque to me.

At a glance, the code seems reasonably well commented, but it definitely assumes some prior familiarity with x86 hardware. Do you have any specific questions?

If not, the OSDev.org wiki is a pretty good starting point: https://wiki.osdev.org/Expanded_Main_Page

There's some documentation in appendix B of their book: https://pdos.csail.mit.edu/6.828/2017/xv6/book-rev10.pdf

Berkeley's undergrad OS class now uses Pintos

IMHO the source code is an example of good C style, and certainly quite pleasant to read --- no excessive verbosity, gratuitous indirections, PretentiouslyCapitalisedObscenelyLongIdentifiers, unnecessarily huge indents, or any of the other annoyances I tend to find with more "modern" source code. With the exception of a few minor stylistic choices I would've done differently, it's extremely close to my preferred source style.

Unfortunate that it isn't quite completely C89 (in particular regarding placement of variable declarations), since C89 compilers are much simpler than C99 ones and otherwise a compiler course could've been created around writing a compiler (and assembler) that can compile itself, Xv6, and then itself run inside Xv6 --- to become a self-contained, self-bootstrapping OS.

Can someone briefly explain how does one go about using this (for self learning)?

it uses the qemu

oh ok, that makes sense. thanks

Any place where you could get a disk images to try to spin this up in a VM?

You can just run make. It doesn't need a cross compiler or anything weird on x86.

It doesn't compile on Windows though, which is a bummer: some of the files have names like COM, which are reserved.

Both my undergrad and grad OS courses used xv6 and I can tell you that the easiest way to get hacking on it is to spin up a VM (I used vagrant for this since I just wanted headless) and run it in QEMU. MIT has a patched version available that has some handy debug features. Feel free to contact me through keybase and I can provide you all the scripts I used.

Thank you! In the end, the source is so easy to read that I didn't actually need to build it all that much, but if I ever do, I'll get in touch :)

Compile it in a linux / bsd VM, too.

WSL does the trick on Windows.

is there are resource like this but for computer networking?

Cool, is this Unix like teaching operating system going to be clandestinely installed on all future Intel CPUs like Minix was?

Made me laugh (thanks for that!), but in fairness, MINIX 3 was designed for actual usage and not just education. From Wikipedia [1]:

> Although it still serves as an example for the new edition of Tanenbaum and Woodhull's textbook, it is comprehensively redesigned to be "usable as a serious system on resource-limited and embedded computers and for applications requiring high reliability."

[1]: https://en.wikipedia.org/wiki/MINIX_3#History

Wikipedia says that there's a least one company using it for an ARM TrustZone kernel[1], but I can't seem to verify that on the linked vendor's home page.

[1] https://en.wikipedia.org/wiki/Xv6#Production_Use

Looking at the github repo [1] I am immediately underwhelmed by the commit messages. "nothing much," "nits," "nit". Really?

[1] https://github.com/mit-pdos/xv6-public

For https://github.com/mit-pdos/xv6-public/commit/6389d9d4103eae...

Seems fine. It’s hardly worth noting. May as well write “Minor” and use your time more efficiently.

Have you seen the diffs for those commits? What else do you suggest should go in the messages for such commits?

Applications are open for YC Summer 2019

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact