C:\1990S\LINUX.TXT
1991
Linux: A Working Kernel Invited More Work
Linux's early public releases combined a useful Unix-like kernel with visible limitations, available source, and a practical invitation to improve the system.
A kernel is an unusual thing to release to the public. It is essential software, but by itself it gives a person remarkably little to do. There is no convenient application window in which to admire the accomplishment. A working system needs programs, libraries, a usable filesystem, and hardware that the kernel knows how to operate.
Linux’s first releases made that distinction explicit. Their significance came from providing working machinery and source that interested people could inspect and change. Their documentation also supplied a fairly substantial list of things that didn’t work yet.
That candor is part of the history. A development project can grow when someone else can reproduce enough of it to discover a useful next problem. The first Linux kernel gave other programmers something more actionable than an attractive diagram of a future operating system.
An announcement became a set of sources
Linus Torvalds’s preserved announcement is dated August 25, 1991, in the comp.os.minix newsgroup. Writing from the University of Helsinki, he described a system for 386/486 AT-compatible computers and asked what features other users wanted. His own 1992 collection of early messages preserves the announcement and places the first source release around mid-September, without establishing an exact day.1
The distinction is useful. Asking for reactions to a developing system and distributing its source are related events; they aren’t the same event.
Version 0.01’s release notes identify a kernel requiring machine-specific configuration and compilation. Supported hardware was narrow, and some system calls were incomplete. The notes describe the release as particularly useful for people interested in reading the source.2
Torvalds had developed it using MINIX, but Linux was a separately written implementation. Early filesystem compatibility helped with bootstrapping and moving data; it did not turn Linux into a copy of the MINIX kernel.2
This was also a hardware-specific beginning. The initial design took advantage of the Intel 386’s facilities rather than starting with broad portability. The modern variety of machines on which Linux runs belongs to later engineering work. A successful future cannot retrospectively make the first implementation portable.

