November 2, 2014

Swapping VHB Bootloaders - UNIX PC & MightyFrame

VHB as Volume Home Block vs. Volume Header Block

All AT&T UNIX PC paper documentation and on-screen usage documentation uses the term "Volume Home Block", but never "Volume Header Block"
 
The MightyFrame seems to like (or at least read) the VHB on a hard drive formatted by the UNIX PC.   On startup with a UNIX PC-formatted drive connected, the MightyFrame reads:

"executing loader from drive 0"



Then, of course, it hangs, as it cannot process the UNIX PC's loader instructions.

We believe that the MightyFrame gets even this far is because the UNIX PC provides the same "magic code" in the VHB that the MightyFrame is looking for:  UQVQ, followed by a valid checksum

So, how do we edit the VHB to execute the complete loader that the MightyFrame is expecting?

Well, how does the UNIX PC install it's own bootloader?

On the UNIX PC...

A deep study of this process on the UNIX PC to install a "verbose bootloader" on a floppy, followed by the hard drive, as shown here:  (source doc hyperlinked below):

# fdfmt.vl
# /etc/ldrcpy /dev/rfp020 /dev/rfp000

So, what does these commands do, anyway?


Let's start at the top

/usr/bin/fdfmt.vl

fdfmt.vl contains the following text:

#sccs    "@(#)iv:fdfmt.vl    1.1"

iv -i /dev/rfp020 /usr/lib/iv/FDvl
mkfs /dev/fp021
dismount -f > /dev/null 2>&1


/etc/iv

iv seems to be the program that does the work.  /dev/rfp020 is the full floppy drive, and /usr/lib/iv/FDvl is another text file ("description file").



Here's an excerpt of the ascii text at the end of the binary file:
 iv: cannot stat %s iv: %s is not slice 0 of a raw device
 iv: opening special file %s r iv: opening description file %s iv: cannot reformat Winchester disk.
 iv: cannot set % disk description.
 iv: cannot do a write test on hard disk.
 iv: cannot set % disk description.
 iv: dismounting %s iv: reopening %s ** Phase %d - Allocating download areas.
 iv: dismounting %s iv: character special file needed.
 iv: description file needed.
 word too long %s
 iv: Bad number conversion: %s
 $ iv: Bad selector (%s) in input file
 iv: Repeated selector (%s) in input file.
 iv: error allocating new memory
 type name cylinders heads sectors steprate singledensity mixeddensity hitech exchangeable precomp loader badblocktable dump downloadarea program sector $ iv: excess 

at end of line in bad block table description:
%s
 iv: too many bad block entries in description file.
 $ iv: automount pathname (%s) too long.
 iv: Excess at end of line in partition description.
%s
 iv: Partition 0 must begin at block 0.
 iv: Partitions must be in increasing sequence.
 iv: Too many partition table entries.
 iv: Too many down load file entries.
 $ iv: Down-load files not supported in this version.

%s
 Device Type: %s  Name: %s %s
 (hitech)  Cylinders: %s  Heads: %s  Sectors: %s

  %d Partitions , %d Blocks for Loader , Bad Block Table Allocated , %d Block Dump Area , %d Block Download Area .
 usage: iv -key specialfile [args...]
           key is one of [iustd] optionally followed by [vmw]
  i initializes the volume given by specialfile
requires a description file
  u updates volume home block of specialfile
requires a description file
  s surface scan the specialfile
  t tell how the volume home block of specialfile is defined
  d print in description file format the volume home block

  v verbose mode
  m do multiple passes on surface tests
  w add write pass to surface tests

    # Ç%d:Bad Block Table: Multiple use of alternate %d.
 iv: bootable program to large for area specified.
 ** Phase %d - Initializing Internal VHB.
 iv: disk must be formatted for surface test.
 iv: Invalid VHB, disk must be formatted.
 iv: doing ioctl GDGETA on %s iv: start track for partition %d is past the end of the disk
 iv: section one of description file must be fully specified on format.
 iv: section one of description file may not be partially specified.
 HD SY HD2 FD iv: unknown disk type in description file: %s
 iv: cylinder count out of range in description file: %d.
 iv: number of heads out of range in description file: %d
 iv: number of sectors per track must be greater than 0.
 iv: step rate out of bounds in description file: %d.
 iv: single density switch valid only on floppy disks.
 iv: mixed density switch valid only on floppy disks.
 iv: cannot combine mixed density and single density switches.
 iv: HiTech switch not valid on Floppy disks.
 iv: disks with odd sectors/track must have bad block table specification.
 empty iv: excess at end of line in bad block area description:
