Keykos was ported to the Luna 88K (too) which was a system with which Omron had planned to enter the work station market.
These are a few notes on how we solved some porting problems and opportunities.
Special Real Addresses
As in Macs and many other architectures of that day, the program controlled the screen image by storing data at special fixed real addresses which directly accessed the display’s refresh buffer, one bit per pixel.
We had decided that X11 would be the main program to control the screen and produced a synthetic Unix sufficient to support X11 and several other important Unix user mode programs without recompiling.
We also wanted to include the display buffer in the checkpoint.
Keys to the page frames holding the pixels were chosen as the mechanism by which to grant X11 and other screen programs, access to the pixels.
We chose not to allocate disk page frames to these entities perhaps to avoid the cost of migration.
We built into the kernel code knowledge that a certain range of CDA’s would designate these page frames.
Page keys with these CDA’s would provide access to the pixels.
There were no range keys for these pages for that would get you into code that expected to meddle with the allocation counts on the disk, of which there were none.
Here are the kernel warts that I recall that grew in order to support these decisions.
- Kernel code knew that these special real addresses were to hold these particular pages.
Rather than modify the code that chooses RAM frames for pages, we added code to the checkpoint restart logic to bring in and core lock those special pages from the checkpoint upon booting the system.
These frames had core table entries and the kernel located the frame from the key by normal logic.
- Kernel migration logic had to know not to migrate these pages.
We saw no need for space banks to deal in these pages.
Space banks allocate a pool of fungible disk frames and the pages of pixels are not fungible.
If a holder of a pixel page key wanted to provide a rescindable key to the page, he could build a one page segment at the cost of one node.
With a shared keeper he could even make the segment key appear as a page key via the alleged type call.
An amusing dilemma was whether to map these pages as cacheable.
Display code ran much faster with the cache set to “write into”.
The pixels would arrive on the screen only after those cache lines were flushed by cache pressure.
With the page table entry set to write-into, you could see some effects on the screen but only if you looked very closely.
The data cache on the 88K was only 8K bytes.
I think this would work for ROM addresses and special IO addresses as well.
Harvard Architecture
The data cache and instruction cache were each a separate chip.
They were identical.
Those chips also held and controlled the respective TLBs.
The address of the mapping table root was on the cache chip and thus there were two.
We found it very convenient to allocate two slots in the domain root for the two logically separate spaces.
In practice those two slots held the same key.
The normal kernel logic discovered the consequent sharing and thus we preserved the inherent and perhaps useless flexibility at virtually no cost.