Trouble chainloading 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.
zehawk
Member
Member
Posts: 35
Joined: Thu Jun 11, 2015 7:26 am
Libera.chat IRC: zehawk

Re: Trouble chainloading from USB?

Post by zehawk »

Octocontrabass wrote: In practice, you can always use 255 heads and 63 sectors to calculate the CHS values in your USB flash drive's partition table. (You still need to use INT 0x13 AH=0x08 if you plan on reading the disk using CHS addressing.)
Kinda figured, because the table in a CHS MBR has a head size of 2^8, sector size of 2^6, and cyllinder size of 2^10. And I'd rather just address using the other addressing scheme, the one that works for hard drives only. A lot easier and less cumbersome. I just wanted a partition table to make the BIOS happy, and this will do! But this is all making tons of sense now!

Octocontrabass wrote: MBR is also standardized and also uses LBA. My own bootloaders completely ignore the CHS values; they're only in the partition table for the BIOS's benefit.
Yeah, MBR is definitely standardized. I saw the main wikipedia article about it, and have been studying it best I could. Hence, the one they marked as 'standard' used CHS keys instead of LBA. Haven't found one that uses LBA keys to reference though.
Octocontrabass wrote: It checks for a signature, exactly one partition marked active, and start and end values that don't overlap. It only checks for USB flash drives and the like; it does not check hard disks or floppy disks.
It makes sense why it wouldn't check Hard disks or floppy, because those aren't being emulated. I was actually thinking that the BIOS checked for an active (80h) flag. Wanted to confirm first. And glad I did!

Octocontrabass wrote: You can't start a partition at CHS (0,0,1). The previous partition table you posted (and have since deleted) booted in floppy disk mode on your test machine because of that mistake.
That makes sense, because as I've just found out, 0,0,1 is equal to LBA 0, which is the MBR. Doesn't make sense to have a partition start at the bootsector. Will change to 0,0,2.(Or whatever value is valid after the GTP is implemented!)

This makes a lot more sense now, and all the answers posted have been very helpful. Will try the revised code later tomorrow, see if it works on my other test machine. Thank you guys for your help! I really appreciate it!
zehawk
Member
Member
Posts: 35
Joined: Thu Jun 11, 2015 7:26 am
Libera.chat IRC: zehawk

Re: Trouble chainloading from USB?

Post by zehawk »

Alright, I did what everyone recommended. Did not work. There is no error reading the from the USB, but the USB does not correctly load the data into 0x0000:7E00. Any ideas what is going on here?

Put into sector 0:

Code: Select all

BITS 16

org 0x7C00

start:
        cli
        mov ax, 0
        mov ds, ax
        mov es, ax
        mov fs, ax
        mov gs, ax

        mov ss, ax 		;Puts 0 into the segment pointer, we are using real memory.
        mov sp, 0x7C00 		;Moves 7C00 into the stack pointer, so that all data <7C00 is stack.
        sti
        
        ;moves the drive number into memory
        mov [DRIVE_NUMBER], dl 
          
    .Read:
        xor bx, bx
        mov ah, 0x0E
        mov al, 'R'
        int 10h
        
        mov ah, 0x42
        mov dl, [DRIVE_NUMBER]
        mov si, DISK_ADDRESS_PACKET
    	int 0x13					; call BIOS - Read the sector
    	jc .Read					; Error, so try again
         
       
    	jmp 0x7E00				        ; jump to execute the sector!
    
    DRIVE_NUMBER db 0
    
;Makes sure the structure is a 4 byte doundary.  0C0h is for sure.
times 0C0h-($-$$) db 0
    DISK_ADDRESS_PACKET:db 0x10  ;Size of disk packet, always 16
                        db 0x00  ;Reserved, always 0.
                        dw 0x04  ;Number of sectors.
                        dw 0x7E00;Location of files to be transfered. 
                        dw 0x0000
                        dd 0x0001;Selector to be transfered from.  We choose 1, because that's where it is loaded to.
                        dd 0x0000

times 1B4h-($-$$) db 0
	;Sets up the drive's unique identification!
	db 'P'
