50

I start my journey to become a hardware / software specialist with an internship in two weeks time and decided to start studying the C language early.

I came across this video, Learn C Programming with Dr. Chuck (feat. classic book by Kernighan and Ritchie), that claims the UNIX OS was written in only 13K lines of code. Which seems a remarkably low number.

Is it true, and if so how did they manage it? Seems completely antithetical to the monolithic monstrosities we know operating systems to be today.

13
  • 5
    What version of Unix do they refer to? Unix has a very long history with a few restarts in there.
    – PMF
    Commented Jan 8, 2023 at 11:16
  • 1
    The book dates from the 70s. So probably a pretty early version.
    – Neil Meyer
    Commented Jan 8, 2023 at 11:17
  • 8
    (It seems the question is received mostly according to the headline "is it true that ..." - if it's rather the one formulated in the last sentence, then you may want to rwrite it accordingly). Why shouldn't a few thousand lines do it? Early Unix was an extreme simple thing. A simple OS can be as short as a few dozend lines of code - especially on simple CPUs. Size comes from the services it provides. Simple OS means short code (and usually vice versa). A basic multittasker for 6502 can be done in about 100 lines Assembly.
    – Raffzahn
    Commented Jan 8, 2023 at 16:12
  • 12
    Well-written code can get a lot of work done in relative few lines. And only few drivers were needed, and the hardware a lot simpler. Commented Jan 8, 2023 at 22:31
  • 5
    Maybe have a look at ed the UNIX editor: Using it, you get a feeling how it is if you get the absolutely necessary only. Then extend the idea to the whole operating system. You cannot compare Linux as it is today with those ancient version of UNIX.
    – U. Windl
    Commented Jan 9, 2023 at 14:59

7 Answers 7

103

If you look at the code in the modern Linux kernel, you will find that most of the code is in the device drivers. There are tens of millions of lines of code to support everything imaginable -- the networking cards in 1990s DEC Alpha workstations, the soundcards in late 1980s ISA IBM PC-compatibles, modern 64-bit ARM tablets, all the USB devices, and so on.

On top of that, we have dozens of file systems, support for many different kinds of networking protocols. There are multiple different schedulers -- not just for processes, but block IO and network transfers. And so on. In fact, the feature variety and hardware drivers make up the great majority of Linux code. Linux, before all these features and bloat were added, as originally released as a crude kernel for 386 machines, was also measured in tens of thousands of lines of code.

I've written a small multitasking kernel, for an embedded application, so I feel qualified to say: it really isn't that big of a job. The basic UNIX design of processes and file system is a structure that has several interworking parts, so it's delicate and finnicky. But it's not ultimately that complex.

Basic memory management takes a few hundred lines. Implementing basic processes takes a few hundred lines. A basic file system takes a few thousand lines of C code. Device drivers depend on the complexity of the device, but can be quite small. You just need drivers for a terminal of some kind, and a disk of some kind.

That will give you the core to load binaries, execute them, and give them some system calls for reading/writing files. That's about all the original UNIX provided. But then you will want networking and fast algorithms for disk caching. It rapidly starts adding up.

4
  • 17
    I have an OS Kernel in 490 dwords. The host machine doesn't have an MMU and the scheduler is vanishing; the OS handles multiple threads accessing the block device so that they don't stomp each other. All system calls are asynchronous.
    – Joshua
    Commented Jan 8, 2023 at 19:55
  • 13
    To add to your comment about device drivers: in the days of early UNIX, your OS would be built for your particular hardware and would only have the device drivers relevant to your machine. Modern embedded systems often do the same thing, and can be tremendously smaller than the standard "desktop" build of the same OS (which includes drivers for everything it might possibly encounter).
    – bta
    Commented Jan 9, 2023 at 16:36
  • 3
    And the devices were very simple. The DEC disk drives had 512b blocks, period. You could read or write one block at a time. You could also seek to a track. But that was it. There were no drive parameters to read or set.
    – John Doty
    Commented Jan 9, 2023 at 21:55
  • 6
    Original UNIX was a small workbench. Modern Linux is a civilization.
    – jeffB
    Commented Jan 10, 2023 at 17:13
75

Yes, and you can buy it in a fully annotated book and have your own copy to peruse, should you be a skeptic:

Lions, John; (1996) "Lions' Commentary on Unix", ISBN 978-1573980135

I have had a copy on my shelf for some time, even though I ported unix to several systems prior to the publication and was familiar with the source of several versions by then. Still an important reference book for learners and gurus alike.

enter image description here

23

That's reasonable.

The first Unix was written in assembly language for the PDP-7 and PDP-11, which had some 16 kB system memory. You can't run a large OS on that! The first versions of the C-based Unixes were built after 1970, when memory was still horribly expensive.

Only in 1980 did 32-bit computers begin to take over in great numbers, and even those started typically with some 4 MB of RAM or even less. This is very similar to today's 32-bit microcontrollers (such as the STM32 or ESP32), for which there exist Linux kernels with a compiled size of about 1.5 MB. They contain more than what the original Linux used to have, but it's reasonable to think that 13,000 lines of C code can get a binary on the order of 500 kB to 1 MB.

3
  • 4
    RSX-11M, which by my estimation had about the same level of capability as early Unix, had an exec ('kernel' to you) which ran in ~24Kb to ~32Kb code, maybe another 16Kb for the file system (which ran as a task) and another 8Kb for MCR (the command interpreter). You could fit a small system into 56Kb (max memory without an MMU), much more reasonable would be a 192Kb 11/40.
    – dave
    Commented Jan 8, 2023 at 13:39
  • @another-dave Yea, that was just a rough estimate. The 500kb are probably exaggerated. The on-disk size of early OSs where more in the order of 100kb, with a memory use of some 20-30kb.
    – PMF
    Commented Jan 8, 2023 at 14:34
  • 5
    And thus the OSes did less than they do today. For example, just speaking of allocating processing power in "cores" - today the kernel is expected to manage efficiently and maybe fairly hundreds of processes, thousands of threads, and complex I/O devices that take queues of requests and return queues of results and do that over many cores - several dozen or more - some of which are not equal in processing power to others - some of which have difference access to different areas of memory than others (NUMA) - and so on and so forth ... whereas on a PDP-7/-11: one "core", etc. etc.
    – davidbak
    Commented Jan 8, 2023 at 17:31
14

Is it true, and if so how did they manage it?

Yes, it is true, as proven by the book linked in Brian's answer.

As to how they managed it: computers are, as a rule of thumb getting more complex over time. Turning that around means that in the past, computers were on average simpler than today. The PDP11 reference manual has around 200 pages (with the PDP-11 being considered the smallest machine having been able to run Unix); the 8086/8088 manual clocks in at 100 pages for the CPU itself but takes 800 in total to describe additional I/O processors and other relatively important parts of the architecture. The 1993 manuals for the Pentium Family already span around 1900 pages, and well past 2000 for the IA-64 docs.

This means all aspects - the hardware itself (from CPUs over the general architecture to ancillary modules like GPUs, or even math co-processors back in the foggy past), but also the software (i.e., features expected by programmers or users), the networking, and so on and forth, got ever more complex; and at the same time, users expected the OS to handle all of that in lieu of the applications ever more.

Many of these complexities scale up exponentially in that adding one feature in one of those areas influence many of the others, thus leading to additional lines of code in many places.

So even if a completely new OS today had zero baggage in the form of backward compatibility, or having to support large numbers of historic hardware devices, it would be much larger than in the distant past simply because the system architecture (CPU, GPU, I/O, RAM, and other low-level modules, together with busses and so on) is vastly more complex on even small machines today than it was in the past.

(As a little bonus: you can run a PDP-11 emulator with the Unix v6 kernel in your browser of choice (including access to cc so you can compile programs). It doesn't do much for this answer, but I find it awesome enough to include it. Here is the deep link to the actual JavaScript code of the emulation. Imagine how long this code would be for a modern CPU...)

3
  • 3
    Does this mean that we can prove that there was a "big bang" of computers, since they kept getting simpler as time goes backwards? :)
    – Barmar
    Commented Jan 9, 2023 at 15:28
  • 2
    Absolutely, @Barmar! The question is just which you count as "first". :) Zuse Z1? Babbage's? The abacus?
    – AnoE
    Commented Jan 10, 2023 at 7:39
  • 2
    But unlike cosmology, it took a while for "inflation" to kick in (once with electronic computers in WWII, again with microchips in the 70's).
    – Barmar
    Commented Jan 10, 2023 at 16:44
9

An additional reference point, Minix:

MINIX 1.0

Andrew S. Tanenbaum created MINIX at Vrije Universiteit in Amsterdam to exemplify the principles conveyed in his textbook, Operating Systems: Design and Implementation (1987). (Despite sharing a name, it has no relation to the older MINIX from Digital Systems House, Inc. based on AT&T Unix code.)

An abridged 12,000 lines of the C source code of the kernel, memory manager, and file system of MINIX 1.0 are printed in the book. Prentice-Hall also released MINIX source code and binaries on floppy disk with a reference manual. MINIX 1 was system-call compatible with Seventh Edition Unix.

(emphasis mine)

8

Early time-share systems could not hold two programs in memory at once. All task switching was accomplished by swapping a program's entire state out to disk. This would obviously be slow by modern standards, but the use of line-based I/O meant that a task switch would often only be necessary when a user finished typing a line of input. Further, task switching would use dedicated areas of the hard disk so as to avoid directory look-ups or other such overhead.

Understanding this is critical to understanding the design rationale for fork(). If a computer is running task #4, and it needs to give task #5 a time slice, it would need to save its current state to slot #4 on the hard disk, load task slot #5 from the hard disk, and resume execution. If a program running task #5 wanted to fork(), and there was no task #6, it could add slot #6 to the list of active tasks, and save its state to slot #6, and resume execution without loading a task from the disk. Forking a task was thus faster than doing a normal task switch, since it only required saving the current state and not retrieving an old one. It was also easier than creating a new task with specified parameters, since doing that would require building an image of what the new task should look like, while forking could exploit the already existing task as a model.

A lot of the complication surrounding Unix memory management today stems from the need to have multiple tasks in memory at a time, with the usable memory divided up dynamically among them. If it had been acceptable to simply give each task a fixed allocation which it could use as it saw fit, as had effectively been the case in the full-RAM-swap era, things could have been much simpler but it would have been necessary to let the system know, before running a program, how much memory it should be given. Such restrictions existed in the Macintosh OS which I used a lot in the 1980s and 1990s, and while they were at times annoying, they offered some advantages which might still be nice today (e.g. if one could control how much memory was available to different browser tabs).

-3

Unlike previous OSes, UNIX provided the pipe facility to allow you to combine the functionality of many small programs.

Ex. ls | grep ... | sort ... | more

Before that, every command-line program had to support the full suite of additional functionality like search, filtering, paging, etc. This UNIX/Pipe approach allowed for greater reuse and much less code. This is explained and simulated in this video: https://www.youtube.com/watch?v=3Ea3pkTCYx4

5
  • 1
    Absent pipes, that N different commands would need to include 'whatever' functionality does not mean that there's N different source files implementing 'whatever'. There exists the concept of libraries.
    – dave
    Commented Sep 11, 2023 at 13:40
  • 3
    You are talking about the programs. Not about the OS.
    – Justme
    Commented Sep 11, 2023 at 13:45
  • I would say that the shell and programs like ls, ps, grep, sort, more, etc. are part of the UNIX OS. Both in terms of utility and line count. Commented Sep 12, 2023 at 15:10
  • pipes were not in the original version of unix, but added later. Commented Sep 15, 2023 at 6:35
  • Yes, the original version of unix didn't have pipes until they were suggested by Douglas McIlroy. But at that point unix hadn't been released yet and was just an internal project. So, as far as anyone outside of AT&T or of the unix project was concerned, it has always had pipes. I talked to Douglas McIlroy about this, and I forget who, but someone said that "unix wasn't unix until it had pipes". Commented Sep 16, 2023 at 13:11

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .