motti@ocsmd.ocs.com (Motti Bazar) (12/11/89)
Hi there,
After getting a lot of requests to post this, I'm posting my original
stuff again. It took me some time to find it. I assume some things
are old but even then, its usefull (no flames please). I'm in the
process of doing some new stuff. I got from Robert Hall his DOS
side development code (thanks) and wrote some utilities to fully do
all my kernel development under DOS (both the editor and compiler
under DOS are better) and even produce the Minix kernel into a DOS
file and then use another utility to boot Minix from DOS. Again,
the DOS code is Robert's and I just added the autoboot. If anybody
want more info I'll be happy to provide it.
Have fun ... Motti
uunet!ocsmd!motti
Original posting follows:
Subject: Multi-partition boot and Booting MINIX from the hard disk
==================================================================
Hi there,
After getting Minix 1.2 from PH I wanted to put it on my hard-disk.
I discovered that I could not do it. One thing that I noticed was that
in the "compatibility" file (at bugs.nosc.mil) and in the Minix docs it was
stated that it will not run on an 8MHz IBM-AT. My problem was even bigger
because not only that I have an 8MHz IBM-AT but it also uses a non
standard hard-disk (72Mb Core). I posted some questions but my mail was
broken and the answers that I got did not help alot. So, I decided to go
for it by myself. I looked on some archive sites (e.g. bugs.nosc.mil)
and found some pointers here and there.
I am posting all this thing for all of you out there that want to do the same
thing but do not want to spend the time investigating and developing all of
it. The Multi-partition boot is good even for anybody that already installed
Minix on his/her hard-disk but does not have a nice and clean way for the
Multi-partition boot. All this code can be used for other versions of Minix
(I assume) because it does not involve Minix directly but the boot code
only.
By the way, the version of Minix I got was compiled and linked for the
XT type machines so before trying it on my AT I had to install it on an
XT machine, copy at_wini.c to wini.c and recreate the system.
What I ended doing can be divided to 2 parts:
1. Development of a Multi-partition boot utility.
2. Modifications to Minix 1.2 for hard-disk booting.
After all this text, I included all the code needed to perform whatever
I describe here namely "mfdisk.asm" for the Multi-partition boot and
"bootblok.s" a modified version of Minix's boot block.
There are a lot more things I am going to add sometime in the future (like
using the hard-disk as root instead of the ram-disk etc.) but I decided to
post it now because its a full solution to start with and can save a lot
of time.
Part 1 - Development of a Multi-partition boot utility
========================================================
I wrote a new Multi-partition utility that runs under MesSDOS and lets you
to modify the main hard-disk boot sector for booting multiple operating
systems from the same hard-disk.
This program will write a new boot sector to the first hard-disk drive that
prompts for the partition you want to boot from (1-4). To the question
'Boot partition (1-4):' you have to answer with the number of the partition
you want to boot from (1-4).
The program must be compiled as a .COM file (remember exe2bin) and run
under MesSDOS.
When the program is run, it produces a message telling you what it is going
to do. At this time you can abort it by typing <CTRL-C> or type <CR> to
allow it to modify the hard-disk.
Before trying to boot from multiple partitions you have to partition your
hard-disk and put the operating systems on the partitions. I used
a partitioning utility called "disk manager" from Ontrack Computer Systems.
There are other utilities available (e.g. Speedstore) but this one is a
good one.
After the partitioning, you can run the Multi-partition boot utility
called "mfdisk" (I started writing it with fdisk in mined and wanted to
write an fdisk clone but then I found disk manager and ended just with
whatever is there). After running the utility you are set and ready to go.
Part 2 - Modifications to Minix 1.2 for hard-disk booting
===========================================================
Some of the information stated here I found in a post done by Don Dugger
(msg-id: 133@wldrdg.uucp). I had to make many more modifications especially
for standardizing the Minix boot sector without any need of the user to
understand its hard-disk parameters, edit it for defining where the boot is
etc. In this boot version I tried to be totally hard-disk independent. If
somebody will really try it, please let me know about it. Remember that for
using this boot you need to use also the Multi-partition boot process.
The steps for installing Minix on the hard-disk on my 8MHz IBM-AT with the
72Mb Core drives (the way I developed the boot record "bootblok.s" will
allow it to use other drives automatically) are:
1. The version of Minix I got was compiled and linked for the XT type
machines so before installing it on my AT I installed it on an XT machine,
copied at_wini.c to wini.c and recreated the system on the XT.
Then, I copied it back to the diskettes and started working on my AT.
2. Partition and format the hard-disk as follows:
Partition 1 - MesSDOS - 32 Mb (/dev/hd1)
Partition 2 - Minix /usr - 20 Mb (/dev/hd2)
Partition 3 - Minix boot - 740 Kb (/dev/hd3)
Partition 4 - Minix / - 17 Mb (/dev/hd4)
3. Install /usr on /dev/hd2 and setup the root filesystem diskette to
mount it automatically when booting. After this step you still have
to boot from 2 diskettes (1. Boot 2. Root filesystem) but then you
can use /dev/hd2 as /usr.
Now for the hard-disk boot:
4. Change a line in the file "const.h" in the "h" directory from:
#define BOOT_DEV (dev_nr) 512
to:
#define BOOT_DEV (dev_nr) 0x304
5. Remake the filesystem (fs).
6. Modify the "build.c" program in the "tools" directory as follows:
In subroutine "patch1" change the lines:
ubuf[(SECTOR_SIZE/2) - 4] = sectrs + 1;
ubuf[(SECTOR_SIZE/2) - 3] = ds;
ubuf[(SECTOR_SIZE/2) - 2] = ip;
ubuf[(SECTOR_SIZE/2) - 1] = cs;
to:
ubuf[(SECTOR_SIZE/2) - 5] = sectrs + 1;
ubuf[(SECTOR_SIZE/2) - 4] = ds;
ubuf[(SECTOR_SIZE/2) - 3] = ip;
ubuf[(SECTOR_SIZE/2) - 2] = cs;
ubuf[(SECTOR_SIZE/2) - 1] = 0xAA55;
and remake the "build" program. This modifications is for setting the
magic number in Minix's boot record.
7. Replace the file "bootblok.s" in the "tools" directory with the
"bootblok.s" file included at the end of this posting and remake the
boot block.
8. Run "build" as follows:
build bootblok kernel mm fs init fsck /dev/hd3
This will build the Minix image into "/dev/hd3" instead of to "/dev/fd0".
9. Put the Root filesystem diskette in the first drive and execute:
cp /dev/fd0 /dev/hd4
It will copy the Root filesystem diskette to /dev/hd4.
You are set. If you followed the instructions correctly (I hope) your
system should boot and ask you for the partition to boot from and when
you type 3 it will boot Minix from your hard-disk and load the ram-disk
from /dev/hd4.
Anybody trying this process, please let me know how was it, what type of
hard-disk was used and if more help is needed.
Motti (Mordehai) Bazar
uucp : ..uunet!ocsmd!motti snail: Online Computer Systems, Inc.
bitnet : motti%ocsmd@uunet.uu.net 20251 Century Blvd.
internet: motti@ocsmd.uu.net OR Germantown, MD 20874
bazar@gwusun.gwu.edu vox: (301) 428-3700
######################## C u t h e r e for ########################
######################## m f d i s k . a s m ########################
page ,132
title MFDISK - FDISK clone & multiple boot-record modifier
;------------------------------------------------------------------------------
; This program will write a new boot sector to the first HD drive
; that prompts for the partition you want to boot from (1-4).
; To the question 'Boot partition (1-4):' you have to answer with
; the number of the partition you want to boot from (1-4).
;
; The program must be compiled as a .COM file (remember exe2bin)
; and run under MesSDOS.
;
; The makefile for compiling under MesSDOS should look like:
;
; mfdisk.obj: mfdisk.asm
; masm mfdisk;
;
; mfdisk.com: mfdisk.obj
; link mfdisk;
; exe2bin mfdisk.exe mfdisk.com
; del mfdisk.exe
;
; When the program is run, it produces a message telling you what
; it is going to do. At this time you can abort it by typing
; <CTRL-C> or type <CR> to allow it to modify the hard-disk.
;
; Now you can boot multiple operating systems (MesSDOS, OS/2,
; SCO Xenix and Minix) from the same hard-disk). To do so you
; had to partition your hard-disk to separate partitions, each
; with another operating-system boot.
;
; Motti (Mordehai) Bazar
;
; uucp : ..uunet!ocsmd!motti
; bitnet : motti%ocsmd@uunet.uu.net
; internet: motti@ocsmd.uu.net OR
; bazar@gwusun.gwu.edu
;
; snail: Online Computer Systems, Inc.
; 20251 Century Blvd.
; Germantown, MD 20874
;
; vox: (301) 428-3700
;
;
; This utility is distributed for personal use only. Use it, modify it
; or do anything you like, just live this comment and let me know of
; any bugs or enhancements you made to it, thanks.
;
;------------------------------------------------------------------------------
;-------------------------
; First, some definitions
;-------------------------
VIDEO equ 10h
KBD equ 16h
DISKIO equ 13h
DOS equ 21h
CR equ 0Dh
LF equ 0Ah
;---------------------------
; Here comes the real thing
;---------------------------
CODE segment byte public 'CODE'
assume cs:CODE, ds:CODE
org 100h
WRITBOOT:
jmp START ; jump around
DISKBUF db 512 dup(?)
HELLOMS db CR, LF
db 'MFDISK - Multiple boot FDISK clone', CR, LF
db CR, LF
db 'This program will read the boot sector from the first disk', CR, LF
db 'and merge the partition table from it with the boot program', CR, LF
db 'supplied and write it all back to the disk overlaying what', CR, LF
db 'was there. The resultant boot program will prompt for the', CR, LF
db 'desired partition for booting (1-4).', CR, LF
db CR, LF
db 'The original boot program will be saved in a file named', CR, LF
db 'IBMBOOT.SVE in the default directory.', CR, LF
db CR, LF
db '<CR> = continue, CONTROL-C = abort ... $'
CRLF db CR, LF, '$'
IBMBOOT db 'IBMBOOT.SVE',0
OKMSG db CR, LF, 'Boot sector updated', CR, LF, '$'
ERMSG1 db CR, LF, 'Error reading boot sector', CR, LF, '$'
ERMSG2 db CR, LF, 'Cannot open save file', CR, LF, '$'
ERMSG3 db CR, LF, 'Cannot write save file', CR, LF, '$'
ERMSG4 db CR, LF, 'Cannot close save file', CR, LF, '$'
ERMSG5 db CR, LF, 'Cannot write boot sector', CR, LF, '$'
BOOTHDL dw 0 ; Boot backup file handle
START:
;----------------------
; Show opening message
;----------------------
mov dx, offset HELLOMS
mov ah, 9
int DOS
RDCNS:
;---------------------------------------------------------
; Get user's response: <CR> or CONTROL-C (aborted by DOS)
;---------------------------------------------------------
mov ah, 0Ch
mov al, 1
int DOS
cmp al, CR ; <CR> key ?
jne RDCNS ; No, retry
;-----------------------------------------
; <CR> typed, go and modify the hard-disk
;-----------------------------------------
mov dx, offset CRLF ; Echo <CR><LF>
mov ah, 9
int DOS
;------------------------------------
; Read the sector from the hard-disk
;------------------------------------
mov si, 5 ; Retry for 5 times
RDDSK:
push si ; Save retry counter
mov ah, 2 ; Read disk
mov al, 1 ; 1 sector
mov bx, offset DISKBUF ; Point to buffer
mov ch, 0 ; Cylinder 0
mov cl, 1 ; Sector 1
mov dh, 0 ; Track 0
mov dl, 80h ; Harddisk 0
int DISKIO
pop si
jnc RDOK ; Good read
dec si ; More tries?
jnz RDDSK ; Yes, try again
mov dx, offset ERMSG1 ; No, point to trouble message
mov ah, 9 ; say console write
int DOS ; can't read boot sector
mov ah, 4Ch ; say terminate
mov al, 1 ; error return code
int DOS
;---------------------------------
; Create the file to save it into
;---------------------------------
RDOK:
mov dx, offset IBMBOOT ; get file name
mov ah, 3Ch ; say create it
sub cx, cx ; zero attribute
int DOS
jnc OPENOK ; file opened
mov dx, offset ERMSG2 ; can't open save file
mov ah, 9
int DOS ; tell 'em
mov ah, 4Ch ; say terminate
mov al, 2 ; reason
int DOS
;---------------------------------
; Write sector to the backup file
;---------------------------------
OPENOK:
mov BOOTHDL, ax ; save handle
mov bx, ax ; and put in bx
mov ah, 40h ; say write to file
mov dx, offset DISKBUF ; get location
mov cx, 512 ; say 1 sector
int DOS ; ask to have it done
jnc WRTOK ; good write
mov dx, offset ERMSG3 ; can't write to save file
mov ah, 9
int DOS ; tell 'em
mov ah, 4Ch ; say terminate
mov al, 3 ; reason
int DOS
;-------------------
; Close backup file
;-------------------
WRTOK:
mov ah, 3Eh ; say close file
mov bx, BOOTHDL
int DOS
jnc CLOSOK ; closed ok
mov dx, offset ERMSG4 ; can't close save file
mov ah, 9
int DOS ; tell 'em
mov ah, 4Ch ; say terminate
mov al, 4 ; reason
int DOS
;-----------------------------------------------------
; Copy the read partition table into our sector so it
; will use it when booting.
;-----------------------------------------------------
CLOSOK:
push si
mov si, offset DISKBUF+1BEh ; start of partition table
mov di, offset BOOTSEC+1BEh ; ditto for new sector
cld ; make direction positive
mov cx, 4*16+2 ; how many bytes to move
rep movsb ; move em
;----------------------------------------
; Write our sector back to the hard-disk
;----------------------------------------
mov si, 5 ; 5 retries
WRTBOOT:
push si
mov ah, 3 ; say write to disk
mov al, 1 ; say 1 sector
mov bx, offset BOOTSEC ; point to sector to write
mov cx, 1 ; say sector 1
mov dx, 80h
int DISKIO ; do the io
pop si
jnc UPDOK ; good write to boot sector
dec si ; count retries
jnz WRTBOOT ; try again
mov dx, offset ERMSG5 ; can't write boot sector file
mov ah, 9
int DOS ; tell 'em
mov ah, 4Ch ; say terminate
mov al, 5 ; reason
int DOS
;----------------------------------------------------------
; Inform the user that the operation finished successfully
; and exit back to DOS.
;----------------------------------------------------------
UPDOK:
mov dx, offset OKMSG ; say we did it
mov ah, 9
int DOS ; tell 'em
mov ah, 4Ch ; say terminate
mov al, 0 ; good return code
int DOS
;****************************************************************
;* BOOTSEC *
;* *
;* Here comes the sector patched into the hard-disk *
;****************************************************************
BOOTSEC:
BSTART equ $ ; Start offset of our boot sector
BOOTLOC equ 7C00h ; Boot sector loaded there
BOOTSIG equ 7DFEh ; Boot sector signal address
MOVETO equ 600h ; Where to move it
PARTTBL equ BSTART + 1BEh ; Start of partition table in our code
cli
xor ax, ax ; (AX) = 0
mov ss, ax ; (SS) = Set stack segment to 0
mov sp, offset BOOTLOC ; Get boot code address
mov si, sp ; (SI) = Source address
mov es, ax ; (ES) = 0
mov ds, ax ; (DS) = 0
sti
cld
mov di, MOVETO ; (DI) = Destination address
mov cx, 100h ; (CX) = # of words to move
rep movsw ; Move it
;------------------------------------
; Setup to continue the boot process
;------------------------------------
mov ax, MOVETO + offset RELBOOT - BSTART
push ax
ret
RELBOOT:
;----------------------------------
; Set all partitions as not active
;----------------------------------
mov bx, MOVETO + 1BEh
mov byte ptr [bx], 0
mov byte ptr 16[bx], 0
mov byte ptr 32[bx], 0
mov byte ptr 48[bx], 0
;------------------------------------------
; Show boot prompt 'Boot partition (1-4):'
;------------------------------------------
WRPRMPT:
mov si, MOVETO + offset BOOTMSG - BSTART
lodsb
mov cl, al
xor ch, ch
WR000:
lodsb
mov bx, 7
mov ah, 0Eh
int VIDEO
loop WR000
;-------------------------------
; Get user's response & show it
;-------------------------------
mov ah, 0 ; Get keyboard input
int KBD
push ax
mov ah, 10 ; Show it
mov cx, 1
int VIDEO
pop ax
;----------------------------------
; Check for legal partition number
;----------------------------------
cmp al, '1' ; # below 1 ?
jb WRPRMPT ; Yes, error
cmp al, '4' ; # above 4 ?
ja WRPRMPT ; Yes, error
;--------------------------------------
; AL contains partition # to boot from
;--------------------------------------
and al, 7 ; Mask partition #
;----------------------------------------
; Calculate partition table entry to use
;----------------------------------------
mov si, MOVETO + 1BEh ; point to first entry
CALCPART:
dec al
jz GOTPART
add si, 16 ; Advance to next partition
jmp short CALCPART
GOTPART:
;-----------------------------------------------------
; Set the requested partition as the active partition
;-----------------------------------------------------
mov byte ptr[si], 80h
push si
push bx
mov ax, 0301h
mov bx, MOVETO
mov cx, 1
mov dx, 80h
int diskio
pop bx
pop si
;-------------------------------------------------------------
; Now go and try to read the selected partition's boot sector
;-------------------------------------------------------------
mov dx, [si] ; (DH) = drive, (DL) = head
mov cx, [si+2] ; (CH) = track, (CL) = sector
mov bp, si ; Save partition pointer
mov di, 5 ; Set retry count
RDBOOT:
mov bx, BOOTLOC ; Location for boot
mov ax, 0201h ; Read 1 sector
push di
int DISKIO ; Go read
pop di
jnc GOODRD ; Good read
xor ax, ax ; Recalibrate
int DISKIO
dec di ; Decrement retries count
jnz RDBOOT ; Counter at zero ?
;---------------------------------------------------
; Can't read boot sector, show a message and hangup
;---------------------------------------------------
mov si, MOVETO + offset MSG2 - BSTART
WRMSG:
lodsb ; Get message length
mov cl, al
xor ch, ch
WR002:
lodsb
mov bx, 7
mov ah, 0Eh
int VIDEO
loop WR002
jmp WRPRMPT
;------------------------------------------------
; Boot sector read, check for the boot signature
;------------------------------------------------
GOODRD:
mov si, MOVETO + offset MSG3 - BSTART ; Point to no boot msg
mov bx, BOOTSIG
cmp word ptr [bx], 0AA55h ; Check for the boot signature
jne WRMSG
;-----------------------------------------------------------------
; Finaly, go and boot.
;
; Before booting set:
; SI - points to partition table entry we are booting from
; BX - starting cylinder number of this partition
;-----------------------------------------------------------------
mov si, bp ; Restore partition table pointer
mov ax, word ptr 2[si] ; AH-cyl, AL-sec
xor bh, bh
mov bl, al
shl bx, 1
shl bx, 1 ; BH-2 msb bits
mov bl, ah ; BL-8 lsb bits
mov ax, offset BOOTLOC ; Where partition boot start
push ax
ret
BOOTMSG db LMSGB, CR, LF, 'Boot partition (1-4): '
LMSGB equ ($-BOOTMSG)-1
MSG2 db LMSG2, CR, LF, 'Error loading operating system'
LMSG2 equ ($-MSG2)-1
MSG3 db LMSG3, CR, LF, 'Missing operating system'
LMSG3 equ ($-MSG3)-1
org BSTART + 512
CODE ends
end WRITBOOT
######################## C u t h e r e for ########################
######################## b o o t b l o k . s ########################
|----------------------------------------------------------------------------
|
| This is a modified version of the Minix bootblok.s file. It supports the
| boot of the operating system (Minix 1.2) from the hard-disk.
| I found some of this code in one of the postings but it had problems
| like its inability to boot from non-standard high capacity disks
| (my Core 72Mb disk has 9 heads) and the need to setup it up with the
| cylinder number and sectors/track.
| The way I built it is that the starting cylinder number is passed
| automatically from the main boot code (you have to use my Multi-partition
| boot code to support it) and in the beginning I inquire the type of disk
| and use it instead of hardcoding it into the code.
|
| The other change (here and in build) is to support the magic number
| at the end of the boot sector. My multi-partition boot utility sets
| the main boot sector to check for it when trying to load the requested
| boot sector from the partition requested to be boot from.
|
| Have fun.....
|
| Motti (Mordehai) Bazar
|
| uucp : ..uunet!ocsmd!motti
| bitnet : motti%ocsmd@uunet.uu.net
| internet: motti@ocsmd.uu.net OR
| bazar@gwusun.gwu.edu
|
| snail: Online Computer Systems, Inc.
| 20251 Century Blvd.
| Germantown, MD 20874
|
| vox: (301) 428-3700
|
|
| 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 192K - 512 (to get itself out of the way). Then it loads the
| operating system from the boot diskette into memory, and then jumps to
| fsck.
| 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 502 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 (fsck) which address is given
| by the last 2 words in the boot block.
|
| Summary of the words patched into the boot block by build:
|
| Word at 502: # sectors to load
| Word at 504: # DS value for fsck
| Word at 506: # PC value for fsck
| Word at 508: # CS value for fsck
| Word at 510: Magic boot block #
|
| This version of the boot block must be assembled without separate I & D
| space.
|
|----------------------------------------------------------------------------
BIOSSEG = 0x07C0 | Boot block is loaded here
BOOTSEG = 0x2FE0 | Boot block is copied there (192K-512b)
DSKBASE = 120 | 120 = 4 * 0x1E = ptr to disk parameters
final = 502
fsck_ds = 504
fsck_pc = 506
fsck_cs = 508
magic = 510
.globl begtext, begdata, begbss, endtext, enddata, endbss | asld needs these
.text
begtext:
.data
begdata:
.bss
begbss:
.text
|---------------------------------------------------------------
| My Multi-partition boot code sets BX as the starting cylinder
| of the partition we are booting from. Save it for use.
|---------------------------------------------------------------
mov ax, #BIOSSEG
mov ds, ax
mov startcyl, bx
|---------------------------
| copy bootblock to bootseg
|---------------------------
xor si, si | (DS:SI) = point to original block
mov ax, #BOOTSEG
mov es, ax
xor di, di | (ES:DI) = point to new block
mov cx, #256 | # of words to move
rep
movw | Copy loop
|----------------------
| start boot procedure
|----------------------
jmpi start, BOOTSEG | (CS) = BOOTSEG, continue execution
start:
mov dx, cs
mov ds, dx | (DS) = (CS)
mov ss, dx | (SS) = (CS) [stack in high core]
mov sp, #1536 | Initialize SP to high core
xor ax, ax
mov es, ax | (ES) = 0
|----------------------------
| initialize disk parameters
|----------------------------
mov ax, #atpar | tenatively assume 1.2M diskette
seg es
mov DSKBASE, ax
seg es
mov DSKBASE+2, dx
|----------------
| print greeting
|----------------
mov ax, #2 | reset video
int 0x10
mov ax, #0x0200 | Put cursor in upper-left corner
xor bx, bx
xor dx, dx
int 0x10
mov bx, #greet | Show greeting msg
call print
|---------------------
| Set disk parameters
|---------------------
movb ah, #8 | Return current drive parameters
movb dl, #0x80 | First hard-disk
int 0x13
andb cl, #0x3F | discard cylinder number high bits
xorb ch, ch | CX - Number of sectors per track
mov tracksiz, cx
movb dl, dh
incb dl | It was 0 origin
xorb dh, dh | DX = Number of heads
mov nheads, dx
|-----------------------------------------
| Load the operating system from diskette
|-----------------------------------------
load:
call setreg | set up ah, cx, dx
|-------------------------------------------------------------------
| Calculate start address in memory to load data into:
| "disksec" is 1 in the beginning, each sector is 512 bytes.
| The beginning address to start load into is 1536 (512*3) so
| in memory we start with the disk sector + 2.
| We have to multiply the sector number by 512 to get the physical
| address (shl 9) but if we use it for the segment we need
| to shift it (9-4) 5 times only.
|-------------------------------------------------------------------
mov bx, disksec | BX = number of next sector to read
add bx, #2
shl bx, #1
shl bx, #1
shl bx, #1
shl bx, #1
shl bx, #1
mov es, bx | (ES:BX) = core address (BX = 0)
xor bx, bx
add disksec, ax | AX = how many sectors to read
orb cl, xtra | cylinder high bits
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.
|---------------------------
cli
mov bx, tracksiz | fsck expects # sectors/track in bx
mov ax, fsck_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 @fsck_pc | jmp to fsck
|-------------------------------------------------------------------
| SETREG
|
| Given the number of the next disk block to read, disksec,
| compute the cylinder, sector, head, and number of sectors
| to read as follows:
|
| DL - Hard-disk drive number
| DH - Head number
| CH - Cylinder to read
| CL - Sector number
| xtra - high 2 bits of cylinder
| AL - # of sectors to read
|-------------------------------------------------------------------
setreg:
|--------------------------------------------
| Divide Start-sector-# by Sectors-per-track
|--------------------------------------------
mov si, tracksiz | SI = Sectors per track
mov ax, disksec | AX = next sector to read
xor dx, dx | DX:AX = 32-bit start sector number
div si | divide sector # by track size
| AX-logical track no
| DX-sector # (0-origin)
mov cx, ax | CX = logical track #
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:
|-----------------------
| Calculate head number
|-----------------------
push si
mov si, nheads | SI = Number of heads
mov ax, cx
xor dx, dx | DX:AX = 32-bit logical start track
div si | divide logical track # by # of heads
| AX-# of cylinders from beginning of partition
| DX-head
movb dh, dl | (DH) = head number
pop si
movb dl, #0x80 | (DL) = driver number (80=hd)
mov cx, ax
add cx, startcyl | low cylinder for boot partition
push cx
xorb cl, cl
shr cx, #1
shr cx, #1 | excess cylinder goes into cl (high 2 bits)
movb xtra, cl | xtra - high 2 bits of cylinder
pop cx
movb ch, cl | (CH) = Cylinder #
movb cl, bl | (cl) = sector number (0-origin)
incb cl | (CL) = sector number (1-origin)
mov ax, si | (AX) = Number of sectors to read
ret | return values in ax, cx, dx
|------------------------------
| ERROR
|
| error & print routines
|------------------------------
error:
push ax
mov bx, #fderr
call print | print msg
xor cx, cx
err1:
mul 0 | delay
loop err1
int 0x19
|------------------------------------
| PRINT
|
| Print a string pointed by BX
|------------------------------------
print:
movb al, (bx) | AL = Character 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
disksec: .word 1 | Next sector to read
xtra: .byte 0 | 2 msb of cylinder number
startcyl: .word 0 | Partition start cylinder
tracksiz: .word 0 | Sectors per Track
nheads: .word 0 | Number of heads
pcpar: .byte 0xDF, 0x02, 25, 2, 9, 0x2A, 0xFF, 0x50, 0xF6, 1, 3 | for PC
atpar: .byte 0xDF, 0x02, 25, 2,15, 0x1B, 0xFF, 0x54, 0xF6, 1, 8 | for AT
fderr: .asciz "Read error, Rebooting...\r\n"
greet: .asciz "\rBooting MINIX 1.2 (HD v1.00)\r\n"
|------------------------------------------------------------
| Don't forget that words 502 - 510 are filled in by build.
| The regular code had better not get that far.
|------------------------------------------------------------
.text
endtext:
.data
enddata:
.bss
endbss: