Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!wuarchive!udel!princeton!splash!clk From: clk@splash.Princeton.EDU (Christopher Kranz) Newsgroups: comp.os.minix Subject: minix on a Gateway 2000 386 & Automatic reboot fix Message-ID: <6485@idunno.Princeton.EDU> Date: 22 Feb 91 01:39:41 GMT Sender: news@idunno.Princeton.EDU Reply-To: clk@gfdl.Princeton.EDU (Christopher Kranz) Organization: Geophysical Fluid Dynamics Laboratory Lines: 404 The original problem that I posted was that I was unable to boot minix on a Gateway 2000 386 with any of the boot disks that came with the PH distribution disks. The following messages would flash across the top of my screen until I removed the boot disk: "Booting MINIX 1.5. Copyright 1990 Prentice-Hall, Inc." "Read error. Automatic reboot." Several people responded to my post and indicated to me that it was indeed possible to run minix on a Gateway 2000 386 because they were doing so. I was also informed that there is a known bug in the boot block code that causes the problem I have described on some high density 5 1/4" drives. After reading people's suggestions and doing some poking around on my own I have come up with three different solutions. The first two require that I find another system to build minix and the last is a patch for the boot disk itself. I'll describe briefly the first two and go into more detail on the third since I believe that is the better way to go. The first and obvious solution is find a system that you can boot on, load minix on that system, get a patched version of bootblok.s, and finally rebuild the system using the new boot code. I heard from at least three people who actually went through this very procedure. One kind person was nice enough to mail me a fixed version of bootblok.s and I have appended it to the end of this post. The second solution is similar to the first. Basically it was suggested that I could get some code via ftp to enable minix to boot from a hard disk. The code I found was shoelace. In addition to being able to boot from a hard disk it also would allow me to build a floppy disk that would also boot up automatically. I found shoelace at plains.nodak.edu in the pub/Minix/oz directory. Again it would require me to find an alternate system to build the new boot disk. The solution that I finally went with was to patch the code that was on the boot disk itself. First make a copy of the AT boot disk using diskcopy. Then make another. You don't want to take any chances. Insert one of the copies into drive 0 and invoke debug using the debug script found towards the end of this post. Be sure to include all blank lines, they are very important to how debug interprets the script. The invocation might look like this: C:> debug < boot.fix This assumes you have saved the debug script as a file called boot.fix. What this script does is read in the the boot block, make some changes to the boot code, and then write the modified boot block back out to disk. I want to thank everyone who responded with special thanks to the following people: bk0y+@andrew.cmu.edu (Brian Christopher Kircher) seb3@gte.com (Steve Belczyk) chiting@garfield.cs.wisc.edu (Chiting Lam) martine@serena.cs.pdx.edu (Martine Wedlake) I hope this information helps somebody out there. Chris Kranz clk@gfdl.princeton.edu ---------------------Begin Debug Script------------------------------------- a100 mov cx,0001 mov bx,0200 mov ax,0201 int 13 jc 0106 int 20 g=100 a261 nop nop a269 jmp 02af a100 mov cx,0001 mov bx,0200 mov ax,0301 int 13 jc 0106 int 20 g=100 q ---------------------End Debug Script--------------------------------------- ---------------------Begin bootblok.s--------------------------------------- | When the PC is powered on, it reads the first block from the floppy | disk into address 0x7C00 and jumps to it. This boot block must contain | the boot program in this file. The boot program first copies itself to | address 256K - 1536 (to get itself out of the way). Then it loads the | operating system from the boot diskette into memory, and then jumps to menu. | Loading is not trivial because the PC is unable to read a track into | memory across a 64K boundary, so the positioning of everything is critical. | The number of sectors to load is contained at address 504 of this block. | The value is put there by the build program after it has discovered how | big the operating system is. When the bootblok program is finished loading, | it jumps indirectly to the program (menu) which address is given by the | last two words in the boot block. | | Summary of the words patched into the boot block by build: | Word at 504: # sectors to load | Word at 506: # DS value for menu | Word at 508: # PC value for menu | Word at 510: # CS value for menu | | This version of the boot block must be assembled without separate I & D | space. | | Guy Helmer - 1/6/91: | Fixed to properly handle 1.44M, 1.2M, 720K, and 360K disk types. LOADSEG = 0x0060 | here the boot block will start loading BIOSSEG = 0x07C0 | here the boot block itself is loaded BOOTSEG = 0x3FA0 | here it will copy itself (256K-1.5K) DSKBASE = 120 | 120 = 4 * 0x1E = ptr to disk parameters final = 504 menu_ds = 506 menu_pc = 508 menu_cs = 510 .globl begtext, begdata, begbss, endtext, enddata, endbss | asld needs these .text begtext: .data begdata: .bss begbss: .text | copy bootblock to bootseg mov ax,#BIOSSEG mov ds,ax xor si,si | ds:si - original block mov ax,#BOOTSEG mov es,ax xor di,di | es:di - new block mov cx,#256 | # words to move rep movw | copy loop | start boot procedure jmpi start, BOOTSEG | set cs to BOOTSEG start: mov dx,cs mov ds,dx | set ds to cs xor ax,ax mov es,ax | set es to 0 mov ss,dx | set ss to cs i.e., stack in high core mov sp,#1536 | initialize sp to high core | print greeting mov ax,#2 | reset video int 0x10 mov ax,#0x0200 | BIOS call in put cursor in ul corner xor bx,bx xor dx,dx int 0x10 mov bx,#greet call print | Initialize disk parameters, then | try 1.44M diskette by trying to read sector 18 | tracksiz has been initialized to 18 for dshd3 test mov ax,#dshd3 | double sided, high density 3.5" parms call sdp xor ax,ax | reset drive int 0x13 | Procedure sdp leaves es set to 0 | xor ax,ax | mov es,ax mov ax,#0x0201 | read sector, #sector = 1 mov bx,#0x0600 | es:bx buffer mov cx,#0x0012 | track 0, sector 18 xor dx,dx | drive 0, head 0 int 0x13 jnb L1 | Error. It wasn't 1.44M. Now set up for 1.2M mov tracksiz,#15 | 15 sectors per track mov ax,#dshd5 | double sided, high density 5.25" parms call sdp xor ax,ax | reset drive int 0x13 | Procedure sdp leaves es set to 0 | xor ax,ax | mov es,ax mov ax,#0x0201 | read sector, #sector = 1 mov bx,#0x0600 | es:bx buffer mov cx,#0x000F | track 0, sector 15 xor dx,dx | drive 0, head 0 int 0x13 jnb L1 | Try 720K by trying to read track 41. 360K has 40 tracks; 720K has | 80. Old code used to try to read track 64, which would grind the | heck out of some drives. | mov tracksiz,#9 mov ax,#dsdd3 | double sided, double density 3.5" parms call sdp xor ax,ax | reset drive int 0x13 | Procedure sdp leaves es set to 0 | xor ax,ax | mov es,ax mov ax,#0x0201 | read sector, number of sectors is 1 mov bx,#0x0600 | es:bx buffer mov cx,#0x2901 | track 41, sector 1 xor dx,dx | drive 0, head 0 int 0x13 jnb L1 | It wasn't 720K either, so set up for last possible | disk type (360K) and hope it works. mov ax,#dsdd5 | double sided, double density 5.25" parms call sdp xor ax,ax | reset drive int 0x13 L1: | Load the operating system from diskette. load: call setreg | set up ah, cx, dx mov bx,disksec | bx = number of next sector to read add bx,#2 | diskette sector 1 goes at 1536 ("sector" 3) shl bx,#1 | multiply sector number by 32 shl bx,#1 | ditto shl bx,#1 | ditto shl bx,#1 | ditto shl bx,#1 | ditto mov es,bx | core address is es:bx (with bx = 0) xor bx,bx | see above add disksec,ax | ax tells how many sectors to read movb ah,#2 | opcode for read int 0x13 | call the BIOS for a read jb error | jump on diskette error mov ax,disksec | see if we are done loading cmp ax,final | ditto jb load | jump if there is more to load | Loading done. Finish up. mov dx,#0x03F2 | kill the motor mov ax,#0x000C out cli mov bx,tracksiz | menu expects # sectors/track in bx mov ax,menu_ds | set segment registers mov ds,ax | when sep I&D DS != CS mov es,ax | otherwise they are the same. mov ss,ax | words 504 - 510 are patched by build seg cs jmpi @menu_pc | jmp to menu | Given the number of the next disk block to read, disksec, compute the | cylinder, sector, head, and number of sectors to read as follows: | ah = # sectors to read; cl = sector #; ch = cyl; dh = head; dl = 0 setreg: mov si,tracksiz | 9, 15, or 18 sectors per track mov ax,disksec | ax = next sector to read xor dx,dx | dx:ax = 32-bit dividend div si | divide sector # by track size mov cx,ax | cx = track #; dx = sector (0-origin) mov bx,dx | bx = sector number (0-origin) mov ax,disksec | ax = next sector to read add ax,si | ax = last sector to read + 1 dec ax | ax = last sector to read xor dx,dx | dx:ax = 32-bit dividend div tracksiz | divide last sector by track size cmpb al,cl | is starting track = ending track je set1 | jump if whole read on 1 cylinder sub si,dx | compute lower sector count dec si | si = # sectors to read | Check to see if this read crosses a 64K boundary (128 sectors). | Such calls must be avoided. The BIOS gets them wrong. set1: mov ax,disksec | ax = next sector to read add ax,#2 | disk sector 1 goes in core sector 3 mov dx,ax | dx = next sector to read add dx,si | dx = one sector beyond end of read dec dx | dx = last sector to read shl ax,#1 | ah = which 64K bank does read start at shl dx,#1 | dh = which 64K bank foes read end in cmpb ah,dh | ah != dh means read crosses 64K boundary je set2 | jump if no boundary crossed shrb dl,#1 | dl = excess beyond 64K boundary xorb dh,dh | dx = excess beyond 64K boundary sub si,dx | adjust si dec si | si = number of sectors to read set2: mov ax,si | ax = number of sectors to read xor dx,dx | dh = head, dl = drive movb dh,cl | dh = track andb dh,#0x01 | dh = head movb ch,cl | ch = track to read shrb ch,#1 | ch = cylinder movb cl,bl | cl = sector number (0-origin) incb cl | cl = sector number (1-origin) xorb dl,dl | dl = drive number (0) ret | return values in ax, cx, dx |-------------------------------+ | error & print routines | |-------------------------------+ error: push ax mov bx,#fderr call print | print msg | Wait for user to hit a key xor ax,ax int 0x16 | xor cx,cx |err1: mul 0 | delay | loop err1 int 0x19 print: | print string (bx) movb al,(bx) | al contains char to be printed testb al,al | null char? jne prt1 | no ret | else return prt1: movb ah,#14 | 14 = print char inc bx | increment string pointer push bx | save bx movb bl,#1 | foreground color xorb bh,bh | page 0 int 0x10 | call BIOS VIDEO_IO pop bx | restore bx jmp print | next character | Sets disk parameter pointer (vector 0x1E) to offset given in ax | and segment given in ds | Leaves es set to 0 and destroys bx sdp: xor bx,bx mov es,bx mov bx,ds seg es mov DSKBASE,ax seg es mov DSKBASE+2,bx ret disksec:.word 1 | For 3.5" drives (the format gap length parms might be wrong, but | that won't matter): dshd3: .byte 0xAF, 0x02, 25, 2,18, 0x1B, 0xFF, 0x54, 0xF6, 1, 8 | To save space, we use the same parameters for dsdd3 as dsdd5, | since they're close enough: | dsdd3:.byte 0xDF, 0x02, 25, 2, 9, 0x2A, 0xFF, 0x54, 0xF6, 1, 8 dsdd3: | For 5.25" drives: dsdd5: .byte 0xDF, 0x02, 25, 2, 9, 0x2A, 0xFF, 0x50, 0xF6, 1, 3 dshd5: .byte 0xDF, 0x02, 25, 2,15, 0x1B, 0xFF, 0x54, 0xF6, 1, 8 fderr: .asciz "Read error. Automatic reboot.\r\n" greet: .asciz "\rBooting MINIX 1.5. Copyright 1990 Prentice-Hall, Inc.\r\n" tracksiz:.word 18 | Changed to 15 for 1.2M or 9 for 360K and 720K | Don't forget that words 504 - 510 are filled in by build. The regular | code had better not get that far. .text endtext: .data enddata: .bss endbss: ---------------------End bootblok.s----------------------------------------- ------------------------------------------------------------------------------- Christopher L. Kranz GFDL Computer Systems Programmer P.O. Box 308 Geophysical Fluid Dynamics Laboratory Princeton, NJ 08542 ------------------------------------------------------------------------------- Internet Address: clk@gfdl.princeton.edu Commercial: (609)452-6585 UUCP Address: princeton!gfdl!clk FTS: 298-6585 FAX: (609)987-5063 =============================================================================== Brought to you by Super Global Mega Corp .com