News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

BIOS Ignoring Boot Code???

Started by Astro, September 21, 2009, 01:25:56 AM

Previous topic - Next topic

Astro

Hi,

I tried the following, but when I cane to boot the system, it just seemed to ignore it and boot the HD. I explicitly told it to boot from this USB device first, so fairly sure if it iwas going to work, it would have. Unfortunately, the only USB stick I know for certain that is bootable is currently in use. I'm going to get another of the same type to play with.

I inserted a stick (formatted FAT16 IIRC), and proceeded to manually edit the boot sector.

I built the following code thus:

@echo off
echo.
echo Building...
\masm32\bin\ml /c %1.asm
.\link.exe /tiny %1.obj
echo.
echo Completed!
echo.
dir %1.*
pause


link.exe is from the Lnk563.exe package.

The code I tried to execute was:

.model tiny
.stack 0
.code
start:
jmp @F

@@:
mov ah,00h ; VIDEO - SET VIDEO MODE - AH=00, AL=11h - G  80x30  8x16  640x480  mono      .   A000 VGA,MCGA,ATI EGA,ATI VIP
mov al,11h
int 10h

mov ah,02h ; VIDEO - SET CURSOR POSITION - AH=02, AL=00 - Pos 0,0
mov al,00h
int 10h

mov ah,02h ; DOS 1+ - WRITE CHARACTER TO STANDARD OUTPUT - AH=02, AL=00
mov al,00h
mov dl,'a'
int 21h

@@:
hlt
jmp @B

org 510
dw 0AA55h

end start


I used this for reference to the interrupts: http://www.ctyme.com/intr/int.htm

Maybe I missed something completely fundamental?

Do I need to set up the segment registers before I do anything? I tried org 0 before jmp @F but no change.

Is the following correct:

0000:0000 to 000F:FFFF for 1 Mb in 16-bit real mode?

I'm also aware of:

CS - Code Segment
DS - Data Segment
SS - Stack Segment

but

ES - ??
FS - ??
GS - ??

Are these just other segment registers like CS, DS, etc..? Do they carry any special meaning? I'm struggling to find anything on it.

I'm trying this anyway, just in case.

Thanks!

EDIT:

jmp @F

@@:
xor ax,ax
mov cs,ax
mov ds,ax
;...


Best regards,
Robin.

Astro

I tried the following:

.model tiny
.8086
.stack 0
.code
start:
jmp @F

@@:
xor ax,ax
mov cs,ax
mov ds,ax

mov ah,00h ; VIDEO - SET VIDEO MODE - AH=00, AL=11h - G  80x30  8x16  640x480  mono      .   A000 VGA,MCGA,ATI EGA,ATI VIP
mov al,11h
int 10h

mov ah,02h ; VIDEO - SET CURSOR POSITION - AH=02, AL=00 - Pos 0,0
mov al,00h
int 10h

mov ah,02h ; DOS 1+ - WRITE CHARACTER TO STANDARD OUTPUT - AH=02, AL=00
mov al,00h
mov dl,'a'
int 21h

@@:
hlt
jmp @B

org 510
dw 0AA55h

end start


after setting the USB boot device type to "Forced FDD" - "Invalid partition table".

Hmm...

Best regards,
Robin.

japheth

Video mode 11h is a graphics mode, monochrom. Using such a mode in boot sector code is a bad idea. It might work, but there's no guarantee that the BIOS will display the characters properly.

If you need more than 25 lines, use video mode 3 and select a 8x8 character set. This will give you 50 lines.

Also, you should set up a valid stack pointer before calling INT 10:

xor ax,ax
mov ss,ax
mov sp,7C00h

And finally, you shouldn't call the DOS interrupt in boot code (Int 21h), because there's no DOS yet.

Astro

Quoteyou shouldn't call the DOS interrupt in boot code (Int 21h), because there's no DOS yet.
I wondered about that when I saw reference to DOS.

QuoteVideo mode 11h is a graphics mode
OK - that would be what the 'G' is for.  :cheekygreen:

QuoteAlso, you should set up a valid stack pointer before calling INT 10:

xor ax,ax
mov ss,ax
mov sp,7C00h
Thanks for this. I need to study segmented addressing a bit more. All the examples I found so far are poor and don't explain clearly how it works.

Would the above code produce:

SS:SP ?
0000:7C00 ?

I'm not sure if I've understood this correctly or not.

Memory is addressable in 64 kB blocks. 0000:0000 would be the first byte at the start of memory.

0001:0000 - would this be the first byte of the second segment (65536 bytes after the start of memory)?

How would I properly set up the CS and DS registers?

Does segmented memory differ from paged memory?

I'll have another look at those interrupts.

Best regards,
Robin.

FORTRANS

Quote from: Astro on September 21, 2009, 12:45:46 PM
Would the above code produce:

SS:SP ?
0000:7C00 ?

I'm not sure if I've understood this correctly or not.

   Yes, 0000:7C00H.

Quote
Memory is addressable in 64 kB blocks. 0000:0000 would be the first byte at the start of memory.

   Right.

Quote
0001:0000 - would this be the first byte of the second segment (65536 bytes after the start of memory)?

   No.  For the 65536 bytes it should be 1000H:0000.

Quote
How would I properly set up the CS and DS registers?

   Well, CS gets set up by the BIOS.  DS needs to be set up by you
in a fashion similar to what japheth did with SS.

Quote
Does segmented memory differ from paged memory?

   Completely different concepts.  Segmented memory allows for
