boot sector

From: Jeffrey S. Sharp <>
Date: Tue Jan 22 09:58:04 2002

Here's a boot sector I whipped up that helps me run a dual-boot
FreeBSD/Windows system using NTLDR with much elegance. It is derived from
a boot sector I wrote for a mystery OS, and includes a debug routine that
isn't used but was left in there because I was proud of it. I haven't
looked at this in quite a while, but it works. It is in NASM (not MASM)

;;; ===========================================================================
;;; This is the source to a fake boot sector to help the Windows NT bootloader,
;;; ntldr, load other operating systems. All this does is load the "real" boot
;;; sector from a drive and pass control to it. The drive number is hard-coded
;;; by the DRIVE %define below. You need NASM to assemble this file.
;;; ===========================================================================

;; BIOS drive number to load from

;; I hate "jmp short"
%macro jmps 1
        jmp short %1

;; Where we want to be
org 0x7E00

;;; ===========================================================================
;;; CODE
;;; ===========================================================================

        ;; Setup stack, move code somewhere else, and jump there
        xor ax, ax
        mov ds, ax
        mov es, ax
        mov ss, ax
        mov sp, 0x7C00
        mov si, sp
        mov di, 0x7E00
        mov cx, 0x0100
        jmp moved + 0x200
moved: sti

        ;; Reset drive
        mov dl, DRIVE
        int 0x13
        jc error

        ;; Load real boot sector
        mov ax, 0x0201
        mov bx, 0x7C00
        mov cx, 0x0001
        mov dh, ch
        mov dl, DRIVE
        int 0x13
        jc error

        ;; Jump to real boot sector
        mov dl, DRIVE
        jmp 0x7C00

        ;; In case of error, print msg and lock up
error: mov si, errmsg
        call print
        jmps lockup

        ;; debug
        ;; Print the value of the registers and wait for a keystroke
debug: push ax
        push cx
        push dx
        push bp
        push ds
        push es
        push cs
        push ss
        mov bp, sp
        add bp, 22
        mov si, regs

.reg: call print
        mov cx, 4 ; print 4 digits
        mov dx, [bp] ; load word into dx

.digit: rol dx, 4 ; rotate so that lowest 4 bits are used
        mov ax, 0x0E0F ; ah = request, al = mask for nybble
        and al, dl
        add al, 0x90 ; convert al to hex digits in ASCII
        adc al, 0x40
        int 0x10
        loop .digit
        cmp bp, sp
        je .done
        sub bp, 2
        jmps .reg

.done: call print
        add sp, 24
        xor ax, ax
        int 0x16

        pop bp
        pop dx
        pop cx
        pop ax

        ;;; print
        ;;; prints the zero-terminated string pointed to by SI.
print: push ax
        push bx
        mov ah, 0x0E
        xor bx, bx

.char: lodsb
        or al, al
        jz .done
        int 0x10
        jmps .char

.done: pop bx
        pop ax

        ;; lockup
        ;; Locks the machine way up.
        jmps lockup

;;; ===========================================================================
;;; DATA
;;; ===========================================================================

        ;; Error message
errmsg: db 'Error reading boot sector. System halted.', 0

        ;; Register names
regs: db 13, 10, "AX=", 0
        db 13, 10, "CX=", 0
        db 13, 10, "DX=", 0
        db 13, 10, "BX=", 0
        db 13, 10, "SP=", 0
        db 13, 10, "BP=", 0
        db 13, 10, "SI=", 0
        db 13, 10, "DI=", 0
        db 13, 10, "DS=", 0
        db 13, 10, "ES=", 0
        db 13, 10, "CS=", 0
        db 13, 10, "SS=", 0
        db 13, 10, 0

        ;; Zero-padding to 512 bytes
pad: times 510-($-$$) db 0x00

        ;; Magic boot sector number
magic: dw 0xAA55

Jeffrey S. Sharp
Received on Tue Jan 22 2002 - 09:58:04 GMT

This archive was generated by hypermail 2.3.0 : Fri Oct 10 2014 - 23:34:57 BST