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

USB Booting Secrets

14 views
Skip to first unread message

Mike Gonta

unread,
Dec 31, 2010, 2:25:08 PM12/31/10
to
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?

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?

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?

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, 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.
Use int 13h function ah=8 to determine the BIOS emulated geometry.

Presented here is simple boot sector / boot loader.
The drive parameters are obtained and the in memory Bios Parameter
Block (at 7C00h) is updated. This information can used later to
calculate CHS. he next 35 sectors are loaded to 0:600h. The A20
line is set and because there is way too much space available in a
512 byte boot sector the background intensity for text mode is set
so that all 16 colors are available. The loaded "kernel" (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.

The MBR table is not required (but 64 bytes of fill is - to make the
boot sector exactly 512 bytes). The use of the MBR is the subject of
another thread.


; Original code by Mike Gonta, Public Domain 2010

LOAD_ADDRESS equ 600h

KBC_STATUS equ 64h
KBC_COMMAND equ 64h
KBC_DATA equ 60h
KBC_INPUT_FULL equ 2
KBC_WRITE_OUTPUT equ 0D1h

ENABLE_A20 equ 0DFh

SECTORS_PER_TRACK equ 7C18h
NUMBER_OF_HEADS equ 7C1Ah
DRIVE_NUMBER equ 7C24h
DRIVE_TYPE equ 7C3Eh
NUMBER_OF_DRIVES equ 7C3Fh
A20_STATE equ 7C40h

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
; extra variables
db 0 ; drive type
db 0 ; number of drives
db 0 ; A20 state

start:
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov esp, 7C00h
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 dx
mov [DRIVE_NUMBER], dl
pop es

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
cli
push -1
pop es
mov bl, 1
call check_A20
jne .2
mov bl, 2
push bx
push es
mov ax, 2401h
int 15h
pop es
pop bx
call check_A20
jne .2
mov bl, 3
in al, 92h
and al, 0FEh
or al, 2
out 92h, al
call wait_A20
jne .2
mov bl, 4
call kbc_flush_input
mov al, KBC_WRITE_OUTPUT
out KBC_COMMAND, al
call kbc_flush_input
mov al, ENABLE_A20
out KBC_DATA, al
call wait_A20
jne .2
xor bl, bl
.2:
mov [A20_STATE], bl
sti
mov ax, 1003h
xor bx, bx
int 10h ; enable background intensity
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

check_A20:
mov BYTE [600h], 0
mov BYTE [es:16+600h], 1
cmp BYTE [600h], 1
ret

wait_A20:
xor cx, cx
.1:
call check_A20
jne .2
out 0EDh, al ; 1 microsecond delay
sub cx, 1
jne .1
.2:
ret

kbc_flush_input:
xor cx, cx
.1:
in al, KBC_STATUS
test al, KBC_INPUT_FULL
je .2
sub cx, 1
jne .1
.2:
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 446-($-$$) db 0

mbr:
db 0 ; status
db 0, 0, 0 ; H, S, C of first block
db 1 ; partition type
db 0, 0, 0 ; H, S, C of last block
dd 0 ; LBA of first sector
dd 2880 ; number of blocks
db 0 ; status
db 0, 0, 0 ; H, S, C of first block
db 0Bh ; partition type
db 0, 0, 0 ; H, S, C of last block
dd 2880 ; LBA of first sector
dd 501759-2880 ; number of blocks (256 Mb - 1.44 Mb)
times 16*2 db 0
dw 0AA55h

use16
org LOAD_ADDRESS
kernel:
times 512*34 db 90h
mov si, message
call kernel_print
mov ah, 10h
int 16h
int 19h

kernel_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


Mike Gonta
look and see - many look but few see

http://aeBIOS.com

Mike Gonta

unread,
Jan 2, 2011, 6:02:06 AM1/2/11
to
"peter" wrote in message
news:80e0d86c-91f2-47fa...@glegroupsg2000goo.googlegroups.com...
> Dear Mike
> After i compile your asm program, what tool I can use to write it to
> the first sector of my USB memory stick?

Hi Peter,

On Windows, the easiest way is with the free "USB Image Tool"
http://www.alexpage.de/

Another excelent free Windows tool is "HxD - Hexeditor"
http://mh-nexus.de/en/
with which you can raw "copy and paste" the image file to the USB drive.

dd for Windows (also available for Linux)
http://www.chrysocome.net/dd
It is important to transfer the image to the physical drive and not the
volume drive letter. If the flash drive is partitoned the volume will not
start at LBA 0.

dd --list

The list option will list the devices on the PC.

set disk =
dd --filter=removable if=your.img of=\\?\Device\Harddisk%disk%\Partition0

If for example, you only have one physical hard drive installed,
drive C: will be physical disk 0 and the flash drive will be physical disk
1.

set disk = 1

The filter=removable option prevents dd from writing to your hard drive
should you set the wrong disk number. See the web site for more details.

Mike Gonta

unread,
Jan 4, 2011, 5:14:19 AM1/4/11
to
"Mike Gonta" wrote in message news:ifplvf$o77$1...@speranza.aioe.org...

> dd for Windows (also available for Linux)
> http://www.chrysocome.net/dd
> It is important to transfer the image to the physical drive and not the
> volume drive letter. If the flash drive is partitoned the volume will not
> start at LBA 0.
>
> dd --list
>
> The list option will list the devices on the PC.
>
> set disk =
> dd --filter=removable if=your.img of=\\?\Device\Harddisk%disk%\Partition0
>
> If for example, you only have one physical hard drive installed,
> drive C: will be physical disk 0 and the flash drive will be physical disk
> 1.
>
> set disk = 1
>
> The filter=removable option prevents dd from writing to your hard drive
> should you set the wrong disk number. See the web site for more details.

If for example, the one physical hard drive installed has only one
partition -
drive C:, and you have one CD/DVD installed - drive D:, then the flash drive
will be drive E:.
After transferring the image, remove and re-insert the flash drive so that
Windows will recognize the new file system on the flash drive.

Rick Hodgin

unread,
Jan 28, 2011, 2:52:42 AM1/28/11
to
On Jan 4, 4:14 am, "Mike Gonta" <mikego...@REMOVEgmailTHIS.com> wrote:
> .....[removed]
> Mike Gonta

Awesome, Mike. Thanks!

- Rick C. Hodgin

0 new messages