%s
 iv: no bad block table specification allowed on disk with even sector/track.
 iv: doing stat on loader file name = %s: iv: area reserved for loader not large enough for file specified.
 iv: doing stat on bootable program name = %s: iv: reserved area specified larger than partition 0.
   
F
z
°The Bad Block Table contains %d entries.
 %s:Bad Block Table Overflow when adding Sector %d.
 %s:Can't Write the new Bad Block Table:Response = %x
 Added Bad Block: Cylinder %d, Track %d, Sector %d.
Used Cylinder %d, Track %d, Sector %d as the Alternate.
 iv: warning bad block entry #%d out of range, sector %d.
 adding bad block %d from Spare Blocks.
 ** Phase %d - Writing out new BBT.
 iv iv: reopening special file after writing BBT on %s iv: bad block %d on device with no bad block table.
 iv: cannot use disk, cylinder 0 contains a bad block.
 BBT: incorrectly sorted for cylinder %d
 Cylinder %d Track %d Sector %d: Data lost due to alternate sector loss.
 BBT: cylinder %d not chained correctly
 iv: -b requires bad block args
 ** Phase %d - Updating BBT.
 iv: reading VHB of %s Invalid VHB Description.
 iv: doing ioctl GDGETA on %s Bad Block handling not supported
 iv: specify slice as slice:block iv: specify block as slice:block
 Adding user specified bad block %d
   Ûm¶Ûm¶Ûm¶Ûm¶
                                          H R cHard Disk Second hard disk Floppy Disk ** Phase %d - Formatting %s.
 iv iv ** Phase %d - Performing Surface Check.
 adding bad block %d in format on write failure
 adding bad block on second write %d
 adding bad block on read %d
 adding bad block on compare %d
 bad block: cyl=%d trk=%d sec=%d
 adding bad block on read only test %d
   iv: seeking to volume home block on %s ** Phase %d - Writing out new VHB.
 iv: seeking to volume home block on %s iv: writing to volume home block on %s     8iv: unexpected EOF on loader file.
              Writing out new Loader.
              Loading Bootable Program Area.
 iv: opening loader file name = %s iv: loader specified (%s) is not an executable file.
 iv: loader text must start at %x iv: %s iv: writing loader to raw device %s iv: doing block_align on %s iv: opening bootable program, name = %s iv: writing bootable 

program to raw device %s     Ì starts at Block %d (size=%d Blocks).
 iv: reading VHB of %s Invalid VHB Description.
 iv: doing ioctl GDGETA on %s Winchester  Second winchester  Floppy  Unknown (%d)  disk
 Volume Name: %6.6s
 %d Cylinders. %d Heads per Cylinder.
 There are %d Physical Sectors (of %d bytes) per Track.
%d Physical Sectors per Cylinder, %d Physical Sectors per Disk.
 There are %d Logical Blocks (of 1024 bytes) per Track.
%d Logical Blocks per Cylinder, %d Logical Blocks per Disk.
 The Floppy is  Single density on Cylinder 0.