;--MBR PARTITIONING!----------------------------------------------------------------------------
times 1BEh-($-$$) db 0
	;Entry one!
	db 0x80 	;active
	db 0x00 	;the starting head
	db 0x02 	;the starting sector
	db 0x00 	;the statring cyllinder 
	db 0x7F 	;the partition type.
	db 0xFF 	;the ending head
	db 0xFE 	;the ending sector
	db 0xFF 	;the ending cyllinder 
	dd 0x1 		;relative sector.
	dd 0xF6CA3C 	;total sectors in partition.
	;Entry two!
	db 0x00 	;active
	db 0x00 	;the starting head
	db 0x00 	;the starting sector
	db 0x00 	;the statring cyllinder 
	db 0x00		;the partition type.
	db 0x00 	;the ending head
	db 0x00 	;the ending sector
	db 0x00 	;the ending cyllinder 
	dd 0x00 	;relative sector.
	;Entry three!
	db 0x00 	;active
	db 0x00 	;the starting head
	db 0x00 	;the starting sector
	db 0x00 	;the statring cyllinder 
	db 0x00		;the partition type.
	db 0x00 	;the ending head
	db 0x00 	;the ending sector
	db 0x00 	;the ending cyllinder 
	dd 0x00 	;relative sector.
	;Entry four!
	db 0x00 	;active
	db 0x00 	;the starting head
	db 0x00 	;the starting sector
	db 0x00 	;the statring cyllinder 
	db 0x00		;the partition type.
	db 0x00 	;the ending head
	db 0x00 	;the ending sector
	db 0x00 	;the ending cyllinder 
	dd 0x00 	;relative sector.
times 510-($-$$) db 0   ; Pad remainder of boot sector with 0s
dw 0xAA55      ; The standard PC boot signature
And code put into sector one:

Code: Select all

BITS 16

org 7e00h

start:
    xor bx, bx
    mov ah, 0x0E
    mov al, 'W'
    int 10h
    mov si, VERSION
    call print_string
    
    call new_line
    
    mov si, MESSAGE
    call print_string
    
    call new_line
    ;Will now allow keyboard input.
    call keyb_in
    
    
    ;Prints the test string for now.
print_string:

    .nextChar:

        mov ah, 0x0E
        mov al, [si]
        cmp al, 0x0
        je .end

        int 10h
        add si, 1
        jmp .nextChar
    .end:
        ret


    MESSAGE db "Hello world!", 0
    VERSION db "Loading version: 0.0.0", 0
    
new_line:
        mov ah, 0x0E
        mov al, 0x0D
        int 10h
        
        mov ah, 0x0E
        mov al, 0x0A
        int 10h
        
        ret

keyb_in:
        mov ah, 00h
        int 16h
        
        mov [KEYBOARD_INPUT], al
        mov al, [KEYBOARD_INPUT]
        
        cmp al, 0x00
        je keyb_in
        
        cmp al, 0x08
        je .back_key
        
        cmp al, 0x1C
        je .enter_key
        
        mov ah, 0Eh
        int 10h
        jmp keyb_in  ;infinite loop!
        
    .back_key:
        mov ah, 0Eh
        mov al, 0x08
        int 10h
        
        mov ah, 0Eh
        mov al, ' '
        int 10h
        
        mov ah, 0Eh
        mov al, 0x08
        int 10h
        jmp keyb_in 
    
    .enter_key:
        call new_line
        jmp keyb_in

    KEYBOARD_INPUT: db 0
    
times 2048-($-$$) db 0   ; Pad remainder of boot sector with 0s
User avatar
TightCoderEx
Member
Member
Posts: 90
Joined: Sun Jan 13, 2013 6:24 pm
Location: Grande Prairie AB

Re: Trouble chainloading from USB?

Post by TightCoderEx »

Function 42 does not work on floppy devices and USB, at least on the systems I've tried DL = 0

I tried your code without modification but changed DL = 0x80 and it works.
Octocontrabass
Member
Member
Posts: 5588
Joined: Mon Mar 25, 2013 7:01 pm

Re: Trouble chainloading from USB?

Post by Octocontrabass »

zehawk wrote:

Code: Select all

	db 0x80 	;active
	db 0x00 	;the starting head
	db 0x02 	;the starting sector
	db 0x00 	;the statring cyllinder 
	db 0x7F 	;the partition type.
	db 0xFF 	;the ending head
	db 0xFE 	;the ending sector
	db 0xFF 	;the ending cyllinder 
	dd 0x1 		;relative sector.
	dd 0xF6CA3C 	;total sectors in partition.
