www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/02/14/01:34:08

Message-ID: <3303F85B.6699@rangenet.com>
Date: Thu, 13 Feb 1997 23:30:03 -0600
From: Dan Hedlund <markiv AT rangenet DOT com>
Reply-To: markiv AT rangenet DOT com
Organization: Range Net
MIME-Version: 1.0
To: Liam <marl AT rmplc DOT co DOT uk>
CC: djgpp AT delorie DOT com
Subject: Re: Boot loader
References: <199702121712 DOT RAA11984 AT mx2 DOT rmplc DOT co DOT uk>

This is a multi-part message in MIME format.

--------------A3E364E18EF
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Liam wrote:
> 
> If you write a boot loader, is it limited to 512 bytes( 1 sector)?
> So apart from containig the boot header information, would the
> boot loader have to load a file from disk to continue the loading
> process? With out having DOS loaded, will this leave you
> with using the BIOS interupts?
> Also, does NASM support the PROC directive?
> Cheers
> Liam

I've writen a boot loader that loads a DOS file into memory, and runs
it.  To compile it type:

djasm bootstra.asm bootstra.bin bootstra.map

Then move bootstra.bin into the boot sector, and boot the computer.

It loads "bootrm.bin" into memory, and runs it.

-- 

*****      ***   **    **       Dan M. Hedlund
 ** **    *****  ***   **       <markiv AT rangenet DOT com>
 **  **  **   ** ****  **       http://www.rangenet.com/markiv
 **   ** **   ** ** ** **
 **   ** ******* **  ****
 **  **  **   ** **   ***
 ** **   **   ** **    **
*****    **   ** **    **

--------------A3E364E18EF
Content-Type: text/plain; charset=us-ascii; name="Bootstra.asm"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="Bootstra.asm"

; Dos Disk Structure
;
; Name:                 Length in Sectors
;
; Boot Loader           [RsvdSectors]
; File Allocation Table [SectorsFAT] * [NumFATs]
; Root Directory        32 * [NumDirs] / 512
; Data                  ...
;
; BIOS_Sector = (DOS_Sector % [SectorsTrack]) + 1
; BIOS_Track  = (Dos_Sector / [SectorsTrack]) / [NumHeads]
; BIOS_Head   = (Dos_Sector / [SectorsTrack]) % [NumHeads]
;
; Dos_Sector = ([SectorsCluster] * (Cluster - 2)) + offset Data
;

		.type	"bin"

		.start

                ; Jmp   RealStart
                .db     0xe9
                .dw     RealStart - 3

OEM:
                .db     0, 0, 0, 0, 0, 0, 0, 0  ; OEM name and version
BytesSector:
                .dw     0x200                   ; bytes per sector
SectorsCluster:
                .db     1                       ; sectors per cluster
RsvdSectors:
                .dw     1                       ; number of reserved sectors
NumFATs:
                .db     2                       ; number of FAT's on disk
NumDIRs:
                .dw     0x00e0                  ; number of root directory entries
NumSectors:
                .dw     0x0b40                  ; number of sectors
MD:
                .db     0xf0                    ; media descriptor byte
SectorsFAT:
                .dw     0x0009                  ; sectors per fat
SectorsTrack:
                .dw     0X0012                  ; sectors per track
NumHeads:
                .dw     2                       ; number of heads
HumHidSectors:
                .dd     0                       ; number of hidden sectors
NumSectors2:
                .dd     0                       ; (DOS4+) number of sectors if NumSectors = 0
Drive:
                .db     0                       ; (DOS4+) physical drive number

                .db     0                       ; (DOS4+) reserved
Sig:
                .db     0x29                    ; (DOS4+) signature byte
SerialNo:
                .dd     0                       ; (DOS4+) volume serial number
VolLabel:
                .db     "Hello World"           ; (DOS4+) volume label

                .db     0, 0, 0, 0, 0, 0, 0, 0  ; (DOS4+) reserved

                .db     0, 0

RealStart:
                mov     ax, 0x9000              ; 64k stack at 0x9000:0
                mov     ss, ax
                mov     sp, 0

                jmpf    0x7c0 : new_csip

new_csip:
                push    cs
                pop     ds

                pushf
                mov     ah, 0x60
                push    ax
                popf
                pushf
                pop     ax
                popf
                cmp     ah, 0x60
                je      ok386

                mov     si, Error386
                jmpl    ErrorMessage

ok386:
                pushw   0xb800
                pop     gs

                mov     ax, 0x8000
                mov     es, ax
                mov     fs, ax

                xor     bx, bx                  ; Load the FAT
                mov     ax, [RsvdSectors]       ; to 0x8000:0x0000
                mov     si, [SectorsFAT]
                call    ReadSectors
  

                mov     bx, 0x8000              ; Load the Root Directory
                mov     ax, [SectorsFAT]        ; to 0x8000:0x8000
                mov     cl, [NumFATs]
                mov     ch, 0
                mul     cx
                add     ax, [RsvdSectors]
  
                mov     si, [NumDIRs]
                shr     si, 4

                mov     [StartSector], ax
                add     [StartSector], si

                call    ReadSectors


                shl     si, 9
                add     si, bx

