posted by Werner "murphee" Schuster on Mon 1st Mar 2004 07:32 UTC
"NachOS, Page 2/2"
Virtual Memory and software-managed TLB

This assignment (the last I had to do in my course), is all about virtual memory. To be clear: this concerns the whole swapping related parts of the memory system; ie. moving parts of the memory from RAM to some backingstore on the systems hard disk (I mention this, since there seems some confusion about the terms, since memory protection (with page tables,... etc.) is also called virtual memory). There is nothing spectacular here, and no code is provided by Nachos for this task.

The other part of this assignment is more interesting. In the previous assignment, memory protection was implemented by use of page tables, ie. each address space had a page table in a specific format, and at a context switch, the MIPS CPU was given a pointer to the current page table. This is basically the method, that the x86 CPU uses. I was somewhat surprised, when I heard about software-managed TLBs. I knew about TLBs but only in the x86 way, where they are just a cache for the pagetable. On the x86, you don't know about the TLB, and you actually can't explicitly modify it (you can only flush it using a trick, ie, changing the control register that stores the address of the page table). Few (if any?) RISC CPUs use this approach, but instead have a software managed TLB, where it's the OS' task to set the entries, and the CPU never actually sees the page table. This approach means some considerable (not immense, but not trivial either) change in the way the memory system works. Due to the limited size of the TLB, the OS now has to implement the cache behaviour for the TLB (ie. the CPU needs the page translation for page x but the TLB is full, which page translation entry can/should be thrown out now, etc.).

Filesystem and Networks assignments

These are actually two assignments, but I haven't done them, so I can't talk much about them. The file system interface is actually already available in the 2nd assignment, ie. you can use the file system from the Nachos kernel and the userspace applications (by way of the syscall interface); the reason is, that in that assignment, all calls to the file system are simply mapped to the host OS' filesystem. This is a rather useful approach, since it allows using the FS early on without actually having to deal with sectors, cylinders etc., and if you have finished your own FS, just one line in a Makefile has to be changed to let the kernel use it instead of the host OS' FS.

Problems

Working with Nachos has certainly been an interesting experience... although some aspects of the system are less than ideal.

  • Code quality:
    Nachos is written in C++ ... kind of. This is not modern, high level C++, but actually your grandfathers C++, basically C with classes. Nachos is a nice example of a software project that uses an OOP language, but is not even remotely object oriented. To cut a long story short, classes are only used to emulate namespaces (to avoid having to give function names prefixes, as is customary in C) and as somewhat more convenient structs.
    Neglect of OOP features isn't the only problem with the source. There are some hacks in the code that just seem out of place and just aren't good style (I won't go into detail here, if you're interested, get the code).
  • User space multithreading:
    In the course of working through the assignments, you'll turn Nachos into a preemptive OS. After you've done that, you'll certainly want to show of the capabilities of your OS, for instance by having several applications output stuff at the same time (you know, application A outputs "A", application B outputs "B" which should get you a nice output of something like "AABABABBBBAABABA", depending on the implementation of your scheduler).
    Cool. Until you try launching several applications from a shell (a sample shell is provided). The problem? Well, a command line shell is basically just a process doing a read() call on STDIN. This call is blocking, meaning the application is halted until this call returns (ie. when some data is entered). Now, in a preemptive OS, this should not be a problem; a blocking app is simply not scheduled to run and other apps get their share of CPU time, nothing special about that.
    The problem is Nachos homegrown, userspace thread model. The downside of userspace threading is that a blocking call to an OS syscall, blocks all threads in the process' address space. As each process in Nachos is mapped to a Nachos thread, this means that a blocking call (like read()) will block the whole system, ie. all processes.
    This means, that you cannot have an interactive shell in Nachos to launch background processes and that one application invoking a blocking call will halt the whole OS.
    People have found ways to get around this situation, but they are only hacks and don't solve the real problem. (In case you're wondering: the trick is to use select() for all blocking I/O. You use select() in a loop and set a short timeout on the operation. If the function returns, you either have data, in which case you'll exit the loop; if you don't have any data, this means the timeout kicked in; you now call yield() which tells the scheduler to let other threads work. When the thread gets control again, you simply continue in the loop and call select() again).

Conclusion and References

Nachos is a great system for teaching OS technoloy. Its use of an emulated CPU allows very realistic insights into the work of OS developers, while hiding some annoying low level details.

The future

Nachos is a rather old project and is in its second decade already. It shows its age, as I already mentioned, in the Problems section of this text. Some of those problems might be solved by Nachos 5.0j, which is a port of the C++ code to Java. One major advantage is that Nachos finally gets a 1:1 threading system and does not have to rely on the crufty userspace threading model it has been using.

References
  • Nachos' Home. Here you can find several versions of the Nachos distribution and all the documentation you'll need.
  • Nachos 5.0j The Java version of Nachos.
  • Mini Stdio for Nachos programs This is a small library including a version of printf() that can be used with applications that run on the Nachos OS. This will come in handy, as using the normal Write() syscalls is quite tedious. It might be somewhat buggy and/or incomplete, but it works.

About the Author:
"murphee (Werner Schuster) is a student at the TU Graz, Austria, where he dabbles in Software Engineering matters. His interests besides Operating Systems are anything concerning Java (mostly the Virtual Machine internals). Find his Weblog here."

Table of contents
  1. "NachOS, Page 1/2"
  2. "NachOS, Page 2/2"
e p (0)    16 Comment(s)

Related Articles

posted by David Adams on Sat 6th Sep 2008 14:29 submitted by Adam Dunkels
posted by David Adams on Wed 13th Aug 2008 16:57, submitted by irbis
posted by Thom Holwerda on Fri 8th Aug 2008 20:47, submitted by ebasconp