sater@duvel.UUCP (Hans van Staveren) (06/20/85)
Recently I posted an offer to post an article I had written
about non-standard disks on the PC-AT with Xenix.
I have received more than a dozen replies, which probably means
I am justified in posting the article.
In the article I express doubt at some places where I do not
fully understand the problem yet, if anyone *knows* the answer
there I would appreciate getting it.
And now, without further ado, ...
Problems with hard disks on Xenix for the AT
Hans van Staveren
Philips, I&E DTS
Eindhoven
_1. _G_e_n_e_r_a_l _i_m_p_l_e_m_e_n_t_a_t_i_o_n _o_f _h_a_r_d _d_i_s_k_s _o_n _t_h_e _A_T
The AT supports two hard disks, named C and D. There
are 15 supported types of hard disks and it is possible to
set the type of each of the two hard disks using the SETUP
option on the diagnostic diskette.
The startup ROM reads these types from a piece of CMOS
lying around in the calendar clock and sets up two vectors
at addresses 0x104 and 0x118 respectively. These vectors
point into a table of diskparameters that resides inside the
BIOS ROM. All programs should take their information from
these vectors.
_2. _W_h_a_t _i_n_f_o_r_m_a_t_i_o_n _i_s _a_v_a_i_l_a_b_l_e _p_e_r _d_i_s_k_t_y_p_e?
Per disktype the following information is kept in the
ROM in a 16-byte structure:
16 bit # of cylinders
8 bit # of heads
16 bit unused, I think
16 bit Start cylinder for write precompensation.
8 bit unused, I think
8 bit Control byte: 0+8*(NHEADS>8)
24 bit unused, I think
16 bit Cylinder # of landing zone
8 bit # sectors per track, always 17
8 bit unused, I think
_3. _W_h_a_t _i_f _y_o_u_r _d_i_s_k _i_s _n_o_t _b_l_e_s_s_e_d _b_y _I_B_M?
In principle any method to remap the vector at one of
the above addresses to an address where the information for
_y_o_u_r disk is should suffice for normal operation. Unfor-
tunately the bootstrap ROM does a disk check before booting
so that the pointer must be changed before that check. We
have not found another method for this than changing the
June 10, 1985
- 2 -
BIOS ROM in its entirety, there is however an alternative
method that is almost as good.
The standard AT has two empty sockets that can take a
27256 EPROM each, which gives you 64 Kb of programspace.
This space can be taken in part by a little program that
changes the pointer to one in your ROM. This extra ROM is
called just before the operating system is started but after
the disk test. So if the disk test happens to work on your
disk this method works. Your changed disk must be larger
then the corresponding entry in IBM's table for this to
work, and the write precompensation cylinder must not get in
the way either.
This method has been tested and works. An example pro-
gram is given as an appendix, do not forget the checksum of
the ROM, all 64 Kb added together must be 0 mod 256. You
can use 2764 EPROM's also, but this needs some pinbending
and soldering. Specifically we used 2764A-2 EPROM's from
Intel, bent out pin 27 so it didn't make contact and sol-
dered a little connection between pin 27 and 28. Ask your
nearest hardware wizzo for the reasons if you care.
_4. _W_h_y _i_s _t_h_i_s _n_o_t _e_n_o_u_g_h _t_o _g_e_t _X_e_n_i_x _t_o _r_u_n?
After all this pinbending and assembly programming you
are certainly entitled to results, right? Wrong.
This work has been enough to get the IBM diagnostics to
format your disk and to get DOS to run. The people that
made Xenix had ideas of their own and decided not to use the
two vectors mentioned above. They read the disktype from
the CMOS and use it is an index in a table of their own mak-
ing. First let us compare the two tables(all numbers in
hex):
Disk IBM Xenix
type ncyl nhds sect wpccyl ncyl nhds sect wpccyl
-----------------------------------------------------------------------
1 132 4 11 80 <- same
2 267 4 11 12C <- same
3 267 6 11 12C <- same
4 3AC 8 11 200 393 8 11 200
5 3AC 6 11 200 19A 6 11 100
6 267 4 11 FFFF 1CE 8 11 100
7 1CE 8 11 100 1EC 5 11 100
8 2DD 5 11 FFFF 384 7 11 FFFF
9 384 F 11 FFFF <- same
A 334 3 11 FFFF <- same
B 357 5 11 FFFF <- same
C 357 7 11 FFFF <- same
D 132 8 11 80 <- same
E 2DD 7 11 FFFF <- same
June 10, 1985
- 3 -
This difference alone would be bad enough, but unfortunately
this table is spread among a lot of programs in Xenix.
Before giving the list of patches an explanation about Xenix
file systems and boot procedures should be given.
_5. _X_e_n_i_x _b_o_o_t _p_r_o_c_e_d_u_r_e_s
The first thing to note about this chapter is that it
has been deduced. Elementary my dear Watson. There can
thus be no guarantee for correctness. If you are not too
scared, read on.
When booting Xenix from scratch, the first thing that
happens is that the boot ROM discovers no floppy disk to
boot from, and a hard disk with a block 0 that looks like a
bootblock. This block is read in and called. When running
it discovers the socalled active partition and if found the
block 0 from that partition is read in and called. Whether
this code is all in block 0 of the disk or partly in ROM, I
did not yet discover.
The block 0 from the hard disk looks like IBM code,
exactly the same as that used by DOS. The block 0 from the
Xenix partition is the first code particular to Xenix. It
proved not to be enough for them, so the only thing this
block of code does is to read some more blocks, 15 to be
precise after skipping one block from the disk.
This next piece of code is a copy of /etc/boot1 and it
reads the program /boot from the Xenix root partition.
After that Xenix is called in the normal way. Counting the
ROM this has been a _s_i_x-stage bootstrap. The moon was
reached in fewer steps!
All this booting means that a complete track is wasted
on booting, which means that you must always subtract 17
sectors, which is 9 Xenix blocks when rounded up, from a
partition size before handing the number to _m_k_f_s.
_6. _W_h_a_t _t_o _p_a_t_c_h?
All patches given here have addresses that count from
the start of the _f_i_l_e, so all you adb-wizards out there
should start fiddling with the map commands. Just to check
your surroundings, all addresses mentioned here should con-
tain 0x132.
There are five programs to patch, let us start with the
kernel itself. If you have the program development package
you should change the hard disk driver
/usr/sys/io/lib_io(hd.o). The disk table starts at address
0x448. If you do not have the driver you are on your own,
dump with the _h_d program the data portion of your Xenix ker-
nel and look for rows of 11's, that will find you the table
June 10, 1985
- 4 -
easily. Good luck.
Other programs to change are
program location
------------------------
/etc/fdisk 0x3302
/etc/badtrack 0xDF4
/boot 0x28DC
/etc/boot1 0x1B50
After changing the last file you must copy it to the hard
disk, this can be done using the undocumented program
/etc/ib, an example of its use can be found in the enlight-
ening shell script /etc/hdinit.
_A_p_p_e_n_d_i_x
The next program is a piece of rommable code that can
be put in the free slots in the AT to change the diskvector.
It is written in a dialect of 8086 assembler, but should be
understandable to all.
June 10, 1985
- 5 -
.sect .text
.assume .text:cs
vechd0 = 0x41 * 4
vechd1 = 0x46 * 4
fd_tbl = 0xE401
start:
.data1 0x55
.data1 0xAA
.data1 0x00
entry:
push ds ! save datasegment, we must change it
xor ax,ax ! make a zero
mov ds,ax ! put it in ds, so we can reach low mem
mov ax,.offset hd_tbl ! compute the diff between our table
sub ax,fd_tbl ! 's address and IBM's
add vechd0[0],ax ! add it to
add vechd1[0],ax ! both diskvectors
mov ax,cs ! Take current code segment (F rom)
mov vechd0[2],ax ! and put in in
mov vechd1[2],ax ! both diskvectors
pop ds ! Restore data segment register
ret.f ! and return from far far away
hd_tbl:
! drive type 1
.data2 306
.data1 4
.data2 0
.data2 128
.data1 0
.data1 0
.data1 0,0,0
.data2 305
.data1 17
.data1 0
! drive type 2
.data2 615
.data1 4
.data2 0
.data2 300
.data1 0
.data1 0
.data1 0,0,0
.data2 615
.data1 17
.data1 0
! drive type 3
.data2 615
.data1 6
.data2 0
June 10, 1985
- 6 -
.data2 300
.data1 0
.data1 0
.data1 0,0,0
.data2 615
.data1 17
.data1 0
! drive type 4
.data2 940
.data1 8
.data2 0
.data2 512
.data1 0
.data1 0
.data1 0,0,0
.data2 940
.data1 17
.data1 0
! drive type 5
.data2 940
.data1 6
.data2 0
.data2 512
.data1 0
.data1 0
.data1 0,0,0
.data2 940
.data1 17
.data1 0
! drive type 6
.data2 615
.data1 4
.data2 0
.data2 0xFFFF
.data1 0
.data1 0
.data1 0,0,0
.data2 615
.data1 17
.data1 0
! drive type 7
.data2 462
.data1 8
.data2 0
.data2 256
.data1 0
.data1 8
.data1 0,0,0
.data2 511
.data1 17
.data1 0
! drive type 8 (changed for MaXtor 105 Mb disk)
.data2 918 ! replacing 733
.data1 11 ! replacing 5
June 10, 1985
- 7 -
.data2 0
.data2 0xFFFF
.data1 0
.data1 8 ! replacing 0
.data1 0,0,0
.data2 918 ! replacing 733
.data1 17
.data1 0
! drive type 9
.data2 900
.data1 15
.data2 0
.data2 0xFFFF
.data1 0
.data1 8
.data1 0,0,0
.data2 901
.data1 17
.data1 0
! drive type 10
.data2 820
.data1 3
.data2 0
.data2 0xFFFF
.data1 0
.data1 0
.data1 0,0,0
.data2 820
.data1 17
.data1 0
! drive type 11
.data2 855
.data1 5
.data2 0
.data2 0xFFFF
.data1 0
.data1 0
.data1 0,0,0
.data2 855
.data1 17
.data1 0
! drive type 12
.data2 855
.data1 7
.data2 0
.data2 0xFFFF
.data1 0
.data1 0
.data1 0,0,0
.data2 855
.data1 17
.data1 0
! drive type 13
.data2 306
June 10, 1985
- 8 -
.data1 8
.data2 0
.data2 128
.data1 0
.data1 0
.data1 0,0,0
.data2 319
.data1 17
.data1 0
! drive type 14
.data2 733
.data1 7
.data2 0
.data2 0xFFFF
.data1 0
.data1 0
.data1 0,0,0
.data2 733
.data1 17
.data1 0
! drive type 15
.data2 0
.data1 0
.data2 0
.data2 0
.data1 0
.data1 0
.data1 0,0,0
.data2 0
.data1 0
.data1 0
June 10, 1985
--
Hans van Staveren, Philips Micro Development Systems
..!{seismo|philabs|decvax}!mcvax!philmds!sater
In the distant future: Hans.van.Staveren@mds.philips.nl.eur.UUCP