25 Sector disk with Uport: "FIX"
Chert Pellett
elwiz at killer.DALLAS.TX.US
Mon Jul 25 14:55:17 AEST 1988
I did it... I got MicroPort unix to BOOT off a 25 sector drive! Compaq 386/20.
Now if I could just get floating point to work.....sigh, have to wait on that.
In any event, I thought that you all might be interrested in what
needs to be done to get it to work....
Here's what you need to do as I see it:
1) Backup your system. Be sure to mount a floppy and use
find /dev -print | cpio -pdmvl /mnt
Note: You will have to use 'mkfs /dev/dsk/fd096 2400:5500' as if your
System is like mine, you will have in excess of 5,000 Devices
in the /dev directory!
to backup all of your devices, (if whatever backup you use does not do
this...Most don't) I forgot to do this and had to reload dosmerge in
order to get back my Virtual consoles..
2) Build a bootable floppy system, I just copied the one supplied by
Microport. (install boot disk). There is an documented command
mkboot (1M), well sorta, I found a reference to it in one of the
intro sections, but I can't find the executable or man page....
This may well be in the famous 'next release'...
3) recompile the kernel to load in the new hd.o, I also loaded
the new asy.o, but that's your choice.
4) Mount the floppy as /mnt (mount /dev/dsk/0s25 /mnt)
5) copy a stripped copy of /unix to /mnt/unix. (I would NOT strip
/unix, but copy it then strip it) I stripped it to reduce it
from a 490K kernel to a 360K kernel. (I have digiboard drivers
installed for Ipx/8)
6) copy the following files to /mnt/bin:
cat - Not needed if you like using cp FILE /dev/console
ls - I like to see what's going on! (not critial either)
cmos_setup - I used this too, but not critial
whatever restore program you need.
If it will fit:
ed/vi - I didn't have this, but really needed it
Or some editor....
7) Using either UNIX or DOS, compile the patch program at end of this
file, it will be needed later. Sorry, I can't say that this patch
code is well tested, I ran it in bits at a time. `It should work'
On UNIX, you will have to modify the sector read/write calls to
use seeks and write()'s into /dev/dsk/0s0. If on unix be sure to
copy the executable to /mnt/bin.
8) Boot the new floppy, (You may need to use dos to set the disk
type, cmos_setup will not allow drive type 16-19!! I have a type
17 as my 2nd drive.. and 47 as my main drive)
9) Follow all of the installation instructions, When it asks you to
remove floppy and reboot, you may attempt to do so, but it won't
work.. You will get a row of dots, then it will hang...
10) Either:
1) Reboot using the floppy (hit DEL at 1st prompt)
edit /etc/partitions so that:
vtocsec = 25 (not 17), altsec=26, (not 18)
(If you were unable to put any form of editor on the disk
you will have to use option 2 here...)
OR: 2) Using Nortons NU, search the disk for the string 'vtocsec'
(somewhere around sector 2350), patch it using the HEX
patch utiltiy in norton.
(or any other sector editor you like)
OR: 3) If you happen to have another unix machine just laying around,
mount the floppy and edit the file...
11) Execute the following string of commands: [May not even be needed]
/* Taken from INSTALL script */
mkpart -i disk0
mkpart -P rootus -P swap -P reserved -P alts disk0
Execute the rest of /INSTALL, I did it by hand as I had no editor...
Note: Do not execute all of /INSTALL as this would overwrite
/etc/partitions and you would be back to square one.
12) Install the patches by running the patch program. Basiclly what
it does is this:
Patches one compare instruction at:
Cylinder 1, Head 0, Sec 3, Offset 0xA0 from 17 to 25.
Installs a patch to the code at: (Before call to int 13)
Cylinder 1, Head 0, Sec 2, Offset 0x5E
From : {0xB2, 0x80, 0xCD, 0x13};
To : {0xE8, 0x9F, 0x15, 0x90};
The old code:
mov dx, 80h
int 13h
The New code:
call near ptr 1800h ; call to patch code.
nop ; had an extra byte...
Copys patch code into unused (but LOADED after boot code!) sector.
Cylinder 1, Head 0, Sec 13
This patch code changes the value in ds:[13B2] to 25..ie:
proc patch near
cmp word ptr ds:[13B2h], 17 ; Right spot?/First time?
jne skip
mov word ptr ds:[13B2h], 25 ; 25 Sectors per track!
skip:
mov dl, 80h
int 13h
ret
The hex bytes are as follows:
83 3E B2 13 11 75 06 C7 06 B2 13 19 00 B2 80 CD 13 C3
[The above patch was needed because The location [13B2] is somehow
initilized AFTER the program is loaded into memory. I tried to patch
all of the "17's" on the disk to "25's", and of the 10 I found,
2 hung the computer, 1 trashed the clock, 6 did nothing, and the
other one is patch #1...]
[The next step may not be needed...]
copys:
Cylinder 0, Head 1, Sec 0
to
Cylinder 0, Head 0, Sec 17
This is the PD/VTOC sector, I copied it over to the old location
so it didn't matter where the OS or Boot code looked for it, as
long as it found the correct one! (the one made by the LAST
mkpart -i part0, using 25 sectors..)
13) Reboot and pray that your system was close enough to mine that the
above patches worked... If they did, you should get the boot:
prompt, and things should work fine when you hit return...
All in all, I only had a week of down time for this little adventure....
Isn't working on the bare metal fun? Having your boss bitch at ya for
spending $1500 on an OS (We got MERGE & Development [Unlimited]) and have
cute little problems like this...All in all tho, I do like microport, only
wish that they would hurry with this next wonderous version! The above
patch comes with ABSOLUTELY NO GUARENTEE, It is Simi-tested, as noted I
did make 7 patches that "did nothing" (so I unpatched them...But they might
have made other patches when they ran..). I am not willing to reformat my
system to test to make sure that the above instructions will work for you..
(unless ya want to send me some pretty hefty bucks, I can on request send
you a hex dump of the first 2 tracks. This might help you if the above did
not do it for ya) I wrote several versions of the patch in sector 13, one
dumped out what Cyl, Head, and Sector the boot program was reading as
well as allowing you to look at any location in memory... (I was getting
rather despate to get this going... After all I had spent some 75 hours on
it, and was almost ready to write my own loader... the only thing that
kept me from doing it was I didn't know where UNIX wanted to be loaded and
if it needed anything setup for it.
For your information, the boot process is as follows:
ROM reads in sector # 0,0,0 (cyl, head, Sec). and Jumps to start of it.
This sector holds Initial boot code as well as the partition table.
(last half)
This then reads in Sector (0,1,0) (Track #2, sector 0) This is UNIX's
Initial boot sector.
This code then reparses sector 0,0,0 to find out where UNIX is at (again)
and loads in sectors (0,1,1) to (0,1,16) This is the Third stage
boot code, presumably /etc/boot. (I have not verified this tho).
This code then reparses sector 0,0,0 to find out where UNIX is at (again)
And loads in Sector 0,0,1 and 0,1,1 From these it computes where the
Physical description sector should be at. The Pd points to the VTOC
sector (It is Just after the Physical description, In the same sector)
(This sector is 0, 1, 2 on my system, I think that it is here on all
Uports disks..)
Then the code puts out the boot: prompt, and waits for a filename,
a <CR> or a timeout.
When it has those, it reads in the first INODE block, Grabs a block
number from there and (The one for the 2nd INODE, 1st one is reserved),
This will be the Root directory INODE. It reads it and obtains a
block list block number, gets that block (which is a list of blocks
that are in the file). Reads in that block (which is the first block
in the / directory). searches it for the file specified (/unix or
whatever). If it finds it then it repeats the last to indirections
to find the blocks in /unix. It then loads unix and jumps to it...
I presume that Unix once loaded, will have to grab sector 0,0,0 and
use it to initilize the hard disk driver so that it knows what part
of the disk is it's. I doubt that there are any information passed
from the 3rd stage boot to the 4th stage boot (/unix).
Good Luck, I'm sure that you will need it.
-- Chert Pellett {ihnp4, etc}!killer!spdyne!root
Spectra Dyne Inc.
---------- Cut/Hack/Rip/Chop/Etc here ----------
/* Apply patchs to allow 25 sectors on Microport's unix.
1) replace call to INT 13 with call to cs:1800 (Relative)
2) Build new sector to jump out to
3) Patch 2nd stage boot code to look for 25 sectors
4) make a 2nd copy of VTOC/PD at the 17th sector...
*/
unsigned char buf[512];
#define WARN 1 /* Warn the person if ORG Code is not correct */
#define NOWARN 0 /* Just make the patch, don't ask about anything */
char ORG_1[] = {0xB2, 0x80, 0xCD, 0x13};
char PCH_1[] = {0xE8, 0x9F, 0x15, 0x90};
#define SIZ_1 4
#define OFF_1 0x5E /* Offset into block.. */
char ORG_2[] = {0}; /* It doesn't matter, it is not used */
char PCH_2[] = {0x83, 0x3E, 0xB2, 0x13, 0x11, 0x75, 0x06, 0xC7, 0x06, 0xB2,
0x13, 0x19, 0x00, 0xB2, 0x80, 0xCD, 0x13, 0xC3};
#define SIZ_2 sizeof (PCH_2)
#define OFF_2 0 /* Offset into block.. */
char ORG_3[] = {0x11};
char PCH_3[] = {0x19};
#define SIZ_3 1
#define OFF_3 0xA0 /* Offset into block.. */
main ()
{
patch (1,0,2, OFF_1, ORG_1, PCH_1, SIZ_1, WARN); /* Patch 2nd boot loader */
patch (1,0,13, OFF_2, ORG_2, PCH_2, SIZ_2, NOWARN); /* Patch code in unused area */
patch (1,0,3, OFF_3, ORG_3, PCH_3, SIZ_3, WARN); /* Patch 2nd boot loader */
#ifdef UNIX
Need to do the calls below via seeking into /dev/dsk/0s0 as shown below
#else
biosdisk (READ_DISK, 0x80, 0, 1, 0, 1, buf); /* Read in VTOC/PD sector */
biosdisk (WRITE_DISK, 0x80, 0, 0, 17, 1, buf); /* Update other location */
#endif
printf ("If you are luckly, it should now be bootable...\n");
}
#ifdef UNIX
patch (cyl, head, sec, offset, orig, pch, size, warn)
int cyl, head, sec, offset, size, warn;
unsigned char *orig, *pch;
{
/* You will have to open /dev/dsk/0s0, and seek into it by
512L * (cly * 125 + head * 25 + sec)
read in 512 bytes, apply patch as below, seek back there again
and write the sector back.. (or you could seek to the exact byte location
that you want and only read in those bytes, but it is all the same..)
*/
}
#else
#define READ_DISK 2
#define WRITE_DISK 3
patch (cyl, head, sec, offset, orig, pch, size, warn)
int cyl, head, sec, offset, size, warn;
unsigned char *orig, *pch;
{
int I;
biosdisk (READ_DISK, 0x80, head, cyl, sec, 1, buf); /* Read in the sector */
if (warn) /* do we check to see if we should do the patch? */
{
for (I=0; I < size; I++)
if (buf[offset+I] != orig[I])
{
printf ("Hum, looks like the patch might not work, as the\n");
printf ("Bytes I am expecting arn't there.\n");
printf ("Press <ENTER> to patch anyway (^C to abort)\n");
getchar ();
}
else
buf[off+I] = pch[I]; /* Apply patch as we scan... */
}
biosdisk (WRITE_DISK, 0x80, head, cyl, sec, 1, buf); /* Update the sector */
}
/* Biosdisk is a Turbo C built in, it calls int 13 as follows:
es = ds;
bx = (int) buf;
cl = sec; Upper 2 used for the Cyl, but it never exceeds 255
in our program, so this will work
ch = Cyl;
dl = Drive #, 0x80 for Hard disk C.
dh = head;
Ah = Opcode; (First parm to biosdisk)
Al = # of sectors to read; never pass in 0...
*/
#endif
More information about the Comp.unix.microport
mailing list