Running a Bootloader from USB

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
MustLearn
Posts: 14
Joined: Wed Feb 04, 2015 4:08 pm

Running a Bootloader from USB

Post by MustLearn »

Hi!
I made a simple bootloader that i wanted to boot from a pen drive. Everything is running perfectly and the message is being displayed fine when running it from Virtual Box but the problem starts when i try to boot it form the pen drive even after copying it into Sector 0 using -

Code: Select all

dd if=Simple.asm of=/dev/sdc bs=512 count=1
Whenever i boot it from the pen drive, there is a black screen with a flickering cursor on the second line, 2-3 pixels from the left.
I would really appreciate some help to figure out what exactly is going wrong :)

This is the simple asm code i'm using(Pasting it here in case anyone needs to see it)-

Code: Select all

BITS 16  
ORG 0x7C00  
jmp main

;Variables
LoadString db "Bootloader Starting",0 

Print:
lodsb
cmp al,0
je Done
mov ah, 0eh
int 10h
jmp Print

Done:
ret

main:
MOV SI, LoadString    
CALL Print
jmp $

TIMES 510 - ($ - $$) db 0 
DW 0xAA55      
I even checked if the .bin file was being copied correctly using the hex editor, like in the image-
Image
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: Running a Bootloader from USB

Post by Roman »

You didn't set up the segments.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
MustLearn
Posts: 14
Joined: Wed Feb 04, 2015 4:08 pm

Re: Running a Bootloader from USB

Post by MustLearn »

Thanks for the reply, i'll try that :)
But one thing though, why would it run on Virtual Box just fine, if setting up the segments was the issue?
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: Running a Bootloader from USB

Post by Techel »

It isn't defined what's in the registers (except dl, containing the bootdrive). In an emulator they are mostly just 0 or already set up, on real hardware it might be different.
MustLearn
Posts: 14
Joined: Wed Feb 04, 2015 4:08 pm

Re: Running a Bootloader from USB

Post by MustLearn »

You didn't set up the segments.
Thank you!
Adding segments solved the problem!! (Resulted in newer ones though :D)
It isn't defined what's in the registers (except dl, containing the bootdrive). In an emulator they are mostly just 0 or already set up, on real hardware it might be different.
Ohhhhhh!! I became fixated on there being a problem with my copying cause it ran on Virtual Box -.-
User avatar
Muazzam
Member
Member
Posts: 543
Joined: Mon Jun 16, 2014 5:59 am
Location: Shahpur, Layyah, Pakistan

Re: Running a Bootloader from USB

Post by Muazzam »

MustLearn wrote:

Code: Select all

dd if=Simple.asm of=/dev/sdc bs=512 count=1
How problem is solved if you are copying .asm file instead of binary file.
MustLearn
Posts: 14
Joined: Wed Feb 04, 2015 4:08 pm

Re: Running a Bootloader from USB

Post by MustLearn »

How problem is solved if you are copying .asm file instead of binary file.
Oh yeah sorry about that
I typed that here instead of copy pasting it from the command terminal and wrote .asm instead of .bin
That was completely my bad :(
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Running a Bootloader from USB

Post by Combuster »

Code: Select all

LoadString db "Bootloader Starting",0 

Code: Select all

69 6E 67 2E 2E 2E   ing...
That assembly doesn't correspond to your hexdump.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
MustLearn
Posts: 14
Joined: Wed Feb 04, 2015 4:08 pm

Re: Running a Bootloader from USB

Post by MustLearn »

I like edited the string, after i took the screenshot :)
But just the string and nothing else, that couldn't be the problem though :O
MustLearn
Posts: 14
Joined: Wed Feb 04, 2015 4:08 pm

Re: Running a Bootloader from USB

Post by MustLearn »

Okay soo after adding the segment registers, it still didn't work on my desktop.
I tried running it on my sisters laptop and it ran perfectly :|
It still won't run on my desktop but runs perfectly fine on my sister's laptop :|. Can anyone tell me why that is?
Techel
Member
Member
Posts: 215
Joined: Fri Jan 30, 2015 4:57 pm
Location: Germany
Contact:

Re: Running a Bootloader from USB

Post by Techel »

Did you set up SS and SP correctly?

Code: Select all

xor ax, ax ;fast way to set ax to 0
mov ss, ax
mov sp, 0x7C00 ;stack points to ss:sp -> 0000:7C00 (below you bootloader, since the stack grows down)
johnsa
Member
Member
Posts: 296
Joined: Mon Oct 15, 2007 3:04 pm

Re: Running a Bootloader from USB

Post by johnsa »

Booting from USB has a few other caveats to consider..

There is no "native" way to boot from a USB device, so the BIOS (in order to allow this) does one of two things usually:
1) Pretend the USB is a FDD (in which case you'll start with DL=00h) and you can use normal int13h functions to read further sectors from the emulated floppy.
2) Pretend the USB is an HDD (in which case you'll start with DL=80h+) at which point you may be able to use the extended int 13h functions for reading with lba or the standard chs ones.

Further more i've noticed that on some machines the BIOS actually verifies certain things about the boot sector:
1) On one machine the BIOS doesn't check for the 0xaa55 signature, another one does and won't boot without it.
2) On one machine the USB is effectively USB-FDD and all works as planned.
3) On another it works as USB-HDD and works as planned.
4) On yet another machine it's USB-HDD but my original loader wouldn't work because THIS BIOS tries to verify the partition table (obviously expecting an MBR being an HDD)
5) On newer machines the MBR has been replaced with a GPT and I suspect that this machine that gives me headaches is in fact trying to verify the structure of the GPT partition.. although I find it strange that the BIOS would make an assumption
like this as it effectively rules out using an OS on the machine which doesn't yet make use of GPT for partitions....

