Unix provides file utilities callable from the shell as user-level programs, for example mkdir,
ln, and rm. This design allows anyone to extend the command-line interface by adding new user-
level programs. In hindsight this plan seems obvious, but other systems designed at the time of
Unix often built such commands into the shell (and built the shell into the kernel).
One exception is cd, which is built into the shell (user/sh.c:160). cd must change the current
working directory of the shell itself. If cd were run as a regular command, then the shell would
fork a child process, the child process would run cd, and cd would change the child ’s working
directory. The parent’s (i.e., the shell’s) working directory would not change.
1.5 Real world
Unix’s combination of “standard” file descriptors, pipes, and convenient shell syntax for operations
on them was a major advance in writing general-purpose reusable programs. The idea sparked a
culture of “software tools” that was responsible for much of Unix’s power and popularity, and the
shell was the first so-called “scripting language.” The Unix system call interface persists today in
systems like BSD, Linux, and Mac OS X.
The Unix system call interface has been standardized through the Portable Operating System
Interface (POSIX) standard. Xv6 is not POSIX compliant: it is missing many system calls (in-
cluding basic ones such as lseek), and many of the system calls it does provide differ from the
standard. Our main goals for xv6 are simplicity and clarity while providing a simple UNIX-like
system-call interface. Several people have extended xv6 with a few more system calls and a sim-
ple C library in order to run basic Unix programs. Modern kernels, however, provide many more
system calls, and many more kinds of kernel services, than xv6. For example, they support net-
working, windowing systems, user-level threads, drivers for many devices, and so on. Modern
kernels evolve continuously and rapidly, and offer many features beyond POSIX.
Unix unified access to multiple types of resources (files, directories, and devices) with a single
set of file-name and file-descriptor interfaces. This idea can be extended to more kinds of resources;
a good example is Plan 9 [13], which applied the “resources are files” concept to networks, graph-
ics, and more. However, most Unix-derived operating systems have not followed this route.
The file system and file descriptors have been powerful abstractions. Even so, there are other
models for operating system interfaces. Multics, a predecessor of Unix, abstracted file storage in a
way that made it look like memory, producing a very different flavor of interface. The complexity
of the Multics design had a direct influence on the designers of Unix, who tried to build something
simpler.
Xv6 does not provide a notion of users or of protecting one user from another; in Unix terms,
all xv6 processes run as root.
This book examines how xv6 implements its Unix-like interface, but the ideas and concepts
apply to more than just Unix. Any operating system must multiplex processes onto the underlying
hardware, isolate processes from each other, and provide mechanisms for controlled inter-process
communication. After studying xv6, you should be able to look at other, more complex operating
systems and see the concepts underlying xv6 in those systems as well.
19