flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
flat assembler > OS Construction > USB Booting Secrets

Author
Thread Post new topic Reply to topic
Mike Gonta



Joined: 26 Dec 2010
Posts: 125
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 ah8
  int 13h                       ; get drive parameters
  mov [DRIVE_TYPE], bl
  and cx3Fh                   ; maximum sector number
  mov [SECTORS_PER_TRACK], cx
  mov [NUMBER_OF_DRIVES], dl
  movzx dxdh                  ; maximum head number
  add dx1
  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 axax
  mov dsax
  mov esax
  mov ssax
  mov sp7C00h
    
  mov bxLOAD_ADDRESS
  mov cx2                     ; track 0, sector 2
  xor dhdh                    ; side 0
  mov ax223h                  ; read 35 sectors
  test dldl
  jne .1
  mov ax211h                  ; read 17 sectors
  call read
  jc exit
  add bx512*17
  mov cx1                     ; track 0, sector 1
  mov dh1                     ; side 1
  mov ax212h                  ; read 18 sectors
.1:
  call read
  jc exit

  jmp 0:LOAD_ADDRESS
  
read:
  mov bp2                     ; 3 tries
.1:
  push ax
  int 13h
  jnc .2
  sub bp1
  jc .2
  xor axax
  int 13h
  pop ax
  jmp .1
.2:
  pop bp
  ret
 
print:
  mov ah0Eh
  xor bhbh
.1:
  mov al, [si]
  lea si, [si+1]
  test alal
  je .2
  int 10h
  jmp .1
.2:
  ret
  
exit:
  mov siboot_drive_read_error
  call print
  mov ah10h
  int 16h
  int 19h
   
boot_drive_read_error:
  db 'Boot drive read error!'1310
  db 'Press any key to restart.'13100
  times 510-($-$$)                db 0
                                  dw 0AA55h

use16
org LOAD_ADDRESS
stage2:
  times 512*34 db 90h
  mov simessage
  call stage2_print
  mov ah10h
  int 16h
  int 19h
  
stage2_print:
  mov ah0Eh
  xor bhbh
.1:
  mov al, [si]
  lea si, [si+1]
  test alal
  je .2
  int 10h
  jmp .1
.2:
  ret
  
message:
  db 'USB booting is easy'1310
  db 'Press any key to restart.'13100  
  times (512*35)-($-$$)           db 0
  
fat1:                           ; empty FAT12 file system
  db 0F0h0FFh0FFh
  times 512*9-($-fat1)            db 0
fat2:
  db 0F0h0FFh0FFh
  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
Post 31 Dec 2010, 18:54
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 12167
Location: The outernet
[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?
Post 31 Dec 2010, 20:26
View user's profile Send private message Visit poster's website Reply with quote
Mike Gonta



Joined: 26 Dec 2010
Posts: 125

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).
Post 31 Dec 2010, 20:51
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 12167
Location: The outernet
The bug is here:

Code:
  push dx
  push es
...
  pop dx
  mov [DRIVE_NUMBER], dl ;dl=0
  pop es ;es=????

Post 31 Dec 2010, 21:26
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 12167
Location: The outernet

Mike Gonta wrote:
Also just a place holder which is updated with the return parameters of int 13h, ah=8.


Code:
  mov ax211h                  ; read 17 sectors
  call read
  jc exit
  add bx512*17
  mov cx1                     ; track 0, sector 1
  mov dh1                     ; side 1
  mov ax212h                  ; read 18 sectors

Looks rather fixed at 18 sectors to me. Question
Post 31 Dec 2010, 21:32
View user's profile Send private message Visit poster's website Reply with quote
Mike Gonta



Joined: 26 Dec 2010
Posts: 125

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.
Post 31 Dec 2010, 22:25
View user's profile Send private message Reply with quote
Mike Gonta



Joined: 26 Dec 2010
Posts: 125

revolution wrote:

Mike Gonta wrote:
Also just a place holder which is updated with the return parameters of int 13h, ah=8.


Code:
  mov ax211h                  ; read 17 sectors
  call read
  jc exit
  add bx512*17
  mov cx1                     ; track 0, sector 1
  mov dh1                     ; side 1
  mov ax212h                  ; read 18 sectors

Looks rather fixed at 18 sectors to me. Question


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 ax223h                  ; read 35 sectors
  test dldl
  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.
Post 31 Dec 2010, 22:34
View user's profile Send private message Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 314
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
Post 02 Jan 2011, 12:18
View user's profile Send private message Reply with quote
Mike Gonta



Joined: 26 Dec 2010
Posts: 125

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.
Post 09 Jan 2011, 14:35
View user's profile Send private message Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 314

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. Smile

No problem Smile Thank you for releasing the code.

Regards
Mac2004
Post 09 Jan 2011, 18:05
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >

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.

Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2013, Tomasz Grysztar.