Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Value of DL in MBR code

33 views
Skip to first unread message

James Harris

unread,
Apr 1, 2012, 6:02:38 PM4/1/12
to
In case someone else finds this useful, I found from recent tests with
a 2006 Phoenix BIOS on a machine with multiple disks that whatever
hard disk it booted it passed to the MBR the value of DL=0x80. I had
expected it to pass DL=0x80, or 0x81 or 0x82 etc depending on which
disk it booted.

Two possible explanations:

1. DL was overwritten in between the start of the code and me printing
it.

2. This BIOS always refers to the boot disk as 0x80.

Not sure which is the right explanation. It wasn't my intention to
test this but the code is below in case it is of interest to others.

Hopefully we can always be sure that whatever the MBR gets in DL is
the correct BIOS id of the boot drive.

;
; MBR test code
;

;Build with
; nasm -fbin mbr.nasm -ombr.bin -lmbr.list

bits 16
cpu 8086
org 0x7c00

;Set the hexadecimal letter case
; For upper case use 7
; For lower case use 7 + 32
hex_case: equ 7 + 32 ;See preceding comment

;Start with an opcode which has a value of less than 6
;; add al, [bx + si]
;; add ax, [bx + si]
; add al, 0
; db 1,0

;Set up the stack
xor ax, ax
mov ss, ax
mov sp, ax

;Set up any other relevant segment registers
mov ds, ax

;Set up the screen
call screen_init

;Write the value of DL
mov si, msg_dl_0x
call text_z_write
mov al, dl
call hex_byte_write

;Stop
jmp halt_loop



halt_loop:
hlt
jmp halt_loop



;******************************************************************************
;
; Hex output
;
;******************************************************************************

hex_byte_write:
push ax ;Save both digits of AL
shr al, 1
shr al, 1
shr al, 1
shr al, 1
call hex_digit_write
pop ax
call hex_digit_write
ret

hex_digit_write: ;Write the digit for the lower nibble of al
push ax
and al, 0x0f
cmp al, 9
jle .rawval

add al, hex_case

.rawval:
add al, "0"
call char_write
pop ax
ret


;******************************************************************************
;
; String output
;
;******************************************************************************

;Write the zero-terminated string pointed to by SI

text_z_write:
push si
push ax

.char_next:
mov al, [si]
test al, al
jz .done

call char_write
inc si
jmp .char_next

.done:
pop ax
pop si
ret


;******************************************************************************
;
; Char output
;
;******************************************************************************

char_write:

push bp ;Destroyed by some BIOSes
push bx
push ax

mov bh, [display_page]
mov bl, [display_ink]
mov ah, 0x0e
int 0x10

pop ax
pop bx
pop bp
ret


;******************************************************************************
;
; Get from the BIOS the current screen mode, active page number and
width
;
;******************************************************************************

screen_init:
push bx
push ax

;Set defaults that are noticeably incorrect
mov [display_mode], byte 255

;Set appropriate defaults
mov [display_ink], byte 7
mov [display_page], byte 0
mov [display_width], byte 80
mov [display_height], byte 25 ;NB: Assumed, not read

;Get current video mode, active page and display width
mov ah, 0x0f
clc
int 0x10
jc .done
mov [display_mode], al
mov [display_page], bh
mov [display_width], ah

.done:
pop ax
pop bx
ret


;******************************************************************************
;
; Data
;
;******************************************************************************

section .data

display_mode: db 0
display_page: db 0
display_width: db 0
display_height: db 0
display_ink: db 0

msg_dl_0x: db "Booted with DL=0x",0

Antoine Leca

unread,
Apr 3, 2012, 11:05:07 AM4/3/12
to
James Harris wrote:
> In case someone else finds this useful, I found from recent tests with
> a 2006 Phoenix BIOS on a machine with multiple disks that whatever
> hard disk it booted it passed to the MBR the value of DL=0x80. I had
> expected it to pass DL=0x80, or 0x81 or 0x82 etc depending on which
> disk it booted.
>
> Two possible explanations:
>
> 1. DL was overwritten in between the start of the code and me printing
> it.
>
> 2. This BIOS always refers to the boot disk as 0x80.

I believe the second option is the correct one. I do not pretend I fully
understand the Phoenix BIOS boot specifications about BEV etc. but it
seems to me the bootom line result is that the "normal booting" hard
disk is re-ordered as disk 0x80 after you change the order within the
bios (things might be different if you boot disk 0x80, it is failing, so
BIOS go through INT 18 and select the "next" disk which I guess will
show as 0x81.)


Antoine

James Harris

unread,
Apr 3, 2012, 5:06:15 PM4/3/12
to
On Apr 3, 4:05 pm, Antoine Leca <r...@localhost.invalid> wrote:
> James Harris wrote:
> > In case someone else finds this useful, I found from recent tests with
> > a 2006 Phoenix BIOS on a machine with multiple disks that whatever
> > hard disk it booted it passed to the MBR the value of DL=0x80. I had
> > expected it to pass DL=0x80, or 0x81 or 0x82 etc depending on which
> > disk it booted.
>
> > Two possible explanations:
>
> > 1. DL was overwritten in between the start of the code and me printing
> > it.
>
> > 2. This BIOS always refers to the boot disk as 0x80.
>
> I believe the second option is the correct one. I do not pretend I fully
> understand the Phoenix BIOS boot specifications about BEV etc.

