February 11, 2018 UPDATE

Today I have successfully recovered the relinkable kernel distribution,
built, and booted a new kernel. This is important as it means that the
portions of the kernel provided in source form can be modified and a new
kernel generated. The important source files provided are:

  • adaptec.c Adaptec AHA 1540/1542 SCSI controller driver
  • autoconf.c Device configurables: Port, IRC/PIC, Memory
  • com.c Serial port 8650/16450 UART driver
  • conf.c Device driver linkages to the kernel
  • hd.c MFM/IDE/ATA controller (DOS/WD-compatible)
  • if_ns8390.c NS8390 (Western Digital and compats) network driver
  • if_par.c Parallel Network Interface
  • if_pc586.c PC 586 and compatibles network driver
  • lpr.c Parallel port driver
  • sd.c SCSI Disk driver
  • st.c SCSI Tape driver
  • qd.c AST Async Cluster Adapter driver

I've changed the default configuration options for the NS8390/WD80x3
network card as follows:

Detection Order Port IRC/PIC Memory
1 0x280 3 0xd0000
2 0x2a0 5 0xd0000
3 0x2e0 10 0xd0000
4 0x300 10 0xcc000

Options #1 and #4 allow use of the hardware jumpering on the card for
those combinations. The others can be set via the SMW EZSETUP utility
for setting the "soft" jumper configuration.

With the recovered and buildable kernel distribution, I will not be
able to debug and fix the SCSI Tape "last tape block" problems described

Included in the relinkable kernel distribution are a kernel driver
and mount_isofs command to mount and read ISOFS/CD9660 CDs. The CD
device must be one that is settable for 512-byte block and SCSI-
interfaced. I've tested this code works in a new kernel.

So far no issues with NFS or any other networking facility.

Today I also successfully mounted an NFSv2 filesystem from a FreeBSD 11.0
server onto Mach386:

# mount mod5:/tiny /nfs
# df /nfs
Filesystem 1024-blocks Used Available Capacity Mounted on

Mounting a Mach386 NFS filesystem on FreeBSD 11.x is also working.
The mount_nfs "-o mntudp" option is needed on the FreeBSD side
to allow it to communicate with the older NFS protocol used by

From my recovered dumps from 1996, I've updated my working recovery system
with all the latest Mt Xinu-distributed updates. I will pursue generating
update-floppy images to bring a freshly-installed system, from the distribution
floppies, to these latest-available binaries.

I've ported the 2.11BSD patched date(1) command to allow manually setting
a date beyond Y2K. The kernel is already using a 32-bit time_t, so it is
still restricted to the Y2038 limitation, however I have not discovered any
Y2K bugs other than the date(1) command; the kernel is Y2038-compliant.

With respect to the SCSI tape problems I've encountered:
I been doing testing with the oldest drive I have: Tandberg Data TDC3600
150MB QIC drive using DC6150 tapes. The driver appears to be returning
the last block twice. That is, when EOF is reached, it sends the previous
block one more time before reporting EOF to the calling process on a
subsequent read. I've verified this with a tape recorded on another
operating system. I believe I've ruled out controller, SCSI version
(SCSI-1 vs SCSI-2), and the drive. Three different drives of different
media type and greatly different generations (QIC vs DDS vs DLT) all
exhibit the driver problem. I continue to track down the exact symptom
and conditions (Unix block size Vs. Pysical device block size, etc.)
before I will start debugging the st.c and adaptec.c drivers for this

Later Note:

OK, here's what's happening. I wrote a tape on this same hardware
with FreeBSD 8.1. I wrote a tarball to disk containing the FreeBSD

# ls -l kernel.tar
-rw-r--r-- 1 root 11784704 Feb 11 21:58 kernel.tar

I then used dd(1) to write that to a DLT III tape (via a DEC
TZ87 tape drive this time) using a 10,240 block size. That was
1,150 blocks plus one partial block of 8,704 bytes at the end.
I read the tape back to verify the block count and written data.

I then copied that kernel.tar to USB and moved it over to another
machine for reference.

I booted Mach386 again on this hardware.
Under Mach386, I read the tape with dd(1) using 10,240-byte blocks:

mod43 11 # dd if=/dev/st0 bs=10240 of=DLT.tap
1151+1 records in
1151+1 records out

Note the extra block. It should have read 1150+1 records.
I copied the USB kernel.tar file across the network to Mach386,
named 'kernel.tar'. Notice the differences in sizes:

-rw-r--r-- 1 root 11794944 Feb 11 21:57 DLT.tap
-rw-r--r-- 1 root 11784704 Feb 11 21:58 kernel.tar

That is a difference of 10,240 bytes, the blocksize being read
via dd(1).

To verify what's happening, I performed the following:

1. Read the first 1150 blocks from tape into a file:

mod43 56 # bs=10240 count=1150 of=t1-1150
1150+0 records in
1150+0 records out

2. Read the next ONE block ONLY to see what comes next:

mod43 57 # dd if=/dev/nrst0 bs=10240 count=1 of=t1151
0+1 records in
0+1 records out

There's the expected partial block. The next read
should return EOF.

3. Read the next ONE block ONLY to see what comes next:

mod43 58 # dd if=/dev/nrst0 bs=10240 count=1 of=t1152
1+0 records in
1+0 records out

Instead of EOF, a full 10,240-byte block was returned
by the driver.

4. Try another read to see what happens:

mod43 59 # dd if=/dev/nrst0 bs=10240 count=1 of=t1153
0+0 records in
0+0 records out

THERE's the previously-expected EOF now.

What we have now are the following files:

-rw-r--r-- 1 root 11794944 Feb 11 21:57 DLT.tap
-rw-r--r-- 1 root 11784704 Feb 11 21:58 kernel.tar
-rw-r--r-- 1 root 11776000 Feb 11 22:05 t1-1150
-rw-r--r-- 1 root 8704 Feb 11 22:07 t1151
-rw-r--r-- 1 root 10240 Feb 11 22:07 t1152
-rw-r--r-- 1 root 0 Feb 11 22:07 t1153

Files t1-1150 and t1151 concatenated together compare exactly
to kernel.tar. So blocks returned by the driver up to and
including the second-to-last block are correct. The very last
block returned, when EOF should have been returned, is a full
block of data that the driver sent back when EOF was encountered
on tape. It's not until another subsequent read, from that point,
is an EOF returned.

The problem could be in the adaptec.c base SCSI driver, or in the
st.c SCSI Tape code. Both contain code specific to Tapes. adaptec.c
contains the kernel/Driver BTE and b_resid determinations. The st.c
also contains some data transfer to the device as well.

A few printf's will help debug this issue. Since it occurs, without
fail [pun], on all tested tape drives (both fixed and variable
block devices), it should be easy to determine the fault. My
suspicion is the logic for handling the EOF and/or short-read
tape blocks is where the bug lies. Fortunately, tape drivers
are no stranger to me.