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