Nor me.

> but it
> seems to me the bootom line result is that the "normal booting" hard
> disk is re-ordered as disk 0x80 after you change the order within the
> bios

Maybe. It seemed that whichever disk in the BIOS order list had the
boot sector got labelled as 0x80.

> (things might be different if you boot disk 0x80, it is failing, so
> BIOS go through INT 18 and select the "next" disk which I guess will
> show as 0x81.)

That was my guess too. But it was just a guess. At the end of the day
as long as DL has been set the value the BIOS uses should be
immaterial.

James

wolfgang kern

unread,
Apr 7, 2012, 8:10:08 AM4/7/12
to

James Harris wrote:

> In case someone else finds this useful, I found from recent tests with
> a 2006 Phoenix BIOS on a machine with multiple disks that whatever
> hard disk it booted it passed to the MBR the value of DL=0x80. I had
> expected it to pass DL=0x80, or 0x81 or 0x82 etc depending on which
> disk it booted.
>
> Two possible explanations:
>
> 1. DL was overwritten in between the start of the code and me printing
> it.
>
> 2. This BIOS always refers to the boot disk as 0x80.

when I remember my analysis of the GRUB-MBR then it seems to modify DL ?

> Not sure which is the right explanation. It wasn't my intention to
> test this but the code is below in case it is of interest to others.

> Hopefully we can always be sure that whatever the MBR gets in DL is
> the correct BIOS id of the boot drive.

OTOH, old DOS until incl. win98se always assigned drive-letter 'C:' to
the first partition of the HD it was booted from.


;my MBR test code:
;entered with HEXEDIT

000 push DX ;keep this alive
001 mov ax,0003h
004 int 10h ;set textmode+CLRScreen just in case it isn't.
006 mov BX,0070h ;page 0, gray on black
009 mov CX,0001h ;no repeat
00c pop AX ;get back DL-value
00d and AL,0fh
00f or AL,30h ;just the lower nibble is of interrest yet
011 mov AH,0Ah ;fn write single character
013 int 10h ;show either '0' or '1' or else ?
015 jmp self ;watch top left corner of screen until eye-blur...


expected '0' for IDE-master
'1' for IDE-slave
and '3' for SATA-02 (SATA 00 is empty, SATA 01 is a DVD-drive)

I checked just with one IDE and swapped master/slave including
correct jumper setting, but what a surprise, I see always Zero!

__
wolfgang


James Harris

unread,
Apr 8, 2012, 8:52:58 AM4/8/12
to
On Apr 7, 1:10 pm, "wolfgang kern" <nowh...@never.at> wrote:

...

> ;my MBR test code:
> ;entered with HEXEDIT
>
> 000 push DX          ;keep this alive
> 001 mov ax,0003h
> 004 int 10h          ;set textmode+CLRScreen just in case it isn't.
> 006 mov BX,0070h     ;page 0, gray on black
> 009 mov CX,0001h     ;no repeat
> 00c pop AX           ;get back DL-value
> 00d and AL,0fh
> 00f or  AL,30h       ;just the lower nibble is of interrest yet
> 011 mov AH,0Ah       ;fn write single character
> 013 int 10h          ;show either '0' or '1' or else ?
> 015 jmp self         ;watch top left corner of screen until eye-blur...
>
> expected '0' for IDE-master
>          '1' for IDE-slave
>      and '3' for SATA-02 (SATA 00 is empty, SATA 01 is a DVD-drive)
>
> I checked just with one IDE and swapped master/slave including
> correct jumper setting, but what a surprise, I see always Zero!

How about removing the jmp self and replacing it with an int 0x18?
Does it then call the second disk 0x81 or does the second disk also
get told it is 0x80? I need to get round to testing that myself at
some point.

James

Antoine Leca

unread,
Apr 18, 2012, 7:27:21 AM4/18/12
to
wolfgang kern wrote:
> OTOH, old DOS until incl. win98se always assigned drive-letter 'C:' to
> the first partition of the HD it was booted from.

We need to make a difference here between

- DOS which reserves one unit (A:) for the first floppy (without
actually checking if it were actually connected, since XT/AT BIOS only
can report from 1 to 4 floppy drives), and added a supplementary unit
(B:) for faked floppy if it were only one, to allow swapping floppies;
since hard disk volumes were allocated just after floppies, this made C:
the unit for the first hard disk volume _unless_ you install more than 2
floppy drives, something which is not usual (but can be done);

- Win9x (the protected mode VxD IIRC) which forces the first hard disk
volume to be C:, even if the firmware reports 0 floppies, even if it
detects there are no floppy available, even if the floppy support stack
is dismounted.


Antoine
0 new messages