Your BIOS may also be rejecting the end CHS value. If I'm not mistaken, the correct translation would be (1006, 194, 17) or 0xC2 0xD1 0xEE. However, I've noticed that Windows automatically rounds down to the nearest whole cylinder. If your drive has fewer than 16,177,455 sectors, Windows will use (1005, 254, 63) or 0xFE 0xFF 0xED.

You might want to insert a debugging function that prints the value of DL to the screen. That way, you can tell if you've gotten hard disk emulation or not.
zehawk
Member
Member
Posts: 35
Joined: Thu Jun 11, 2015 7:26 am
Libera.chat IRC: zehawk

Re: Trouble chainloading from USB?

Post by zehawk »

I tried both of your guys' suggestions. I printed out the debug for dl, and got, surprisingly, the value 0x80. I also tried the suggestion to hard code '0x80' into the 42 function to no avail either.

This is getting really odd. I'm not entirely sure what else it could be. Unless my last value is still wrong. But if it was, then dl wouldn't be set to the hard drive mode, right?

Code: Select all

times 1B4h-($-$$) db 0
	;Sets up the drive's unique identification!
	db 'P'
;--MBR PARTITIONING!----------------------------------------------------------------------------
times 1BEh-($-$$) db 0
	;Entry one!
	db 0x80 	;active
	db 0x00 	;the starting head
	db 0x02 	;the starting sector
	db 0x00 	;the statring cyllinder 
	db 0x7F 	;the partition type.
	db 0xFF 	;the ending head
	db 0xFE 	;the ending sector
	db 0xFF 	;the ending cyllinder 
	dd 0x1 		;relative sector.
	dd 0xc2D1EE 	;total sectors in partition.
	;Entry two!
	db 0x00 	;active
	db 0x00 	;the starting head
	db 0x00 	;the starting sector
	db 0x00 	;the statring cyllinder 
	db 0x00		;the partition type.
	db 0x00 	;the ending head
	db 0x00 	;the ending sector
	db 0x00 	;the ending cyllinder 
	dd 0x00 	;relative sector.
	;Entry three!
	db 0x00 	;active
	db 0x00 	;the starting head
	db 0x00 	;the starting sector
	db 0x00 	;the statring cyllinder 
	db 0x00		;the partition type.
	db 0x00 	;the ending head
	db 0x00 	;the ending sector
	db 0x00 	;the ending cyllinder 
	dd 0x00 	;relative sector.
	;Entry four!
	db 0x00 	;active
	db 0x00 	;the starting head
	db 0x00 	;the starting sector
	db 0x00 	;the statring cyllinder 
	db 0x00		;the partition type.
	db 0x00 	;the ending head
	db 0x00 	;the ending sector
	db 0x00 	;the ending cyllinder 
	dd 0x00 	;relative sector.
times 510-($-$$) db 0   ; Pad remainder of boot sector with 0s
dw 0xAA55      ; The standard PC boot signature
Also worth noting, and I guess I forgot to mention, this does not work on any testbed I've tried it on. My home pc and work pc do not get past the initial bootload. I might just have to stay using AH=08, which at least worked on my home PC. Also got a 128 gigabyte USB the other day, which given this code, wasn't even considered bootable at all. Thinking that could be because it has 4096 byte sectors though.
Octocontrabass
Member
Member
Posts: 5588
Joined: Mon Mar 25, 2013 7:01 pm

Re: Trouble chainloading from USB?

Post by Octocontrabass »

zehawk wrote:Thinking that could be because it has 4096 byte sectors though.
The BIOS can't boot 4K-sectored media.

I just noticed something very important that I must have overlooked earlier:
zehawk wrote:There is no error reading the from the USB,
So, it prints the letter "R" once and then does nothing? That makes it sound like the read is succeeding, but the sector you're reading doesn't contain the code you want. How are you putting your code on the disk?
zehawk
Member
Member
Posts: 35
Joined: Thu Jun 11, 2015 7:26 am
Libera.chat IRC: zehawk

Re: Trouble chainloading from USB?

