5

Today pretty much all kernels use virtual memory provided by the MMU. They do that with the global page table, the address of which is located in a CPU register, and a page supervisor/mapper of pages to processes. The "vm" in vmlinuz, for example, means that the linux kernel supports virtual memory.

All that is possible because the MMU maps continuous addresses of memory to the memory segments understood by the x86 architecture.

The original UNIX kernel did have a vmunix version, which, I believe, must have used a similar technique. Yet, the original UNIX kernel was written before MMUs were available. If I'm not mistaken the original UNIX kernel (called simply unix), was written before the existence of the x86 architecture. Historically it did run on the PDP-9 and PDP-11.

How that kernel performed memory addressing and management? Was it a segment based addressing (two numbers) or full memory addressing (a single number)? How it separated memory between processed?

grochmal
  • 8,657
  • 1
    I'm pretty sure UNIX never ran on architectures without virtual memory. That would be fundamentally insecure for a multi-user OS. – Celada Dec 25 '16 at 15:40
  • I am really unsure about this, I know nothing that was before the double click desktop. But maybe it was this easy method? https://en.wikipedia.org/wiki/Memory_management_(operating_systems)#Partitioned_allocation – Junaga Dec 25 '16 at 16:05
  • 3
    It's more complicated than that. Unix ran on PDP-11/34. – Thomas Dickey Dec 25 '16 at 16:06
  • I'm pretty sure the PDP-7 had no VM support. – schaiba Dec 25 '16 at 16:11
  • 2
    It certainly ran on a PDP-11/20, no doubt without a KS-11, so without memory protection. – Stephen Kitt Dec 25 '16 at 16:22
  • @Celada why? you can make memory access restrictions with other hardware features? not just vm – Junaga Dec 25 '16 at 16:25
  • @Junaga As far as I've always known, the features to control memory mappings (address X is: not mapped in your address space vs. mapped read-only vs. maped read+write, etc...) all come together in one package more or less called an MMU. But my experience does not go as far back as PDPs, so I want to let other people provide good answers. – Celada Dec 25 '16 at 16:32
  • 1
    Intel didn't invent the MMU. Memory management units were used long before the x86 architecture. For example, the Digital VAX line of computers was introduced in the mid 1970s. VAX is short for Virtual Address Extension. – Johan Myréen Dec 25 '16 at 17:06
  • 2
  • 1
    The PUPS FAQ has more info. There's a cut-down release of V6 which can run on a PDP-11 without memory protection. – Stephen Kitt Dec 25 '16 at 18:42
  • @MarkPlotnick - Wow! That link really explains it well. There are no page tables, only registers that control the memory segments. The really interesting part is that the segments already had kernel and user modes, so there must have been interrupts when a CPU in a higher mode accessed the segment in a lower mode. I find it amazing that this was already there long before I was born. Many thanks. – grochmal Dec 26 '16 at 01:21
  • 1
    @Celada We're talking about ancient Unix versions. The original Unix was written to play games, isolation between processes was not a requirement. – Gilles 'SO- stop being evil' Dec 27 '16 at 00:11
  • 1
    @grochmal: more exactly PDP-11 CPUs (except the most basic) have K/[S]/U modes (Unix didn't use S) and segment registers (plus R6=StackPointer) exist per mode; the user mapping is set for the current process and the kernel mapping is mostly fixed except Labs Unix remapped KD6 to protected info for the current user process if any (the 'u' structure). Syscall from U to K was a special trap instruction (like INTx in x86) and userspace arguments could be accessed by kernel code using special instructions MFPx Move From Previous (space) and MTPx Move To Previous (space). – dave_thompson_085 Dec 27 '16 at 09:44

2 Answers2

5

Virtual memory is almost a decade older than Unix: there was one in the Burroughs B5000 in 1961. It didn't have an MMU in the modern sense (i.e. based on pages) but provided the same basic functions. IBM System/360 Model 67 in 1965 (still older than Unix) had an MMU. Intel x86 processors didn't get an MMU until the 80386 in 1986.

Implementing a Unix system doesn't actually require an MMU. It does require some form of virtual memory, otherwise implementing the fork system call is prohibitively difficult. The fork system call, to create processes by copying an existing process, was a fundamental part of Unix ever since the very first version, so it did require virtual memory. See D. M. Ritchie and K. Thompson, The UNIX Time-Sharing System, CACM, 1974, §V “Processes and images”.

I don't know the details of the hardware that the first Unix versions ran on, but they did have virtual memory in the form of a segmented architecture. The CPU translated between pointers dereferenced by a program (virtual addresses) and actual locations in memory (physical addresses). The mapping was performed by adding an offset to the virtual address. On each context switch between processes, the register containing the offset was adjusted.

Although virtually all Unix implementations provide process isolation, this was not the case of some historical implementations on hardware that didn't have memory protection (both in the 1970s, and also in the 1980s with MINIX on 8088 and 80286). Memory protection is somewhat orthogonal to address virtualization; an MMU provides both, a simple segmented architecture doesn't, an MPU¹ provides protection without virtualization. There is a Linux implementation for systems without an MMU, uCLinux, but due to the lack of fork many programs can't run (the only supported of fork is vfork which requires an execve call in the child immediately afterwards).

¹ An MPU (memory protection unit) records access rights for each page of memory.

  • That's pretty awesome, thanks. The only thing I'm left wondering is why there have been two different kernel names for UNIX: /boot/unix and /boot/vmunix. My source for that is Michael Kerrisk's Linux Programming API, which may be wrong. And Michael there argues that the unix kernel (without the vm prefix) didn't support virtual memory. I guess he meant virtual memory with paging. Then again, that probably should be another question. – grochmal Dec 28 '16 at 22:38
  • Intel CPUs starting with the 8086/8088 have memory segmentation (anyone who programmed PCs in the 1980s learned to hate it...) but no protection at all. – RonJohn Feb 06 '18 at 11:39
2

You don't need a paging MMU to get memory protection.

Paging MMUs solve a lot of more advanced problems, such as fragmentation of memory (unavailability of large blocks) and mmap (keep only recently used parts of a file in memory). And paging MMUs are required for implementing a "unified page cache" to cache file accesses across all processes.

But basic memory protection can be done with simpler "segmentation" alone, which was probably available to early Unix implementations. For example, the protected kernel memory can be placed in a segment that is set to "no access" when user-mode code is executed. Even on the modern paged OS Linux, the system calls brk() and sbrk() exist as compatibility hold-overs from the days of segmented implementations.

Essentially, segmentation is kind of like a paged MMU, except you only get a fixed number of variable-size "pages" (actually called segments), instead of a variable number of fixed-size pages.

Even today, segmentation lives on in low-cost microcontrollers that might have only a few kilobytes of SRAM, making it possible to implement a small OS with protected memory, despite the absence of a real paging MMU.

  • I learned something new (the brk() and sbrk() syscalss) so it is a good answer alright (+1). The only thing I believe that is missing (that is present in the link given by Mark Plotnick) is that the PDP already had a differentiation between kernel and user mode. So brk()/sbrk() solved (well, more-or-less solved) the per process memory protection, whilst the segmentation and registers for each segment solved the protection of the kernel memory from userspace programs. – grochmal Dec 26 '16 at 01:34
  • That's not quite right: segmentation provides virtualization, not necessarily protection. Unix fundamentally requires virtualization but can run without protection if you don't mind that a process can access another process's memory. Normally you do mind but the first version of Unix was just written to play games... @grochmal – Gilles 'SO- stop being evil' Dec 27 '16 at 00:11