addressing memory with (usually) 16-bit registers to access more
than 64k memory.  You essentially multiply the segment register
by 16 and add the pointer register to create a 20 bit address.
That is a full megabyte.  But a segment register plus pointer can
only address a specific 64k range at one time.

Steve N.

MichaelW

For a hard disk, two boot sectors are involved in the boot process, the MBR first, followed by the volume boot sector. The term boot sector generally refers to the volume boot sector for a hard disk, or to the first sector for a diskette. AFAIK hard drives have from the beginning reserved the entire first track, even though only the first sector was typically used. The reserved sectors where used by drive overlay programs to store code and data, and I seem to recall seeing some evidence that Windows uses at least some of the reserved sectors for some purpose.

The attachment is a Windows console program that displays a hex-ascii dump of the MBR and the volume boot sector for the first partition, if it is bootable (tested under Windows 2000 with FAT32 only).
eschew obfuscation

dedndave

wow Michael - lol
didn't know you could do that

Astro

Quote
Quote0001:0000 - would this be the first byte of the second segment (65536 bytes after the start of memory)?
No.  For the 65536 bytes it should be 1000H:0000.
Hmm.

1000h = 4096d

4096 x 16 = 65536... ahh - I just got it.  :cheekygreen:

I thought for each 0000:0000, 0001:0000 it jumped 64 kB.

OK... so if I wanted the 1,024,000th byte it would be:

1024000 / 16 = FA00

FA00:FFFF ?

EDIT: That also means a segment can start anywhere, but code can only reference things in that segment? A jmp for example?

Best regards,
Robin.

FORTRANS

Hi Robin,

QuoteEDIT: That also means a segment can start anywhere, but code can only reference things in that segment? A jmp for example?

   Right, a segment starts on a 16-byte "page" boundary.  And
executing code can only access stuff within that segment without
having to change the code segment register contents.  That is
called near calls and jumps.  If the call or jump goes to a different
segment it is a far call or jump.

Regards,

Steve N.

Astro

Great! Thanks!

My code seems to be doing something (crashing the system) but I seem unable to write the code entirely into the boot sector without getting "Invalid partition table" errors.

http://home.teleport.com/~brainy/fat16.htm - I was using the section "FAT16 Boot Record" for reference.

.model tiny
.8086
.stack 50
.code
start:
;-----------------------------
org 0

jmp short bt1

;-----------------------------
org 3

boot db "BootDisk"

;-----------------------------
org 0Bh

boot0B dw 200h ;bytes per sector
boot0D db 1 ;sectors per cluster
boot0E dw 1 ;reserved sectors (the boot sector is reserved)
boot10 db 2 ;number of copies of the FAT
boot11 dw 0E0h ;root directory entries (224 for 1.4 mb)
boot13 dw 0B40h ;total disk sectors
boot15 db 0F0h ;media descriptor byte (F0 for 1.4 mb)
boot16 dw 9 ;sectors per FAT
boot18 dw 12h ;sectors per cylinder
boot1A dw 2 ;number of heads
boot1C dd 0 ;hidden sectors
boot20 dd 63 ;number of sectors
boot24 dd 0 ;logical number of partition
boot26 db 0 ;extended signature of partition (29h)
boot27 dd 1 ;serial number of partition
boot2B db "TESTPART",0,0,0 ;volume name (11 bytes)
boot36 db "TESTPART" ;bytes DOS name

;-----------------------------
bt1:
cli ; disable maskable interrupts
xor di,di
mov ss,di
mov sp,7C00h ; SS:SP = 0000:7C00
sti

xor ax,ax
mov ds,ax

; write z to screen 5 times
mov ah,0Ah
mov al,'z'
mov bh,0
mov bl,0
mov cx,5
int 10h

@@:
hlt
jmp @B

;-----------------------------
org 1FEh
dw 0AA55h

end start


I ended up formatting the stick, and just replacing the code starting at the location referenced by the already existing jmp.

0000h: EB 3C 00 ...

so at 003Ch I started my code, and zeroed the rest of it between the end of my code and 55 AA.

Best regards,
Robin.

dedndave

tiny model - no stack
and needs to be exe2bin'ed - or set the right switch on the linker to create a binary instead of an exe

MichaelW

For a jump instruction encoded as EB3Ch, the 3Ch is a "displacement", not an offset address. To get the destination offset address you add the displacement to the offset address of the next instruction (i.e. the instruction following the jump instruction).
eschew obfuscation

Astro

Hi,

@Michael: OK, if I understand correctly, it will jump forward *from this point* 3Ch bytes?

@dedndave: It was complaining about no stack directive. I was just playing with numbers to see if there was any discernible effect (if any). I'm using the linker from Lnk563.exe package.

Build options:

ml /c
link /tiny


The output file is by default .com.

Best regards,
Robin.

BlackVortex

Quote from: MichaelW on September 21, 2009, 02:25:15 PM
For a hard disk, two boot sectors are involved in the boot process, the MBR first, followed by the volume boot sector. The term boot sector generally refers to the volume boot sector for a hard disk, or to the first sector for a diskette. AFAIK hard drives have from the beginning reserved the entire first track, even though only the first sector was typically used. The reserved sectors where used by drive overlay programs to store code and data, and I seem to recall seeing some evidence that Windows uses at least some of the reserved sectors for some purpose.

The attachment is a Windows console program that displays a hex-ascii dump of the MBR and the volume boot sector for the first partition, if it is bootable (tested under Windows 2000 with FAT32 only).

I just tested this in my win7 x64 and it worked !!!  (and ntfs of course, lol)