Post by zehawk »

Yep, only prints R once. And I'm using HxD to post the code directly into the sector after this one. (I use HxD to copy the binary of the bootloader into sector 0, and the binary for the chainloaded code into sectors 1-4.)

It's an interesting problem. Not sure what's going on. I did verify that it's being read in HardDisk mode, the read is successful, and the sectors I want to read to and from are all correct. This is all using the USB that used to work with AH=08.

Edit: Worth noting that my BIOS has UEFI support, and could in theory boot from 4k sectored media. But that's a topic all in itself. Don't even know why I posted about the other 128 GB USB. Jut ignore that xD
Octocontrabass
Member
Member
Posts: 5588
Joined: Mon Mar 25, 2013 7:01 pm

Re: Trouble chainloading from USB?

Post by Octocontrabass »

The only significant difference I see between your code and mine is my bootloader reads only one sector at a time. But if that were the problem, I'd expect you to receive a read error...

I have a pretty robust MBR and FAT12/FAT16 bootloader that I can quickly hack into LBA-only mode, if you're interested in trying them. If they fail, then you'll know the issue is with the BIOS and not your code...
zehawk wrote:Worth noting that my BIOS has UEFI support, and could in theory boot from 4k sectored media.
It probably can, but not in Legacy mode, so you still can't use that 128GB drive. :lol:
zehawk
Member
Member
Posts: 35
Joined: Thu Jun 11, 2015 7:26 am
Libera.chat IRC: zehawk

Re: Trouble chainloading from USB?

Post by zehawk »

Octocontrabass wrote:The only significant difference I see between your code and mine is my bootloader reads only one sector at a time. But if that were the problem, I'd expect you to receive a read error...

I have a pretty robust MBR and FAT12/FAT16 bootloader that I can quickly hack into LBA-only mode, if you're interested in trying them. If they fail, then you'll know the issue is with the BIOS and not your code...
I'd try them, happily. Especially if it means we can help pinpoint the issue I'm having. My BIOS has quite a few bugs, even before going into BIOS interrupts. For instance, it asks the user to press F2 or DEL to go into the BIOS menu, but only DEL works. And reordering the Boot sequence isn't considered something that can be 'saved' for who knows why. Whoever worked on the BIOS didn't make sure that even basic functionality worked properly. So if there are issues with this particular function on my machine, I would not be surprised.

I don't really care too much about how accurate the values in the MBR are. I don't plan on using them until I have a solid file driver. Furthermore, I plan on implementing a GTP anyways. I just want the BIOS to be happy with the values I feed into the MBR so it can boot into Hard Drive mode. (Which, it does. Even when the last value was whatever junk was in there before.)

But yeah, send the bootloader and I'll give it a shot!
Octocontrabass wrote:
zehawk wrote:Worth noting that my BIOS has UEFI support, and could in theory boot from 4k sectored media.
It probably can, but not in Legacy mode, so you still can't use that 128GB drive. :lol:
Haha well, for now, I won't even mess with it. If my current, 8 GB standard USB has issues loading in legacy mode, then I don't want to get into further complications with UEFI and GTP on the 128GB drive.. That comes after we get this one working xD
Last edited by zehawk on Thu Jun 18, 2015 9:29 am, edited 1 time in total.
zehawk
Member
Member
Posts: 35
Joined: Thu Jun 11, 2015 7:26 am
Libera.chat IRC: zehawk

Re: Trouble chainloading from USB?

Post by zehawk »

TightCoderEx wrote:Function 42 does not work on floppy devices and USB, at least on the systems I've tried DL = 0

I tried your code without modification but changed DL = 0x80 and it works.

That's because DL = 0 means it is emulating Floppy Drive Mode, and Function 42 is specific to Hard drives and hard drive emulation. DL = 0x80 just so happens to be the code for the first hard drive.(Or booted hard drive if passed from the BIOS). Regardless, even though my BIOS sets DL to 0x80 as the drive being booted from, it did not work.
Octocontrabass
Member
Member
Posts: 5588
Joined: Mon Mar 25, 2013 7:01 pm

Re: Trouble chainloading from USB?

Post by Octocontrabass »

zehawk wrote:I'd try them, happily.
I've sent you a PM. Let me know how it goes.
Post Reply