
Xv6, a simple Unix-like teaching operating system - rspivak
https://pdos.csail.mit.edu/6.828/2017/xv6.html
======
ArtWomb
A great (and free) companion textbook to any introductory OS class is Three
Easy Pieces:

[http://pages.cs.wisc.edu/~remzi/OSTEP/](http://pages.cs.wisc.edu/~remzi/OSTEP/)

~~~
goodells
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.

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

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

------
rdh
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.

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

~~~
Koshkin
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.

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

~~~
jermaustin1
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.

------
KenoFischer
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/](http://os161.eecs.harvard.edu/)

~~~
sassy_samurai
How does OS/161 compare to xv6?

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

~~~
burfog
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.

~~~
pcwalton
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.

~~~
module0000
> 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.

~~~
JdeBP
> _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=15642116)

* [https://news.ycombinator.com/item?id=15634014](https://news.ycombinator.com/item?id=15634014)

* [https://news.ycombinator.com/item?id=15697888](https://news.ycombinator.com/item?id=15697888)

* [https://news.ycombinator.com/item?id=15641592](https://news.ycombinator.com/item?id=15641592)

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

~~~
pcwalton
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.

------
pieterr
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](https://en.wikipedia.org/wiki/MINIX)

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

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

~~~
namanyayg
His son; Morris Senior passed away in 2011.

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

They're both brilliant.

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

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

~~~
grkvlt
That's the joke...

------
joebergeron
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.

------
lkurusa
My school used Pintos from Stanford, which is also a great introduction to
operating systems:
[https://web.stanford.edu/class/cs140/projects/pintos/pintos_...](https://web.stanford.edu/class/cs140/projects/pintos/pintos_1.html)

------
userbinator
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.

------
wolfgke
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](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.

~~~
sigjuice
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.

~~~
wolfgke
Look at the open pull requests.

~~~
sigjuice
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.

~~~
wolfgke
Counterexamples:

Optimization: [https://github.com/mit-
pdos/xv6-public/pull/24/files](https://github.com/mit-
pdos/xv6-public/pull/24/files)

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

Bugfix in build system: [https://github.com/mit-
pdos/xv6-public/pull/34/files](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](https://github.com/mit-pdos/xv6-public/pull/43)

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

Bugfix: [https://github.com/mit-
pdos/xv6-public/pull/51/files](https://github.com/mit-
pdos/xv6-public/pull/51/files)

Improvement in console system: [https://github.com/mit-
pdos/xv6-public/pull/62/files](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.

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

~~~
teraflop
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](https://wiki.osdev.org/Expanded_Main_Page)

------
jpeg_hero
Nachos at UC Berkeley

[https://en.wikipedia.org/wiki/Not_Another_Completely_Heurist...](https://en.wikipedia.org/wiki/Not_Another_Completely_Heuristic_Operating_System)

~~~
apengwin
Berkeley's undergrad OS class now uses Pintos

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

~~~
bitcoinmoney
it uses the qemu

~~~
dev510213
oh ok, that makes sense. thanks

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

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

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

~~~
0culus
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.

~~~
steveklabnik
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 :)

------
bitcoinmoney
is there are resource like this but for computer networking?

------
shawn
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?

~~~
mav3rick
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 :)

~~~
shawn
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.)

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

~~~
tonysdg
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](https://en.wikipedia.org/wiki/MINIX_3#History)

------
fernly
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](https://github.com/mit-
pdos/xv6-public)

~~~
shawn
For [https://github.com/mit-
pdos/xv6-public/commit/6389d9d4103eae...](https://github.com/mit-
pdos/xv6-public/commit/6389d9d4103eaebdd4749cacf475014e525a1c9a)

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

