For anyone contemplating porting Minix to a new hardware platform, I have put together an approximate timeline for my Prisma port. It is difficult to say exactly how much time I have spent on it altogether but I would estimate that I have been spending roughly 2 or 3 evenings a week on it, sometimes more, sometimes less and some weeks none at all.
Looking over the dates, it appears that it took roughly 4 months to develop the boot loader and find a cross compiler, only 3 months to do the bulk of the kernel port and then another 8 months just to add the select() function! Probably indicates my enthusiasm, or lack of it, for the different tasks.
For those unfamiliar with BSD style network programming, I ought to explain why the lack of the select() system call in Minix was such a big issue for me.
The first reason is a consequence of the way in which the fork() system call is implemented in the m68k versions of Minix, this is by means of memory shadowing. Memory shadowing is a technique by which the parent and child processes are continually swapped in and out of the parent's address space every time either one needs to run. This is necessary because, without a memory management unit (MMU), you cannot copy a block of m68k code to somewhere else in memory and expect it to still work (yes, I do know about PC relative addressing but that brings with it a different set of problems and anyway, it is not supported by either the linker or the kernel). Memory shadowing uses lots of processor time and badly affects the performance not just of the program being shadowed but of the rest of the system as well. Fortunately, most fork() calls are immediately followed by an exec(), which cancels the need for shadowing, so the overhead is not as bad as it might be. The exceptions are interactive communications utilities such as terminal emulators and network tools such as telnet and rlogin. On Minix, these are implmented using parent and child processes, one waits for input from the keyboard and writes to the serial port or network and the other waits for input from the port or network and writes to the console. On x86 Minix this works fine, on m68k Minix, you get a big performance hit. This is where select() comes in.
The select() system call is part of the BSD socket interface to networks, particularly TCP/IP networks. Since the BSD socket interface has been widely adopted by other Un*x implementations, most interactive network applications are written to use select(). What select() actually does, is it allows a single process to wait for input from multiple channels by setting up an array of file descriptors and passing it to the kernel through the select() call. The process can then wait, using no processor time, until characters appear on any of the designated channels. This avoids the need for child processes and, if available on Minix, would remove the overhead associated with shadowing.
The second reason why select() is important is that I wanted to port some graphical applications to the Prisma, being able to use the graphics display is, after all, what this project is all about. The first project was a port of the VNC client and that uses select() to wait for input from the network, keyboard and mouse. Co-ordinating input from three channels using parent and child processes would be messy even without the overhead of shadowing.
I spent quite a bit of time trying to work round the lack of select(), but in the end I just had to have it. Fortunately, I was able to re-use a lot of the select() code from the TNET package which gave me a base to work from. The results can be found in the downloads section.
Write OSI boot server using ISODE toolkit.
Debug NetBSD OSI network support on Amiga.
Try various compilers to see how I can generate binaries for the Prisma.
Install Amiga Minix 1.5, with hard disk patches, on my Amiga 2000.
Upgrade NetBSD system from 1.2 to 1.3, spend time debugging problems with
Picasso graphics card.
Further experiments with C compilers.
Discover GCC for Atari Minix.
Build cross-compiler using GCC, GAS and Atari linker.
Start work on porting the Amiga 1.5 kernel to the Prisma.
Get 1.5 kernel as far as trying to load the root filesystem then stop and
switch effort to 2.0.
The 2.0 port is based on the standard sources from the CD-ROM
distribution with m68k specific code taken from the Amiga 1.5
sources as necessary.
Working on 2.0 kernel, devise method to load a ramdisk as part of
the kernel image.
Some initial work on the Ethernet driver.
First shell commands run on 10th April.
First successful ping on 21st April.
Start work on test programs for graphics card.
Port ttcp to the Prisma.
Further debugging of the network driver.
Release ttcp source for i386 Minix.
First display of an X desktop on the Prisma using the VNC client
(no keyboard or mouse).
Realise that I really need select() if I hope to get any usable
performance out of interactive network programs.
Hmm, no record of doing anything this month but must have been looking for a solution to the select() problem.
Download the TNET patches for Minix 1.5 (TNET has select() ).
Attempt to build a 1.5 kernel with TNET.
Abandon 1.5 and start porting TNET to Minix 2.0.
Get TNET to the stage where I can ping and ftp but realise that this is not the right direction to be going in.
Decide that the only way forward is to add select() to Minix 2.0 but the thought of tackling the internals of INET puts me off doing anything for a month.
Working on adding select() to the tty and inet interfaces.
Add support for the Prisma serial ports so that I can use a serial
mouse.
Update VNC client to use select() and a serial mouse.
Attempt to optimise kernel performance.
Start work on select() for ptys.
Upgrade Prisma from 20MHz to 33MHz.
Start porting select() code to i386 Minix.
Upgrade PC to Minix 2.0.2 and run network performance tests.
Add select() to 2.0.2.
Upgrade Prisma to 2.0.2.
Release select() patches for i386 Minix 2.0.2.
More attempts to improve the graphics performance of VNC on the Prisma.
Attempt to build a m68k cross-compiler to run on i386 Minix (the attempt failed).
Create Minix on the Prisma web site.
Update web site with OSI boot loader patches and VNC client.
Start working on the SCSI driver.
SCSI driver working, read-only on the 20th then read-write on the 27th.
Start working on an X server based on the X11 R5 sources updated with the XFree86 2.1.1 patches. This is going to be a long job, the Prisma video board cannot be accessed as a frame buffer and the X sources are strongly biased towards frame buffers. X also needs system calls that Minix doesn't have (eg. gettimeofday()) and library functions that I haven't ported yet (the maths library).
Succeed in getting a dummy X server to compile and link. There is no Prisma code in there yet but at least I know that I have a usable cross-compiler environment and that I now have all the kernel and library functions.
Minor updates to web site, Work on the X server halted while I try and get a DVD-RAM drive to work with my Amigas.
Resume working on X server, create dummy screen, keyboard and mouse code to allow the DDX initialization to complete. Hit a major problem with the network interface, X needs to be able to process data from existing connections at the same time as waiting for new connections but Minix does not support a non-blocking listen() function.
Have a look at the Microwindows project instead, the code is much smaller and the screen interface primatives are a good fit for the Prisma's capabilities. Device independent code compiles on Minix with only a few changes but the Makefile needs GNU make. Add a basic Prisma screen driver and get some of the demos to run. Try and build the client-server (nano-x) code and hit the same problem as X, no non-blocking listen(). Have a look at converting the Minix listen() function to operate in a non-blocking mode using select() to check when a new connection has arrived but it is not clear how this should work in the Minix networking environment.
Realise that the non-blocking listen() problem is not going to be easy to solve. Start to seriously consider porting uCLinux as an alternative OS platform.