Dirk Hohndel, left, and Linus Torvalds, right, at LinuxCon Europe in Düsseldorf, October 15, 2014. Later photograph by Krd, source, CC BY-SA 4.0. No alterations.
The kernel isn’t the whole workstation
Torvalds’s October 10, 1991 description points readers to version 0.03 and lists the surrounding software needed to make it useful. Bash supplies a shell. GCC and related tools supply a development environment. Libraries connect application code to available services. GNU utilities supply familiar operations on files and text.3
These components have distinct responsibilities. A shell reads a command and arranges to run a program. A compiler translates source code. The kernel manages processes, memory, and access to devices. Calling all of that “Linux” in everyday conversation can be convenient, provided it doesn’t erase where the work came from.
The October document credits other contributors and existing projects, including Bruce Evans, Earl Chew, Alain W Black, Richard Tobin, GNU, and Alfred Leung’s keyboard patches.3 An early kernel still depended on a considerable amount of previous and collaborative work.
A conceptual command makes the division clearer. A user types a request to compile a program. The shell locates and starts the compiler. The compiler reads source and creates output. Those actions require kernel services for processes and files. The kernel doesn’t understand the program’s C declarations merely because the compiler runs on it.
That separation also explains why source compatibility mattered. An application written for a Unix-like environment expects particular operations and interfaces. Implementing enough of those expectations lets existing software become useful on the new kernel. Missing library functions or system calls can interrupt the arrangement even when the kernel boots successfully.
Booting is a milestone. It is an exceptionally early place to stop measuring usefulness.
Make a new process without copying everything immediately
Memory management offers a concrete way to understand the early kernel’s engineering. The 0.01 notes describe using paging and segmentation, sharing pages after a fork, and copying them when a write requires it. The preserved implementation in mm/memory.c shows the relevant page-table copying and write-protection handling.4
fork creates a child process whose memory initially has the same contents as its parent’s. Conceptually, the two processes need separate states: if the child changes one of its ordinary private values, that must not unexpectedly change the parent’s value.
One way to arrange this is to copy all the relevant memory immediately. Another is copy on write. The processes can initially refer to the same physical data pages while the kernel arranges to separate a shared page when a write makes separation necessary.
Here is an invented model with three data pages, A, B, and C. Page-table storage, kernel state, and every other overhead are omitted so that the relationship is visible.
| Stage | Parent’s mapping | Child’s mapping | Physical data pages |
|---|---|---|---|
| Before fork | A, B, C | No child yet | 3 |
| After sharing | A, B, C | A, B, C | 3 |
| Child writes into B | A, B, C | A, B′, C | 4 |
The child receives a separate copy B′ before its modification can affect the parent’s B. Pages A and C remain shared in this simple scenario. Immediate full copying would have required six data pages; this particular sequence requires four.
Original explanatory illustration, 2026. Three invented data pages with bookkeeping omitted. Not exact historical page tables, a memory measurement, or a screenshot.
The advantage depends on what happens next. If the child changes every shared page, the copies eventually have to be made. If it replaces its program image without modifying much of the inherited data, avoiding those copies can save work that would soon have been discarded.
The principle is therefore conditional. Sharing postpones a cost until there is evidence that the cost is needed. It doesn’t establish that memory can be duplicated without any cost or complication.
Hardware helps enforce the promise
Copy on write needs more than a convention that programs ought to behave. If both processes could freely write the shared page, either could alter the other’s data.
The inspected early code clears the write permission in shared mappings. A write-protection event leads to handling that can create a separate page, update the mapping, and copy the existing contents. The same routine can restore write permission without copying when the page no longer has another reference.4
The hardware’s refusal is useful. It tells the kernel when a promised separation has become necessary. The kernel can then change the mapping so that the program’s intended write applies to its own copy.
The programmer sees a private-memory abstraction. The implementation can use temporary physical sharing behind it. That arrangement works only if permission bits, reference accounting, and mapping updates remain consistent.
Our model also makes a second write interesting. After the child owns B′ privately, another write to B′ doesn’t require another copy merely because it is a write. The important condition is sharing that must be broken. If the parent later writes B after the child has moved away, the kernel may be able to make B writable in place.
This is a substantial difference from interpreting “copy on write” as “copy something every time a value changes.” The mechanism preserves process isolation while avoiding unnecessary duplication. The choice of name is concise; the condition behind it deserves the extra sentence.
None of this model claims that our three-page table reproduces the complete early address-space design. It isolates one mechanism documented in the release and visible in the source. Real process creation also has descriptors, registers, mappings, and other state to maintain.
A public source tree made the missing parts visible
The initial release was limited enough to make participation concrete. The 0.01 notes describe a hardwired Finnish keyboard arrangement and invite help adapting it. The October document records US keyboard patches among its acknowledgments.23
A small hardware-specific obstacle can therefore become a tractable contribution. Someone with the missing equipment can inspect the table and test a change. The project owner doesn’t need to own every possible device before anyone else can improve support.
The October account also makes its wider shortcomings visible: no normal login/init arrangement yet, incomplete device support, and missing system-administration tools. It identifies communication channels and welcomes reports and patches.3
That doesn’t mean every proposed change can be accepted automatically. A patch needs review, integration, and testing alongside other changes. Publishing source exposes the work to more people; it doesn’t remove the need to decide which work belongs in the system.
I find that distinction important when discussing collaborative software. The productive unit is a concrete change that can be inspected and tested. Enthusiasm alone has an unfortunately incomplete device-driver interface.
The license also changed
The first kernel’s distribution conditions required source availability and preserved notices, but prohibited distribution fees, including handling costs. The GNU programs around it had their own licensing arrangements.2
Linux’s later GPL identity shouldn’t be silently projected onto that first release. The 0.12 notes announce a move toward GNU copyleft, remove the fee prohibition, and state an intended effective date of February 1, subject to contributors’ objections. This belongs to the early 1992 transition.5
Those same notes describe later features including job control and swapping. They provide useful evidence that the project was developing, and equally useful boundaries on what should be claimed for 0.01. An early release is easier to understand when later improvements retain their own dates.
A beginning that could be examined
Linux’s 1991 importance lies in a working, inspectable kernel that could run useful surrounding software and invite specific contributions. The implementation had constraints, the system had missing pieces, and its documentation told interested readers where to look.
The memory example shows the kind of engineering available for examination. Two processes can have logically separate states while sharing physical storage temporarily. A hardware event and a kernel mapping change make the abstraction hold when the states diverge.
The collaboration follows a similar practical logic. Existing tools make the new kernel useful. A public implementation lets another programmer find a limitation, attempt a fix, and supply evidence that it works. Growth comes from successive concrete additions rather than from describing the destination as inevitable.
The first release wasn’t a ready-made version of today’s Linux systems. It was a sufficiently real beginning for other people to work on. Its source and its list of shortcomings arrived together, which is often the most useful kind of invitation a programmer can send.
Footnotes
-
Torvalds, 1992 collection of original early messages, preserved by Alain W Black; August 25, 1991 announcement and creator’s approximate mid-September first-release recollection. Exact September day not claimed. ↩
-
Linux 0.01 release notes, hardware, bootstrapping, architecture and original distribution terms. Kernel implementation distinguished from MINIX filesystem-format compatibility. ↩ ↩2 ↩3 ↩4
-
Torvalds, Linux—a free unix-386 kernel, October 10, 1991, references version 0.03; supporting tools, deficiencies, help and acknowledgments. This later 1991 document is not treated as an exact 0.01 feature list. ↩ ↩2 ↩3 ↩4
-
Original Linux 0.01 source archive,
mm/memory.c, inspectedcopy_page_tables,un_wp_pageanddo_wp_page; original teaching model, no copied implementation code or historical runtime claim. ↩ ↩2 -
Linux 0.12 release notes, GNU copyleft transition with intended February 1 effective date, job control and swapping; explicitly subsequent to the 1991 beginning. ↩