@L3:                                            ; find "BOOTRM.BIN" - "BOOTRM  BIN"
                cmp     si, bx
                je      @L2

                cmpd    es: [bx + 00], 0x544f4f42   ; "BOOT"
                jne     @L4
                cmpd    es: [bx + 04], 0x20204d52   ; "RM  "
                jne     @L4
                cmpw    es: [bx + 08], 0x204e4942   ; "BIN "
                jne     @L4

                mov     si, es: [bx + 26]       ; First FAT entry
                jmp     LoadRM

@L4:
                add     bx, 32
                jmp     @L3

@L2:
                mov     si, ErrorFile
                jmpl    ErrorMessage


LoadRM:                
                mov     cx, 0x1000
                mov     es, cx
                xor     bx, bx

                mov     ax, [BytesSector]       ; paragraphs per cluster
                mov     cl, [SectorsCluster]
                mov     ch, 0
                mul     cx
                shr     ax, 4
                xchg    si, ax

                mov     cx, 0x1000

LoadRMloop:
                mov     es, cx
                add     cx, si

                call    ReadCluster

                mov     di, ax
                add     di, ax
                add     di, ax
                shr     di, 1

                test    ax, 1
                mov     ax, fs: [di]
                jnz     odd
even:
                and     ax, 0x0fff
                jmp     EOcontinue
odd:
                shr     ax, 4

EOcontinue:
                cmp     ax, 0x0ff0
                jle     LoadRMloop

;               callf   0x1000:0
                .db     0x9a
                .dw     0
                .dw     0x1000

                movd    gs: [4], 0x12345678

Done:
                jmp     Done



                ; Read Cluster
                ; AX - Cluster
ReadCluster:

                pusha

                sub     ax, 2

                mov     dh, 0
                mov     dl, [SectorsCluster]
                mov     si, dx

                mul     dx
                add     ax, [StartSector]

                call    ReadSectors

                popa
                ret


                ; Read Several Sectors

                ; AX - Dos Starting Sector
                ; SI - Number of Sectors
                ; ES:BX - Buffer
ReadSectors:
                pusha
@L1:
                call    ReadSector

                inc     ax
                add     bx, [BytesSector]
                dec     si
                jnz     @L1

                popa
                ret


                ; Read One Sector

                ; AX - Dos sector
                ; ES:BX - Buffer
ReadSector:
                pusha

                call    Dos2Phys

                mov     si,3            ; three reties
rs_loop:
                mov     ax,0x0201       ; read one sector
                int     0x13            ; bios disk services
                jnc     rs_exit         ; carry set=error, not set=hunky dory
                dec     si              ; does not affect carry flag
                jz      rs_error        ; oop's sumpin wong wit du disk
                mov     ah,0            ; reset the disk system before we try again
                int     0x13            ; bds
                jmp     rs_loop         ; play it again, sam

rs_error:
                mov     si, ErrorDisk
                jmp     ErrorMessage

rs_exit:
                popa
                ret



                ; Dos Sector to Physical Sector
                ; 
                ; AX - Dos Sector

                ; DX - Head
                ; CH:CL : - track:cylinder - for int13
Dos2Phys:
                push    ax
                push    bx

                mov     dx, 0
                divw    [SectorsTrack]
                mov     bx, dx
                inc     bx

                mov     dx, 0
                divw    [NumHeads]
                mov     bh, al

                shl     ah, 6
                or      bl, ah

                mov     cx, bx

                mov     dh, dl
                mov     dl, 0

                pop     bx
                pop     ax
                ret


ErrorMessage:
                mov     ax, 0xb800

                mov     es, ax
                xor     di, di

em1:
                lodsb
                or      al, al
                jz      em2
                
                stosb

                mov     al, 0x0f
                
                stosb

                jmp     em1

em2:
                jmp     em2


ErrorDisk:
                .db     "Error reading disk!", 0
ErrorFile:
                .db     "Cannot load bootrm.bin!", 0
Error386:
                .db     "80386 required!", 0


		; obligatory bios doodad (int 19 won't recognize us without this)
		.org	0x1fe	; this will catch any overflow (code getting too big)
		.dw		0xaa55	; bios validation flag
		.align	512,0	; error checking, will cause the bin file to go to
						; 1024 bytes if there is any overflow above.
		.bss			; no bytes will be generated from this point on
StartSector:
                .dw     0

--------------A3E364E18EF--


- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019