| Author |
| Thread |
 |
|
|
|
USB Booting Secrets
Everything you always wanted to know about USB booting but were too USB (Unable or Sophisticated or Busy) to ask.
Have you ever seen this error message when trying to boot from a floppy disk?
Quote: |
|
Remove disks or other media.
Press any key to restart
|
|
I guess that floppy is not bootable.
Or how about this message when booting from a CD?
Quote: |
|
Boot from ATAPI CD-ROM :
Press any key to boot from CD. . .
|
|
If you don't touch the keyboard, that CD won't boot.
Or maybe you've seen this error message when booting from a USB flash drive?
Quote: |
|
Disk error
Press any key to restart
|
|
Gee wiz, another boot failure, right? Wrong!
USB Booting Secret #1: Everything boots!
In fact, all of the above messages came directly or indirectly from the boot sector of the device.
That's the way the PC works, based on the BIOS setup (that's up to you) the BIOS will load the first sector of the
Initial Program Load device to 7C00h, perform a few checks and then jump to 7C00h. Everything boots.
(Of course there are old computers with USB that can't boot a flash drive, but we're not concerned about those here).
USB Booting Secret #2: What happens in the boot sector, stays in the boot sector!
When it comes to USB booting there are basically 4 types of computers:
PC without USB, or with USB and can't boot USB because of old BIOS firmware.
PC that always boots USB with floppy disk emulation.
PC that always boots USB with hard drive emulation.
PC that examines the boot sector to determine the type of emulation and/or with BIOS selection setup.
Because #1 - everything boots and #2 - booting occurs no matter what's in the boot sector (it does of course have to
pass a few simple BIOS checks), we can come up with a simple USB booting method designed specifically for
OS development.
The floppy disk is dead, long live the floppy disk!
Tip # 1
The FAT12 floppy disk format is simple, easy and universal.
Transfering files to the USB is easy and it will run from any PC that can boot from USB.
Use CHS for access and don't assume floppy disk geometry.
Tip # 2
Ask and you shall receive.
Later on, in the second stage, use int 13h function ah=8 to obtain and save the BIOS emulated geometry. This
information can used later to calculate CHS.
Code: |
|
push dx
push es
mov ah, 8
int 13h ; get drive parameters
mov [DRIVE_TYPE], bl
and cx, 3Fh ; maximum sector number
mov [SECTORS_PER_TRACK], cx
mov [NUMBER_OF_DRIVES], dl
movzx dx, dh ; maximum head number
add dx, 1
mov [NUMBER_OF_HEADS], dx
pop es
pop dx
mov [DRIVE_NUMBER], dl
|
|
Presented here is simple boot sector / boot loader.
The next 35 sectors are loaded to 0:600h. The loaded second stage (filled with "nop" to make it 17 1/2 K in size)
displays a message to the screen.
5 lines of data statements follow to create a basic FAT12 file system structure.
Code: |
|
; Original code by Mike Gonta, Public Domain 2011
LOAD_ADDRESS equ 600h
use16
org 7C00h
jmp start
nop
db ' '
dw 512 ; bytes per sector
db 1 ; sectors per cluster
dw 36 ; reserved sector count
db 2 ; number of FATs
dw 16*14 ; root directory entries
dw 18*2*80 ; sector count
db 0F0h ; media byte
dw 9 ; sectors per fat
dw 18 ; sectors per track
dw 2 ; number of heads
dd 0 ; hidden sector count
dd 0 ; number of sectors huge
db 0 ; drive number
db 0 ; reserved
db 29h ; signature
dd 0 ; volume ID
db ' ' ; volume label
db 'FAT12 ' ; file system type
start:
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 7C00h
mov bx, LOAD_ADDRESS
mov cx, 2 ; track 0, sector 2
xor dh, dh ; side 0
mov ax, 223h ; read 35 sectors
test dl, dl
jne .1
mov ax, 211h ; read 17 sectors
call read
jc exit
add bx, 512*17
mov cx, 1 ; track 0, sector 1
mov dh, 1 ; side 1
mov ax, 212h ; read 18 sectors
.1:
call read
jc exit
jmp 0:LOAD_ADDRESS
read:
mov bp, 2 ; 3 tries
.1:
push ax
int 13h
jnc .2
sub bp, 1
jc .2
xor ax, ax
int 13h
pop ax
jmp .1
.2:
pop bp
ret
print:
mov ah, 0Eh
xor bh, bh
.1:
mov al, [si]
lea si, [si+1]
test al, al
je .2
int 10h
jmp .1
.2:
ret
exit:
mov si, boot_drive_read_error
call print
mov ah, 10h
int 16h
int 19h
boot_drive_read_error:
db 'Boot drive read error!', 13, 10
db 'Press any key to restart.', 13, 10, 0
times 510-($-$$) db 0
dw 0AA55h
use16
org LOAD_ADDRESS
stage2:
times 512*34 db 90h
mov si, message
call stage2_print
mov ah, 10h
int 16h
int 19h
stage2_print:
mov ah, 0Eh
xor bh, bh
.1:
mov al, [si]
lea si, [si+1]
test al, al
je .2
int 10h
jmp .1
.2:
ret
message:
db 'USB booting is easy', 13, 10
db 'Press any key to restart.', 13, 10, 0
times (512*35)-($-$$) db 0
fat1: ; empty FAT12 file system
db 0F0h, 0FFh, 0FFh
times 512*9-($-fat1) db 0
fat2:
db 0F0h, 0FFh, 0FFh
times 512*9-($-fat2) db 0
root:
times 512*14-($-root) db 0
|
|
Fixed bug reported by revolution.
Edited source code (removed extraneous code) to simplify presentation.
more USB Booting Secrets
How to transfer a bootable image to the USB flash drive
Last edited by Mike Gonta on 20 Aug 2011, 14:36; edited 5 times in total
|
31 Dec 2010, 18:54 |
|
revolution
When all else fails, read the source
Joined: 24 Aug 2004
Posts: 10875
Location: Talos IV
|
[DRIVE_NUMBER]=0 always. Looks like a bug to me.
Mike Gonta wrote: |
|
Use CHS for access and don't assume floppy disk geometry.
|
|
Why do you always assume 18 sectors per track?
|
31 Dec 2010, 20:26 |
|
|
|
revolution wrote: |
|
[DRIVE_NUMBER]=0 always. Looks like a bug to me.
|
|
That's just a placeholder in the assembled code which is updated with the saved BIOS drive number in dl.
revolution wrote: |
|
Why do you always assume 18 sectors per track?
|
|
Also just a place holder which is updated with the return parameters of int 13h, ah=8.
This same code boots and runs on any PC that can boot USB (it will also work on a floppy disk).
|
31 Dec 2010, 20:51 |
|
revolution
When all else fails, read the source
Joined: 24 Aug 2004
Posts: 10875
Location: Talos IV
|
The bug is here:
Code: |
|
push dx
push es
...
pop dx
mov [DRIVE_NUMBER], dl ;dl=0
pop es ;es=????
|
|
|
31 Dec 2010, 21:26 |
|
revolution
When all else fails, read the source
Joined: 24 Aug 2004
Posts: 10875
Location: Talos IV
|
Mike Gonta wrote: |
|
Also just a place holder which is updated with the return parameters of int 13h, ah=8.
|
|
Code: |
|
mov ax, 211h ; read 17 sectors
call read
jc exit
add bx, 512*17
mov cx, 1 ; track 0, sector 1
mov dh, 1 ; side 1
mov ax, 212h ; read 18 sectors
|
|
Looks rather fixed at 18 sectors to me. 
|
31 Dec 2010, 21:32 |
|
|
|
revolution wrote: |
The bug is here:
Code: |
|
push dx
push es
...
pop dx
mov [DRIVE_NUMBER], dl ;dl=0
pop es ;es=????
|
|
|
|
Thank you.
Fixed it. I wasn't paying attention to the order of the pushes.
|
31 Dec 2010, 22:25 |
|
|
|
revolution wrote: |
Mike Gonta wrote: |
|
Also just a place holder which is updated with the return parameters of int 13h, ah=8.
|
|
Code: |
|
mov ax, 211h ; read 17 sectors
call read
jc exit
add bx, 512*17
mov cx, 1 ; track 0, sector 1
mov dh, 1 ; side 1
mov ax, 212h ; read 18 sectors
|
|
Looks rather fixed at 18 sectors to me.
|
|
This is the part that reads from the flash drive that boots with floppy drive emulation. The test for the drive number is
just before it.
Code: |
|
mov ax, 223h ; read 35 sectors
test dl, dl
jne .1
|
|
If dl=80h (hard drive emulation) the code jumps past this code to here.
Code: |
|
.1:
call read
jc exit
|
|
And reads 35 sectors.
The code to convert LBA to CHS based on the obtained values for SECTORS_PER_TRACK and NUMBER_OF_HEADS is
trivial but not required for loading 35 sectors from LBA=1.
|
31 Dec 2010, 22:34 |
|
Mac2004
Joined: 15 Dec 2003
Posts: 313
|
I tested Mike's code on 2 different machines (amd64 3500+ and 4000+). Boot example seems to work nicely.
Should this thread be added to the FAQ section? These booting issues
are frequently asked questions.
regards
Mac2004
|
02 Jan 2011, 12:18 |
|
|
|
Mac2004 wrote: |
|
I tested Mike's code on 2 different machines (amd64 3500+ and 4000+). Boot example seems to work nicely.
|
|
Hi Mac2004,
Thanks for testing.
The small step from antiquated floppy disk to USB flash drive seems to be a gigantic hurtle for the OS dev beginner.
|
09 Jan 2011, 14:35 |
|
Mac2004
Joined: 15 Dec 2003
Posts: 313
|
Mike Gonta wrote: |
Mac2004 wrote: |
|
I tested Mike's code on 2 different machines (amd64 3500+ and 4000+). Boot example seems to work nicely.
|
|
Hi Mac2004,
Thanks for testing.
The small step from antiquated floppy disk to USB flash drive seems to be a gigantic hurtle for the OS dev beginner.
|
|
Most of modern bioses support usb booting nicely.
No problem  Thank you for releasing the code.
Regards
Mac2004
|
09 Jan 2011, 18:05 |
|
|
|
Forum Rules:
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|
|
|
|
|
Powered by phpBB © 2001-2005 phpBB Group.
|