[comp.sys.ibm.pc] Multi-partition boot source

motti@ocsmd.ocs.com (Motti Bazar) (08/24/89)

Hi there,

Today I read some postings of you trying to have multi-boot partitions
on your machines. I developed more then a year ago a small utility to
do the same thing (then, for MS-DOS, Minix and OS/2).
  
I wrote a new Multi-partition utility that runs under MS-DOS and modifies
the main hard-disk boot sector for booting multiple operating systems from
the same hard-disk.

The 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 MS-DOS. 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.
  
Anybody trying this process, please let me know how was it, what type of
hard-disk was used and if more help is needed.

Have fun...

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                   Germantown, MD 20874
                                        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  
;
;           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