Double density everywhere else.
 Double density
 Single density
 Head select bit 3 is valid.
 The Step Rate supplied to the Controller is %d.
 Old style partition table
 Partition %d: start Track=%d, size (in Blocks)=%d , automount on %s

 Loader Bad Block Table Dump Area Down Load File Bootable Program Unused Area Cylinder %4d, Track %2d, Sector %2d, uses Track %2d, Sector %2d as Alternate.
 iv: %s: Bad VHB cannot continue.
 iv: doing ioctl GDGETA on %s type HD
 HD2
 FD
 name %6.6s
 cylinders %d
 heads %d
 sectors %d
 steprate %d
 mixeddensity
 singledensity
 hitech
 $
 badblocktable %d
 loader /usr/lib/iv/loader
 dump %d
 downloadarea %d
 program %d
 $
 %d
 $
 %d %s 
 $
 $
 %8x:  %2.2x  %c . 
 @(#) iv:iv.sl 1.21



/usr/lib/iv/FDvl

This is what the iv documentation calls the "description file"


Contents of /usr/lib/iv/FDvl:

#sccs "@(#)iv/lib:FDvl 1.1"
# iv description file for 48 TPI Floppy file system disk.
type FD
name Floppy
cylinders 40
heads 2
sectors 8
steprate 0
singledensity
$
loader /usr/lib/iv/s4load.verbose
$
$
0
7
$
$



/usr/lib/iv/s4load.verbose

Clearly, this is THE loader source code...right?


Here Philip Pemberton discusses the code inside of s4load.verbose 

For reference, Philip is the author of a 3b1 emulator project.



Floppy VHB

After executing fdfmt.vl, the Floppy VHB is this:


We can use the iv -t "Tell volume description" option:  iv -t /dev/rfp020
It reveals:

Floppy disk
Volume Name: Floppy
40 Cylinders. 2 Heads per Cylinder.
There are 8 Physical Sectors (of 512 bytes) per Track.
16 Physical Sectors per Cylinder, 640 Physical Sectors per Disk.
There are 4 Logical Blocks (of 1024 bytes) per Track.
8 Logical Blocks per Cylinder, 320 Logical Blocks per Disk.
The Floppy is Single density
The Step Rate supplied to the Controller is 0.
Partition 0: start Track=0, size (in Blocks)=28
Partition 1: start Track=7, size (in Blocks)=292
Loader starts at Block 1 (size=24 Blocks).

Floppy VHB binary download
created by:  dd if=/dev/rfp020 of=vhb.fdfmt-vl.dd count=65
(Why did I choose 65 instead of 28 blocks?  See comments below under the HD VHB section.)




/etc/ldrcpy

So, now we come to the command:

# /etc/ldrcpy /dev/rfp020 /dev/rfp000


# ldrcpy -h
usage: ldrcpy [-f] source destination



Here's an excerpt of the ascii text at the end of the binary file:
Loader copy, version 0.2

ldrcpy: opening special file name = %s 
ldrcpy: ioctl failed on %s
ldrcpy: opening special file name = %s 
ldrcpy: ioctl failed on %s
ldrcpy: vhb read failed 
ldrcpy: no loader on source disk Loader size is %d blocks ( %d bytes )
ldrcpy: malloc failed 
ldrcpy: lseek to loader start (reading) failed 
ldrcpy: loader read failed 
ldrcpy: vhb read failed on destination 
ldrcpy: lseek to loader start (writing) failed 
ldrcpy: loader write failed 
ldrcpy: vhb write on target failed 
usage: ldrcpy [-f] source destination
ldrcpy: not enough files specified.
ldrcpy: seeking to volume home block on %s 
ldrcpy: vhb read failed 
ldrcpy: magic number is %x
ldrcpy: checksum = %d
ldrcpy: seeking to volume home block on %s 
ldrcpy: writing to volume home block on %s    

@(#) flopsys:flopsys.sl 1.86                    



HD (Hard Drive) VHB


We can use the iv -t "Tell volume description" option:  iv -t /dev/rfp000
It reveals:
Winchester disk Volume Name: WINCHE 820 Cylinders. 2 Heads per Cylinder. There are 17 Physical Sectors (of 512 bytes) per Track. 34 Physical Sectors per Cylinder, 27880 Physical Sectors per Disk. There are 8 Logical Blocks (of 1024 bytes) per Track. 16 Logical Blocks per Cylinder, 13120 Logical Blocks per Disk. The Step Rate supplied to the Controller is 0. Partition 0: start Track=0, size (in Blocks)=32 Partition 1: start Track=4, size (in Blocks)=4000 Partition 2: start Track=504, size (in Blocks)=9088 Loader starts at Block 2 (size=24 Blocks). Bad Block Table starts at Block 1 (size=1 Blocks). The Bad Block Table contains 0 entries.
created by:  dd if=/dev/rfp000 of=vhb.rfp000.dd count=65
I chose 65 instead of 32 blocks just to see if I could determine the end of Partition 0 and the beginning of Partition 1.  
I can't...can anyone else?

Here's something REALLY interesting...If I believe what the above -t report says "Loader starts at Block 2 (size=24 Blocks)", then I would think that the loader ends after 2+24 blocks (=26, right?)...well it clearly doesn't.  It doesn't seem to end until about 51 blocks or so (comparing it with the end of s4load.verbose)...isn't this interesting?  


On the MightyFrame...

So, now, the thought is to trick this system into writing the MightyFrame loader onto the HD instead:  usr/lib/iv/loader14cust



INTERACTIVE BOOT LOADER from page 10-15 of "Writing MightyFrame Device Drivers" says:

INTERACTIVE BOOT LOADER

The boot loader is the program that is written into the loader
area of the disk by iv(1M). It is not the Id(1) program, which
links object modules together into a runnable process. The boot
loader has the responsibility of loading the CTIX operating system
at bootstrap time.

CTIX software provides the capability to substitute an interactive
boot loader in place of the loader normally supplied with the
operating system. This interactive loader allows you to boot
from an alternate load file, instead of /unix, which is the normal
default. This capability is very useful when you are debugging a
new device driver.

To install the interactive loader, you must alter the description
file and run the iv(1M) program. The pathname of the interactive
loader is (currently) /usr/lib/iv/loader11cust. You must
substitute this pathname on the loader line of the description
file. After you alter the description file, run the iv(1M) program
to write the interactive loader onto the loader area of the boot
disk. Until you change the description file and run iv(1M)
again, the interactive loader will always run instead of the noninteractive
loader.

When you reboot the the system, the interactive loader carries
on the following dialog.

• The loader displays its banner line Mightyframe Loader
Version 11.

• The loader then prompts Do you to boot anything
other than the default?

• If you respond by typing n, the loader searches for and
boots from /unix.

• If you respond by typing y, the loader displays Select device
to load from (0-2=Onboard Disks, T=Tape, 4-
7=VME disks).

• You must select one of the displayed load devices. After
you have entered a valid choice, the loader prompts Enter
filename from which to load.

• If you enter a directory name, the loader lists the files
within the named directory and then starts over, from its
banner line.

• If you enter the name of a nonexistent file, the loader
displays Error: no such file, try again, and then starts
over from its banner line.

• If you enter the name of a file within slice one of the
named load device, the loader boots that file.

-------------------------------------------------

Well, since I have no access to any running CTIX operating system, this UNIX PC loader "install" is is an interesting idea, and it ALMOST works. 


I get FURTHER on the MightyFrame boot stage after executing this process:

executing loader from drive 0

MightyFrame I loader version 14


S/80 loader version 14


WhooHoo!  2 more lines of response than I have ever seen before from my MightyFrame!

But, why does it stop there?

Well, after deep analysis, I found A problem...it may not be THE problem, or may be one of many problems, but let's start with what I can see and (potentially) understand...

Here's the deal:

When I use this process to load the MightyFrame's loader14cust, it is truncated at 48 blocks, and the last segment is a repeat of an above segment.  Confused?  So am I.  

Here's what deeper study shows, using EITHER the UNIX PC or the MightyFrame loader in this process.


Now, an interesting observation I've made along the way is this "copied" section seems to exist when iv is used to "install" the UNIX PC loader s4load.verbose as well.  If you look closely at the dd-out files from both the floppy and the hard drive, you can see that there are extra asterisks after the final "@(#) bootload:bootload.sl 1.10" ?  

Well, it just so happens that these asterisks are copied from the exact same section that I reference in my above picture.  The reason it works on the UNIX PC, is that the whole s4load.verbose fits just shy of 5F6F, and evidently the section after "@(#) bootload:bootload.sl 1.10" is just ignored.

What craziness is this?

So, I had the bright idea to use dd to copy in the data, since it seems to work so well to copy out the data...well, not so fast.  Now we have missing 0D characters on the dd-in stage.

How do I know that these 0D characters even matter?  Well, after using my dd process to copy the loader onto the disk, then I am back to where I was at the beginning:

executing loader from drive 0

...and no further, just as if the loader was still the my originally-tried UNIX PC loader.

So, the 0D (ASCII carriage return) characters/bits must matter, I guess.  The absence of those 0D characters is the only difference that I can see when I analyze the file after doing a dd-out after the dd-in.  So now what?

Why does dd-in skip those characters, but dd-out catches them?  The mystery deepens.  

To do this anaylsis, I am using HxD - Hexeditor
Version 1.7.7.0

Running on Windows 7
www.mh-nexus.de


Here's the dd-out result files for comparison:

floppy loader created using iv

floppy loader created using dd

floppy loader created using cat

*NOTE* The source file for the iv process is the unmodified loader14cust, while I modified the source for the dd and cat files to match the VHB that the iv process creates "on top of" the loader.  Here is my modified source file for dd and cat only.

UNIX PC "dd" command failing to copy ASCII Carriage Return characters:

Discussing this topic on:







-------------------------------------------------

MISC:

#sccs "@(#)iv/lib:maxtor2190 1.1" # Maxtor 2190 type HD name mx2190 cylinders 1224 heads 15 sectors 17 steprate 0 $ badblocktable 1 loader /usr/lib/iv/s4load.silent $ $ 0 15 515 $ $ ????????????????????????????????????????????????????????????????????