Basically.. the bottom line is getting something which boots reliably on a lot/most machines is challenging. There are also many little catches (most of which are probably obsolete these days) to deal with various bios bugs and incompatabilities like resetting the FDC parameter table, ensuring DX is saved across an int13h call for sector reads.. another one as well to consider when setting up the segments initially is that (and i'm not sure if this still applies today but doesn't hurt)
is that some BIOSes may load you to 0000:7c00 while another might use 07c0:0000 (seg:ofs).
So it's a good idea to make sure you standardise that on boot to conform with your ORG.
MustLearn
Posts: 14
Joined: Wed Feb 04, 2015 4:08 pm

Re: Running a Bootloader from USB

Post by MustLearn »

Did you set up SS and SP correctly?
I think so, this is what i'm using now and sis it works on the laptop, im assuming i'm doing it correctly?-

Code: Select all

BITS 16

start:
mov ax, 07C0h       ; Set up 4K stack space after this bootloader
add ax, 288     ; (4096 + 512) / 16 bytes per paragraph
mov ss, ax
mov sp, 4096

mov ax, 07C0h       ; Set data segment to where we're loaded
mov ds, ax

mov si, msg
call move

jmp $   

msg db 'Whatever!', 0

move:
mov ah, 0Eh

.print:
lodsb
cmp al,0
je .Done
int 10h
jmp .print

.Done:
ret

times 510-($-$$) db 0   
dw 0xAA55       
Last edited by MustLearn on Sat Feb 07, 2015 8:45 am, edited 1 time in total.
MustLearn
Posts: 14
Joined: Wed Feb 04, 2015 4:08 pm

Re: Running a Bootloader from USB

Post by MustLearn »

Further more i've noticed that on some machines the BIOS actually verifies certain things about the boot sector:
1) On one machine the BIOS doesn't check for the 0xaa55 signature, another one does and won't boot without it.
2) On one machine the USB is effectively USB-FDD and all works as planned.
3) On another it works as USB-HDD and works as planned.
4) On yet another machine it's USB-HDD but my original loader wouldn't work because THIS BIOS tries to verify the partition table (obviously expecting an MBR being an HDD)
5) On newer machines the MBR has been replaced with a GPT and I suspect that this machine that gives me headaches is in fact trying to verify the structure of the GPT partition.. although I find it strange that the BIOS would make an assumption
like this as it effectively rules out using an OS on the machine which doesn't yet make use of GPT for partitions....
How can i tell which machine does what?
I thought all machines checked for the aa55 signature :O
johnsa
Member
Member
Posts: 296
Joined: Mon Oct 15, 2007 3:04 pm

Re: Running a Bootloader from USB

Post by johnsa »

Here is my minimal example (using fasm):

Code: Select all


    USE16
    offset equ

    org 0h  ; I prefer to use 07c0:0000 instead of 0000:7c000 because i can relocate the code to a different segment address without affecting offsets in the code.

start:
    jmp short begin

; BPB ... some bioses will NOT boot a USB-FDD or even real FDD without this block here.. I also cheat a bit and re-use some of the entries as variables..
	nop
	OEM                 DB "VXOS    "
	m_sectorsize        DW 512      
	Sectors_per_cluster DB 1      
	Reserved_sectors    DW 1      
	Number_of_FATs      DB 2      
	Root_entries        DW 224      
	Total_sector_count  DW 2880      
	Media_descriptor    DB 0f0h
	Sectors_per_FAT     DW 9
	m_spt			    DW 18
	Heads               DW 2
	m_cylinders         DD 80								; was Hidden_Sectors 1 
	m_sectors           DD 18								; was Large_Sectors 2880
	bsDriveNumber 	    DB 0
	Current_Head        DB 0
	bsExtBootSignature 	DB 29h
	m_heads			    DD 2								; was VolumeID.
	bsVolumeLabel 	    DB "VXOS       "
	bsFileSystem 	    DB "VXL12   "

begin:
	db 0eah
	dw offset cs_correction, 07c0h							; Hard-coded long jump to force cs:ofs correction.

	;--------------------------------------------------------------------------------
	; Configure Stack and Segment Registers.
	;--------------------------------------------------------------------------------
cs_correction:
	cld														; Ensure the direction flag is clear.
	cli														; Switch off interrupts while we setup the stack.
	xor ax,ax												; Configure segment registers and stack.
	mov ss,ax
	mov es,ax
	mov sp,(7c00h-16)										; Set stack just below boot loader (padding to be safe).
	push cs
	pop ds
	mov [m_driveNo],dl	;store boot drive no.

        jmp short $

db 509-($-start) DUP (0)								; Padding to ensure that boot-loader is exactly 512 bytes for fdd/hdd/emulated boot modes.
	
	m_driveNo   db ?										; BIOS Boot Drive Number [00h=first floppy / 80h=first fixed disk]. We store it here so it's at a fixed location to be read later.
	
	bios_sig    db 055h,0aah								; BIOS 512byte sector boot signature.




Post Reply