flat assembler
Message board for the users of flat assembler.

Index > OS Construction > Bootloader / int 13h and USB problem

Author
Thread Post new topic Reply to topic
Richy



Joined: 20 Aug 2014
Posts: 10
Richy 20 Aug 2014, 18:21
So I have a working (if very basic) OS. I developed it a few years ago to run from a floppy disk. Today I decided the time had come to migrate it to a USB stick. I decided to take it step by step, getting small pieces working one by one. Hopefully the first pieces will be the hardest and the rest will fall into place nicely.

So anyway, the first piece is obviously the bootloader, and getting the PC to boot from USB using my code. Stage 1 bootloader works, it displays a nice welcome message. Problems arise when I try to load the stage 2 bootloader. It doesn't display the stage-2 message. It displays either a character of garbage or nothing at all, depending on what I try.

This is the stage-1 bootloader
Code:
[BITS 16]       ;16-bits real mode
[ORG 0x7C00]    ;Origin, tell the assembler that where the code will be in memory after it is been loaded

jmp main

;Included functions
%include "PrintScreen.inc"

;Data
LoadString db 'Stage 1 Bootloader Starting...', 10, 13, 0       
DriveNumber db 0x00


main:
xor AX, AX
MOV DS, AX
MOV ES, AX
mov ss, ax
mov sp, 7C00h

mov [DriveNumber], dl

MOV SI, LoadString      ;Store string pointer to SI
CALL PrintString        ;Call print string procedure


    reset:                      ; Reset the floppy drive
            mov ax, 0           ;
            ;mov dl, 80h           ; Drive: 0=first floppy, 80h = first HDD
            mov dl, byte [DriveNumber] ; drive
            int 13h             ;
            jc reset            ; ERROR => reset again


    read:
            mov ax, 1000h       ; ES:BX = 1000:0000
            mov es, ax          ;
            mov bx, 0           ;

            mov ah, 2           ; Load disk data to ES:BX
            mov al, 1           ; Load 1 sectors
            mov ch, 0           ; Cylinder=0
            mov cl, 2           ; Sector=2
            mov dh, 0           ; Head=0
            ;mov dl, 80h         ; Drive
            mov dl, byte [DriveNumber] ; drive
            int 13h             ; Read!

            jc read             ; ERROR => Try again


            jmp 1000h:0000      ; Jump to the program



TIMES 510 - ($ - $$) db 0       ;Fill the rest of sector with 0
DW 0xAA55                       ;Add boot signature at the end of bootloader
    


This seems to work and to get to the jump.

This is the stage-2 bootloader:

Code:
[BITS 16]       ;16-bits real mode
[ORG 0x0000]    ;Origin, tell the assembler that where the code will be in memory after it is been loaded

jmp main

;Included functions
%include "PrintScreen.inc"

;Data
HelloString db "Hello World",10,13,0


main:
mov ax, 1000h
MOV DS, AX
MOV ES, AX

MOV SI, HelloString     ;Store string pointer to SI
CALL PrintString        ;Call print string procedure
JMP $                   ;Infinite loop

    

Couldn't be simpler, really.

I put both on my usb stick using dd:
Code:
dd if=part1.bin of=\\.\d: bs=512 count=1
dd if=part2.bin of=\\.\d: seek=1 bs=512 count=1    


Where part1 and part2 refer to stage 1 and stage 2 respectively.

Like I said, all the code worked on the floppy. Back then I had hard-coded the drive value in dl to 0. Here I tried to change the drive number in Stage 1 to 1, 80h, 81h, or the value put in dl by the bootloader (either saving and loading it, or just leaving it unchanged). In no case do I get the hello world message. With 81h I get a garbage character, in the other cases I get nothing.

