8 ms·
I feel the same - V7 is significant - but for different reasons. (1) V7 did not use a MMU, there are no shared object libraries. The whole stack feels simpler,
by cturner 5y ago
I feel the same - V7 is significant - but for different reasons.
(1) V7 did not use a MMU, there are no shared object libraries. The whole stack feels simpler, less layered. It is straightforward to hand-craft a binary on a pre-ELF system.
(2) V7 was just before select was introduced. V7 was only capable of basic networking like uucp where you give over the cpu to the networking operation.
A while back I wrote some notes contrasting RetroBSD (2BSD, close to v7) to LiteBSD (4.4 BSD), http://songseed.org/dinghy/d.pic32.platform.html http://songseed.org/dinghy/d.pic32.platform.html
Both ports were done by the same developer, from different versions of the same codebase, separated by four years. If you compared any releases of Solaris, FreeBSD and Linux from the last twenty years, the differences would seem trivial compared to the differences between RetroBSD and LiteBSD.
- whartung 5y agoIf V7 didn't use an MMU, how did it load programs? Did it rely on PIC code? Did it have a relocating loader that it relied upon? Curious how Unix managed to progress as far and as quickly as it did without an MMU while relying on something as notorious as C in an unprotected space. Just seems system stability would always be at stake. Just curious what their experiences were like, not questioning it.
- phicoh 5y agoThe pdp-11 had a very primitive virtual memory system. It was not page based. So you had to swap in and out entire processes (with seperate instruction and data you could leave the program in memory, swap out data, and swap in data from another process running the same program). Later pdp-11 models could have a few processes in ram at the same time.
- monocasa 5y agoOnly for very low end systems. Most PDP-11s running Unix had something like the KT-11D MMU providing true paging hardware.
- phicoh 5y agoYou are right. After I wrote my text, I realised that there must have been some kind of paging. Of course, with 8 Kbyte pages in a 64 Kbytes it is not the same granularity as today. Imagine unmapping one page to keep the stack separate from the heap. That's 1/8th of your already small address space. But the part that is also missing the ability to restart instructions after a page fault. If I remember correctly some old discussion, that may have been possible for many instructions but not some popular instructions. I found an online copy of the reference manual which states: "It is not generally possible to recover from these aborts." So paging yes, but not in the modern sense where you can recover from a page fault. Which is key to many aspects of a modern unix system. For example, copy-on-write forks.
- monocasa 5y agoThe 8KB pages could also be broken down into 128 byte blocks, so that you could map a (contiguous) portion of a page, and not have to use the whole 8KB. You could also use the same feature to give yourself guard 'pages' (but really guard blocks). It specifically supported the ability to grow down for stacks and guards. And the abort issue is around restarting indirect addressing modes, which will result in repeats of accesses. Technically this is an issue if you were pulling pointers directly out of MMIO regions, but it's one of those "doctor it hurts when I do this." "Then don't do that" kind of situation. If you're getting real cute with advanced addressing using MMIO regions to bounce out to other regions, do that in the kernel (as you probably would be anyway). Then you can do all the fun virtual memory tricks.
- monocasa 5y agoV7 absolutely used the MMU. V6 did too; you can see it's use in Lyon's commentary.
- adrian_b 5y agoThe PDP-11 had a MMU, but it was an extremely simple MMU, even simpler than what was available in Intel 8088/8086. When MMU is mentioned in UNIX context, a MMU like in DEC VAX is understood, which provided features like access protection, dynamic relocation and virtual memory. The main purpose of the PDP-11 MMU was to extend the maximum memory size from 64 kB to 4 MB, but that was done in a very inconvenient way. A single process was limited to 64 kB of program code + 64 kB of data. For larger processes one had to use memory overlays, i.e. to swap out parts of the program while other parts were swapped in over the same addresses, but this feature was not used in UNIX, but in other operating systems for PDP-11, e.g. DEC RSX-11M. In UNIX, the larger memory was exploited by loading in memory many concurrent processes. It was easier to split some task into subtasks done by cooperating processes communicating through pipes, than to attempt to remap some of the 8 kB pages of the 64 kB address space while the program was running, in order to exceed the process size limit.
- monocasa 5y agoThe PDP-11 MMU was more powerful than what existed in the 8088/8086. It provided a supervisor/user distinction and didn't allow user code to go to town on the MMU directly. Yes, being a true 16 bit system, it was limited to 64KB total in each address space, but there was both * True process isolation since user code couldn't load whatever they wanted into the base registers like on an 8086, * True pages, so that the entire 64KB didn't have to be contiguous like on a 8086, but was instead broken into 8KB pages that could be mapped, shared between process, and mixed together in different places in the virtual address space. Everything you're saying applies equally to the 32bit virt/36bit phys PAE world that we had for a while, and I wouldn't call that a simple MMU.
- adrian_b 5y agoIt is true that the PDP-11 MMU provided memory protection, unlike 8088/8086. However that mattered only for the operating system kernel, as it allowed process isolation. For user programs, the 8088/8086 MMU was a thousand times more convenient, because the segments could start on any 16-byte boundary instead of 8 kB boundaries and there were 4 segments instead of 2 and you could load a pointer to a new segment with a single instruction. For an IBM PC, it was very easy to write a 512 kB program, you just had to select an appropriate memory model option for the compiler. For a PDP-11, even when having 4 MB of memory, writing a large program was extremely difficult. You had to partition the code and data of the program in pieces not to small and not too large, to fit in 1 or a few 8 kB pages. You had to partition in such a way that the parts will not need to be active simultaneously and you would not need to swap them frequently. Swapping parts was slow, as it had to be done by an operating system call. The linker had to be instructed to allocate the overlapping parts to appropriate addresses, so that it will be possible to swap them.
- denotational 5y agoI don't have any knowledge of V7, but V6 definitely used an MMU (as does xv6).
- CalChris 5y agoV7 supported hardware segmentation registers. Look at sureg() in usr/sys/sys/ureg.c [1]. What it didn't support was pages. That came with 3BSD [2]. [1] https://github.com/v7unix/v7unix/blob/master/v7.tar.gz https://github.com/v7unix/v7unix/blob/master/v7.tar.gz [2] https://en.wikipedia.org/wiki/History_of_the_Berkeley_Software_Distribution https://en.wikipedia.org/wiki/History_of_the_Berkeley_Softwa... BTW, I think by far the main reason that V7 matters is that it was (somewhat) portable. That begat the workstation boom.
- monocasa 5y agoThey call them segmentation registers in the source, but it's really paging hardware in the modern parlance. The estabur function in your citation can be seen iterating over the whole virtual address spaces (one each for I and D), and setting the permissions for each 8KB page. It's not super clearly written code, but those ap and dp variables are pointers to PTEs. The hardware they're programming against is a KT-11D (compatible) MMU. Here's it's user guide: http://www.bitsavers.org/pdf/dec/pdp11/1140/KT11D_UsersMan.pdf http://www.bitsavers.org/pdf/dec/pdp11/1140/KT11D_UsersMan.p...
- inkyoto 5y ago> (1) V7 did not use a MMU, there are no shared object libraries. The whole stack feels simpler, less layered. It is straightforward to hand-craft a binary on a pre-ELF system. It is strightforward or not quite. V7 on the PDP-11, even those with the MMU, had a 64kB process address space limitation (actually, I think it was 56kB); therefore, the solution was the overlay linking (a cheap and nasty implementation of memory paging in the user space) for applications that could not fit into the fixed address space which was pretty arcane to get right. If the code accidentally crossed the overlay boundary, it would result in the application entering a death spiral of discarding a chunk of address space to replace it with the next overlay to discard the loaded overlay almost immediately and load the previous overlay back into the address space and start over again.