Would you like to make this site your homepage? It's fast and easy...
Yes, Please make this my home page!
;----------------------------------------------------------------
; BootLoader - simple test boot loader for PCs
; The boot loader performs the following functions:
; - sets the segments for use in the boot process.
; - loads and verifies the boot image, then transfers control to it.
; v 0.01 Joseph Osako 3 June 2002
%define entrypoint 0x7C00 ; can't us an equate constant with the ORG directive
stage2_entry equ 0x1000 ; the segment:offset to load the second stage into
stage2_offset equ 0x0000
stack_seg equ 0x9000
stack_top equ 0xFFFC
VBIOS equ 0x10 ; BIOS interrupt vector for video services
ttype equ 0x0E ; insert character in AL as if screen were teletype
EOL equ 0x00 ;end of string marker
CR equ 0x0D
LF equ 0x0A
DBIOS equ 0x13 ; BIOS interrupt vector for disk services
disk_reset equ 0x00 ; disk reset service
disk_read equ 0x02 ; disk read service
cyl equ 0x00 ; cylinder to read from
head equ 0x00 ; head to read from
startsector equ 0x02 ; sector to start reading at
numsectors equ 0x01 ; number of sectors to read
%define zero(x) xor x, x
%macro write 1
mov si, %1
call printstr
%endmacro
[bits 16]
[org entrypoint]
; entry - the entrypoint to the code. Make a short jump passed the BPB.
entry:
jmp short entry2
; The Boot Parameter Block - keep this for compatibility with the FAT12 filesystem.
BPB times 56 db 0
; entry2 - do a far jump to ensure that you have the desired segment:offset location
entry2:
jmp 0x0000:start
;***************************************************
; start
; This is the real begining of the code. The first order of
; business is clearing the interrupts, then setting the
; segment registers and the stack pointer.
start:
mov ax, stack_seg
mov bx, stack_top
cli
mov ss, ax ; and the stack at an arbitrarily high point past ES.
mov sp, bx ; put the stack pointer to the top of SS
sti ; reset ints so BIOS calls can be used
mov ax, cs
mov ds, ax ; set DS == CS
write testnumber
mov [bootdrv], dl ; save boot drive info for later use
write reset
; reset disk to read from
reset_disk:
mov dl, [bootdrv]
zero (ah)
mov al, disk_reset
int DBIOS
jnc short read_disk
write no_reset
call shutdown
; read in the data from disk and load it to ES:BX (already initalized)
read_disk:
write loading
mov ax, stage2_entry
mov es, ax
mov dl, [bootdrv]
mov ch, cyl ; cylinder
mov dh, head ; head
mov cl, startsector ; first sector
mov al, numsectors ; number of sectors to load
mov ah, disk_read
mov bx, stage2_offset
int DBIOS
jnc short done_reading
write disk_fail
call shutdown
done_reading:
write done
; set up fake return frame for code returning from second stage
mov ax, cs
push ax
mov ax, reenter
push ax
; fake a jump to the second stage entry point
mov ax, stage2_entry
mov es, ax
mov bx, stage2_offset
push es
push bx
write snd_stage
retf
reenter:
mov ax, cs
mov ds, ax
write returned
shutdown:
write exit
jmp short $
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Auxilliary functions
;; printstr - prints the string point to by SI
printstr:
push ax
mov ah, ttype ; set function to 'teletype mode'
.loop:
lodsb ; update byte to print
cmp al, EOL ; test that it isn't EOL
jz short .endstr
int VBIOS ; put character in AL at next cursor position
jmp short .loop
.endstr:
pop ax
ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; data
testnumber db 'Test #12A', CR, LF, EOL
reset db 'Resetting disk drive.', CR, LF, EOL
loading db 'Loading stage two... ', EOL
done db 'done.', CR, LF, EOL
snd_stage db 'Second stage loaded, proceeding to switch context.', CR, LF, EOL
returned db 'Control returned to first stage, ', EOL
no_reset db 'Could not reset drive,', EOL
disk_fail db 'could not read second stage, ', EOL
exit db 'system halted.', EOL
bootdrv db 0 ; byte reserved for boot drive ID number
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; pad out to 510, and then add the last two bytes needed for a boot disk
space times (0x0200 - 2) - ($-$$) db 0
bootsig dw 0xAA55