My best guess is that it is either not loading the stage 2 to memory (but I cannot figure out why) or the stage 2 is broken somehow (but it's too simple to break!).

Help? Please?
Post 20 Aug 2014, 18:21
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 20 Aug 2014, 18:35
Well we can't see the code for PrintScreen.inc so the problem could be there.

If you want to see what was loaded at 1000:0000 then put a hex dump routine in the boot sector to show what is there before jumping to it.

BTW this is the fasm board. Your code above doesn't compile for me
Post 20 Aug 2014, 18:35
View user's profile Send private message Visit poster's website Reply with quote
Richy



Joined: 20 Aug 2014
Posts: 10
Richy 20 Aug 2014, 18:39
I use NASM to compile it. It's the compiler I've always used, sorry.

I doubt the problem is in the printscreen code; that one can display messages in the stage 1 without problems. But here it is:

Code:
%ifndef _PRINTSCREEN_INC_
%define _PRINTSCREEN_INC_

;************************************************;
;       PrintCharacter
;       Prints a single character
;       AL: the character
;************************************************;


PrintCharacter:         ;Procedure to print character on screen
                        ;Assume that ASCII value is in register AL
MOV AH, 0x0E            ;Tell BIOS that we need to print one charater on screen.
MOV BH, 0x00            ;Page no.

INT 0x10                ;Call video interrupt
RET                     ;Return to calling procedure


;************************************************;
;       PrintString
;       Prints a null terminated string
;       DS=>SI: 0 terminated string
;************************************************;


PrintString:            ;Procedure to print string on screen
                        ;Assume that string starting pointer is in register SI

next_character:         ;Lable to fetch next character from string
LODSB 
OR AL, AL               ;Check if value in AL is zero (end of string)
JZ exit_function        ;If end then return
CALL PrintCharacter     ;Else print the character which is in AL register
JMP next_character      ;Fetch next character from string
exit_function:          ;End label
RET                     ;Return from procedure

%endif ;_PRINTSCREEN_INC_
    


Sorry, but how do I write a dump routine?
Post 20 Aug 2014, 18:39
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20363
Location: In your JS exploiting you and your system
revolution 20 Aug 2014, 18:49
Load bytes one by one from 1000:0000, convert to hex and print to the screen. This is basic debugging without access to a debugger. Even just displaying the first byte might tell you something if the value displayed is not what is expected.
Post 20 Aug 2014, 18:49
View user's profile Send private message Visit poster's website Reply with quote
smiddy



Joined: 31 Oct 2004
Posts: 557
smiddy 20 Aug 2014, 20:24
Check to see what your CS is...I suspect you CS is hosed. Other than that, looking at it seems ok to me.

Revolution, I like that debugging tip! I will use that! Smile
Post 20 Aug 2014, 20:24
View user's profile Send private message Reply with quote
Richy



Joined: 20 Aug 2014
Posts: 10
Richy 20 Aug 2014, 20:35
I added a line in my stage-2 to make sure:

Code:
mov ax, 1000h
MOV CS, AX
MOV DS, AX     

No change.
Post 20 Aug 2014, 20:35
View user's profile Send private message Reply with quote
neville



Joined: 13 Jul 2008
Posts: 507
Location: New Zealand
neville 20 Aug 2014, 23:27
Richy you are asking your PC BIOS to support floppy emulation when booting from USB. It probably doesn't. Which means that you will have to at least specify device 80H in register DL. You will probably also have to use INT13H/AX=4200H EDD function because in my experience few PC BIOS's support legacy INT13H/AH=2 for USB booting. The fact that the IPL worked proves little, because the BIOS finds and loads the device's Absolute Sector 0 in its own way (most likely but not necessarily using EDD).

I assume from your code that you've written your stage 2 code at Absolute Sector 2. Have you independently checked that it's actually there? (e.g. using HxD - see my recent post in Examples & Tutorials). Also you've set CS correctly by the JMP 1000H:0 Take out the MOV CS,AX. You can't set CS this way!

_________________
FAMOS - the first memory operating system
Post 20 Aug 2014, 23:27
View user's profile Send private message Visit poster's website Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u 21 Aug 2014, 14:59
There is no magic to booting from usb drives, it very simple.
But you must understand one or two things or you will not get it to boot. that is unlike any other method of booting USB does check what its booting.
Eg: normaly the MBR or boot sector is just load into memory at a set address and jump to.
But in the case of USB boot, it checks for BPB, if it users hdd emulation it will boot with or without BPB, if it users floppy emulation and you do not have a BPB, it will NOT boot.
Here are two examples, the one with BPB should work with any emulation, if placed on the disk right (assemble with fasm)
With BPB
Code:
Code:
;************************************
; By Dex
; Assemble with fasm
; c:\fasm USB1.asm USB1.bin
;
;************************************
org 0x7C00
use16
Boot:     jmp   start
     nop
;------------------------------------------;
;  Standard BIOS Parameter Block, "BPB".   ;
;------------------------------------------;
     bpbOEM     db  'MSDOS5.0'
     bpbSectSize     dw  512
     bpbClustSize     db  1
     bpbReservedSec  dw  1
     bpbFats     db  2
     bpbRootSize     dw  224
     bpbTotalSect     dw  2880
     bpbMedia     db  240
     bpbFatSize     dw  9
     bpbTrackSect     dw  18
     bpbHeads     dw  2
     bpbHiddenSect   dd  0
     bpbLargeSect     dd  0
     ;---------------------------------;
     ;  extended BPB for FAT12/FAT16   ;
     ;---------------------------------;
     bpbDriveNo     db  0
     bpbReserved     db  0
     bpbSignature     db  41           
     bpbID      dd  1
     bpbVolumeLabel  db  'BOOT FLOPPY'
     bpbFileSystem   db  'FAT12   '

;****************************
; Realmode startup code.
;****************************
start:
        xor   ax,ax
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   sp,0x7C00
         mov   si,Mesage1
        call  print
        jmp   $

;****************************
;  print.
;****************************
print:
        mov   ah,0Eh                       
again1:
   lodsb                             
        or   al,al                         
        jz   done1                         
   int  10h                           
        jmp  again1                       
done1:
   ret                               

Mesage1: db  'USB, with BPB works OK',0

;*************************************
; Make program 510 byte's + 0xaa55
;*************************************
times 510- ($-Boot)  db 0
dw 0xaa55
    

Without BPB
Code:
Code:
;************************************
; By Dex
; Assemble with fasm
; c:\fasm USB2.asm USB2.bin
;
;************************************
org 0x7C00
use16
;****************************
; Realmode startup code.
;****************************
start:
        xor   ax,ax
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   sp,0x7C00
         mov   si,Mesage1
        call  print
        jmp   $

;****************************
;  print.
;****************************
print:
        mov   ah,0Eh                       
again1:
   lodsb                             
        or   al,al                         
        jz   done1                         
   int  10h                           
        jmp  again1                       
done1:
   ret                               

Mesage1: db  'USB, without BPB works OK',0

;*************************************
; Make program 510 byte's + 0xaa55
;*************************************
times 510- ($-start)  db 0
dw 0xaa55
    
Post 21 Aug 2014, 14:59
View user's profile Send private message Reply with quote
Richy



Joined: 20 Aug 2014
Posts: 10
Richy 21 Aug 2014, 15:19
neville wrote:
Richy you are asking your PC BIOS to support floppy emulation when booting from USB. It probably doesn't. Which means that you will have to at least specify device 80H in register DL. You will probably also have to use INT13H/AX=4200H EDD function because in my experience few PC BIOS's support legacy INT13H/AH=2 for USB booting. The fact that the IPL worked proves little, because the BIOS finds and loads the device's Absolute Sector 0 in its own way (most likely but not necessarily using EDD).

I assume from your code that you've written your stage 2 code at Absolute Sector 2. Have you independently checked that it's actually there? (e.g. using HxD - see my recent post in Examples & Tutorials). Also you've set CS correctly by the JMP 1000H:0 Take out the MOV CS,AX. You can't set CS this way!


If I'm using HxD right.... sector 1 is all zeros? It never copied my stage-2 on the device! But DD returns a copy success...
Post 21 Aug 2014, 15:19
View user's profile Send private message Reply with quote
Richy



Joined: 20 Aug 2014
Posts: 10
Richy 21 Aug 2014, 15:52
Actually, now that I look at it closely, the stage-1 HxD displays was not mine at all. I've checked the binaries I'm trying to copy onto the stick and they are not what HxD is showing. But when I put the stick in and boot the computer it's my bootloader, not the one displayed in HxD, that takes over.

To make matters more confusing, I've copy-pasted my stages 1 and 2 bootloaders on top of the content of the USB stick using HxD. Now it boots and displays my stage 2's hello-world message.

So... I was not copying right? Can anyone check my DD commands and tell me if they're wrong?
Post 21 Aug 2014, 15:52
View user's profile Send private message Reply with quote
Richy



Joined: 20 Aug 2014
Posts: 10
Richy 21 Aug 2014, 19:04
Dex4u wrote:
There is no magic to booting from usb drives, it very simple.
But you must understand one or two things or you will not get it to boot. that is unlike any other method of booting USB does check what its booting.
Eg: normaly the MBR or boot sector is just load into memory at a set address and jump to.
But in the case of USB boot, it checks for BPB, if it users hdd emulation it will boot with or without BPB, if it users floppy emulation and you do not have a BPB, it will NOT boot.
Here are two examples, the one with BPB should work with any emulation, if placed on the disk right (assemble with fasm)
With BPB
Code:
Code:
;************************************
; By Dex
; Assemble with fasm
; c:\fasm USB1.asm USB1.bin
;
;************************************
org 0x7C00
use16
Boot:     jmp   start
     nop
;------------------------------------------;
;  Standard BIOS Parameter Block, "BPB".   ;
;------------------------------------------;
     bpbOEM     db  'MSDOS5.0'
     bpbSectSize     dw  512
     bpbClustSize     db  1
     bpbReservedSec  dw  1
     bpbFats     db  2
     bpbRootSize     dw  224
     bpbTotalSect     dw  2880
     bpbMedia     db  240
     bpbFatSize     dw  9
     bpbTrackSect     dw  18
     bpbHeads     dw  2
     bpbHiddenSect   dd  0
     bpbLargeSect     dd  0
     ;---------------------------------;
     ;  extended BPB for FAT12/FAT16   ;
     ;---------------------------------;
     bpbDriveNo     db  0
     bpbReserved     db  0
     bpbSignature     db  41           
     bpbID      dd  1
     bpbVolumeLabel  db  'BOOT FLOPPY'
     bpbFileSystem   db  'FAT12   '

;****************************
; Realmode startup code.
;****************************
start:
        xor   ax,ax
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   sp,0x7C00
         mov   si,Mesage1
        call  print
        jmp   $

;****************************
;  print.
;****************************
print:
        mov   ah,0Eh                       
again1:
   lodsb                             
        or   al,al                         
        jz   done1                         
   int  10h                           
        jmp  again1                       
done1:
   ret                               

Mesage1: db  'USB, with BPB works OK',0

;*************************************
; Make program 510 byte's + 0xaa55
;*************************************
times 510- ($-Boot)  db 0
dw 0xaa55
    


If I use this bootloader, or another bootloader with a BPB I had made for my floppy, the BIOS on the computer I'm testing on stops seeing the USB stick as a bootable device altogether.

I've never seen something like that before.
Post 21 Aug 2014, 19:04
View user's profile Send private message Reply with quote
Richy



Joined: 20 Aug 2014
Posts: 10
Richy 25 Aug 2014, 15:49
Richy wrote:
Dex4u wrote:
There is no magic to booting from usb drives, it very simple.
But you must understand one or two things or you will not get it to boot. that is unlike any other method of booting USB does check what its booting.
Eg: normaly the MBR or boot sector is just load into memory at a set address and jump to.
But in the case of USB boot, it checks for BPB, if it users hdd emulation it will boot with or without BPB, if it users floppy emulation and you do not have a BPB, it will NOT boot.
Here are two examples, the one with BPB should work with any emulation, if placed on the disk right (assemble with fasm)
With BPB
Code:
Code:
;************************************
; By Dex
; Assemble with fasm
; c:\fasm USB1.asm USB1.bin
;
;************************************
org 0x7C00
use16
Boot:     jmp   start
     nop
;------------------------------------------;
;  Standard BIOS Parameter Block, "BPB".   ;
;------------------------------------------;
     bpbOEM     db  'MSDOS5.0'
     bpbSectSize     dw  512
     bpbClustSize     db  1
     bpbReservedSec  dw  1
     bpbFats     db  2
     bpbRootSize     dw  224
     bpbTotalSect     dw  2880
     bpbMedia     db  240
     bpbFatSize     dw  9
     bpbTrackSect     dw  18
     bpbHeads     dw  2
     bpbHiddenSect   dd  0
     bpbLargeSect     dd  0
     ;---------------------------------;
     ;  extended BPB for FAT12/FAT16   ;
     ;---------------------------------;
     bpbDriveNo     db  0
     bpbReserved     db  0
     bpbSignature     db  41           
     bpbID      dd  1
     bpbVolumeLabel  db  'BOOT FLOPPY'
     bpbFileSystem   db  'FAT12   '

;****************************
; Realmode startup code.
;****************************
start:
        xor   ax,ax
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   sp,0x7C00
         mov   si,Mesage1
        call  print
        jmp   $

;****************************
;  print.
;****************************
print:
        mov   ah,0Eh                       
again1:
   lodsb                             
        or   al,al                         
        jz   done1                         
   int  10h                           
        jmp  again1                       
done1:
   ret                               

Mesage1: db  'USB, with BPB works OK',0

;*************************************
; Make program 510 byte's + 0xaa55
;*************************************
times 510- ($-Boot)  db 0
dw 0xaa55
    


If I use this bootloader, or another bootloader with a BPB I had made for my floppy, the BIOS on the computer I'm testing on stops seeing the USB stick as a bootable device altogether.

I've never seen something like that before.


@Dex4u:
Sorry for a few days without posting... I did figure out the bug, it's that without the BPB the USB drive is detected as an HDD by the BIOS, but with this BPB it's detected as a removable device. Probably because you've used a floppy disk's BPB there. Is there a reason you did that?
Post 25 Aug 2014, 15:49
View user's profile Send private message Reply with quote
Dex4u



Joined: 08 Feb 2005
Posts: 1601
Location: web
Dex4u 27 Aug 2014, 16:07
Richy wrote:
Richy wrote:
Dex4u wrote:
There is no magic to booting from usb drives, it very simple.
But you must understand one or two things or you will not get it to boot. that is unlike any other method of booting USB does check what its booting.
Eg: normaly the MBR or boot sector is just load into memory at a set address and jump to.
But in the case of USB boot, it checks for BPB, if it users hdd emulation it will boot with or without BPB, if it users floppy emulation and you do not have a BPB, it will NOT boot.
Here are two examples, the one with BPB should work with any emulation, if placed on the disk right (assemble with fasm)
With BPB
Code:
Code:
;************************************
; By Dex
; Assemble with fasm
; c:\fasm USB1.asm USB1.bin
;
;************************************
org 0x7C00
use16
Boot:     jmp   start
     nop
;------------------------------------------;
;  Standard BIOS Parameter Block, "BPB".   ;
;------------------------------------------;
     bpbOEM     db  'MSDOS5.0'
     bpbSectSize     dw  512
     bpbClustSize     db  1
     bpbReservedSec  dw  1
     bpbFats     db  2
     bpbRootSize     dw  224
     bpbTotalSect     dw  2880
     bpbMedia     db  240
     bpbFatSize     dw  9
     bpbTrackSect     dw  18
     bpbHeads     dw  2
     bpbHiddenSect   dd  0
     bpbLargeSect     dd  0
     ;---------------------------------;
     ;  extended BPB for FAT12/FAT16   ;
     ;---------------------------------;
     bpbDriveNo     db  0
     bpbReserved     db  0
     bpbSignature     db  41           
     bpbID      dd  1
     bpbVolumeLabel  db  'BOOT FLOPPY'
     bpbFileSystem   db  'FAT12   '

;****************************
; Realmode startup code.
;****************************
start:
        xor   ax,ax
        mov   ds,ax
        mov   es,ax
        mov   ss,ax
        mov   sp,0x7C00
         mov   si,Mesage1
        call  print
        jmp   $

;****************************
;  print.
;****************************
print:
        mov   ah,0Eh                       
again1:
   lodsb                             
        or   al,al                         
        jz   done1                         
   int  10h                           
        jmp  again1                       
done1:
   ret                               

Mesage1: db  'USB, with BPB works OK',0

;*************************************
; Make program 510 byte's + 0xaa55
;*************************************
times 510- ($-Boot)  db 0
dw 0xaa55
    


If I use this bootloader, or another bootloader with a BPB I had made for my floppy, the BIOS on the computer I'm testing on stops seeing the USB stick as a bootable device altogether.

I've never seen something like that before.


@Dex4u:
Sorry for a few days without posting... I did figure out the bug, it's that without the BPB the USB drive is detected as an HDD by the BIOS, but with this BPB it's detected as a removable device. Probably because you've used a floppy disk's BPB there. Is there a reason you did that?

I have sent you a PM, hope that helps.
Post 27 Aug 2014, 16:07
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 can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.