If the style looks familiar, it's because it mimics the famous Lions UNIX v6 source code book: http://v6.cuzuco.com/v6.pdf
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.
Xv6 is also written in a more modern coding style, using stuff like C99 initializers. It runs on modern hardware, even supporting SMP.
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.
* https://blog.darknedgy.net/technology/2016/01/01/0/ (https://news.ycombinator.com/item?id=10824382)
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?
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.
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.
No, they won't.
What?! Linus, is that you?
In fact, Xv6 was derived from the UNIX v6. You can think of it as an x86 port of UNIX v6.
xv6, on the other hand, is just bare kernel with no functional purpose.
They're both brilliant.
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?
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 :)
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.)
but the authors (probably because of lack of time and/or academic obligations) seem to ignore them.
Some "basic" (actually very involved, but the modern-day PC is hell) requirement to get it to run on physical hardware past 2020 is UEFI support. USB keyboard support is probably also a hard requirement nowadays and would basically require a full USB stack.
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
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.
If not, the OSDev.org wiki is a pretty good starting point: https://wiki.osdev.org/Expanded_Main_Page
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.
> 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."
Seems fine. It’s hardly worth noting. May as well write “Minor” and use your time more efficiently.