Page 1 of 2

INT 13h Returns 0x07 [SOLVED]

Posted: Tue Nov 19, 2013 10:35 pm
by tlf30
Hello,
I am running into a new problem for me. My new boot loader is using a simple int 13h to read in the next couple of sectors for my OS. I am trying to boot off of a thumb drive, I am using int 13h to grab the boot drive number (which is returning the correct value) and then calling a int 13h reset before calling the int 13h read functions. My only problem is that the read functions are returning 0x07: "Drive parameter activity failed."

I am wondering if anyone has run into this problem and/or could tell me what this means.

Thanks,
Trevor

Re: INT 13h Returns 0x07

Posted: Wed Nov 20, 2013 12:50 am
by mrstobbe
Just curious here for my own knowledge (aka, can't help)... is this a "new" machine you've tried to boot from in this manner (untried box+same code+same boot method)?

Re: INT 13h Returns 0x07

Posted: Wed Nov 20, 2013 3:05 am
by M2004
You should show your source code. Without seeing it is impossible to say what is
wrong.

Regards
M2004

Re: INT 13h Returns 0x07

Posted: Wed Nov 20, 2013 3:42 am
by nerdguy
Hello,
I am running into a new problem for me. My new boot loader is using a simple int 13h to read in the next couple of sectors for my OS. I am trying to boot off of a thumb drive, I am using int 13h to grab the boot drive number (which is returning the correct value) and then calling a int 13h reset before calling the int 13h read functions. My only problem is that the read functions are returning 0x07: "Drive parameter activity failed."
Just wanted to ask one thing, does it work on emulators? QEMU? Bochs? VBOX?
Did you try using a debugger? Maybe the problem would occur during a reset.
try printing some strings like : "Reset Success","Drive Parameters Received" after a specific operation to see where it's going wrong.

Re: INT 13h Returns 0x07

Posted: Wed Nov 20, 2013 10:09 am
by tlf30
It is new code that I have tried to test on 4 different boxes. I have not tried it in an VM nor debugger at this point. I have confirmed that the loading of the disk works correctly but I did not check the reset.

Re: INT 13h Returns 0x07

Posted: Wed Nov 20, 2013 10:31 am
by tlf30

Code: Select all


;Set info for NASM
BITS 16 ;Code bitness
ORG 0x00 ;Start location of instructions in file 
;(Optional, the default is zero but this is included for clarity)
%define segment_address 0x07C0
%define stage1_address 0x5000
%define stage1_segment 0x0500
;
;Debugging switches, 0 = NO_DEBUG & 1 = DEBUG
%assign DEBUG_CLEAR_LOOP_PRINT_ADDRESS 0 ;Print the address that the ram clearing loop is at
%assign DEBUG_JERRY_RIG_JUMP 0 ;Force use of far return to accomplish jump into os loader
%assign DEBUG_DISABLE_JUMP 0 ;Disable jump into os loader
%assign DEBUG_HALT_JUMP 1 ;If jump is disabled and jerry rig jump is disabled then this will act as if it is on
%assign DEBUG_ENABLE_HANG_OVER_HALT 0 ;If hang is jumped to and this is enabled, then halt will be jumped to
%assign DEBUG_HALT_STRING 0 ;Print a string if halt is jumped to
%assign DEBUG_HANG_STRING 0 ;Print a string if hang is jumped to
;

;Boot Stage 0
main:
	jmp 0x07C0:0x0001 ;Set CS to correct location
	;Dissable interupts for stack operations
	cli

	;Setup stacks for kernel
	mov ax, segment_address ;Start address of stacks
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax

	;Setup ss and sp registers and stacks
	mov ax, 0x0600 ;0x6000
	mov ss, ax
	xor ax, ax
	mov sp, ax

	;Enable interupts, stack operations done
	sti
	
	pusha ;Store registers while we prep the video 
	
	;Setup video mode
	xor bx, bx
	xor cx, cx
	xor dx, dx
	mov ah, 0x00 ;Int 10h set video mode
	mov al, 0x12 ;640x480, 16 colors, VGA
	int 10h
		
	popa ;Restore registers, RAM is prepared
	
	.boot_id_store0:
		;Store boot device ID in RAM at 0x1002
		mov ax, 0x0100
		mov es, ax
		mov ah, 0x01
		int 13h ;ah already has 0x01
		mov byte [es:0x0002], al
		mov ax, segment_address
		mov es, ax
	
	;Continue onto read_disk
	
read_disk:
	.prep:
		;Print string
		mov si, starting_stage1_s
		call update_status
		
		mov byte [errors_b], 0x07 ;Counter for errors, 7 trys
	
	.values:
		mov ax, 0x0100
		mov es, ax
		mov dl, [es:0x0002] ;Set drive number (boot device ID stored at 0x1002)
		mov ax, segment_address
		mov es, ax
		;Reset the disk and load it with disk geom' ... dl has disk BIOS ID already loaded above
		xor ax, ax ;Int 13 disk reset
		int 13h ;Reset disk
		;
		xor bx, bx ;0x0000, Location to write sectors at in relation to es
		mov ax, 0x0201 ;Int 13h read sector function, al; Number of sectors to read,
				 ;fills RAM allocated for Boot Stage 1 (3,584 bytes, 7 sectors) #### HAS BEEN CHANGED TO 01 FOR DEBUGGING!
		mov cx, 0x0002 ;Set cylinder + Set sector to start reading at... NOTE: Cylinders start at 0, Sectors start at 1 
		mov dh, 0x00 ;Set head
		;
		push bx
		mov bl, 0x02 ;Bios color green
		call print_dx ;#########################DEBUGGING OUTPUT
		pop bx
		;
		;Setup es for data transfer, segment for writing os loader
		mov ax, stage1_segment
		mov es, ax 
		
	.loop:
		;Read code
		int 13h ;Perform read
		jnc .done ;If read worked
		
		cmp byte [ds:errors_b], 0x00
		je .error ;Check if counter is zero
		;If not...
		dec byte [ds:errors_b]
		;Print errors
		pusha
		mov bl, 0x02 ;Bios color green
		mov dl, byte [ds:errors_b]
		call print_dx
		popa
		jmp .values ;Try to read again
		
	.error:
		xor ax,ax ;Int 13 disk reset
		int 13h ;Reset disk
		
		;Restore es to es address
		mov ax, segment_address
		mov es, ax
		
		mov si, disk_error_s
		mov bl, 0x04 ;Bios color red
		call update_status
		
		pusha
		mov dx,ax
		mov cl, 0x02
		call print_dx.calc
		
		jmp hang ;Stall system, cannot boot
		
	.done:
		
		;Restore es to ds address
		mov ax, segment_address
		mov es, ax
		
		;Calculate and store number of read failures
		pop cx ;Get counter out of stack
		mov ax, 0x0007 ;Store value to operate against
		sub ax, cx ;Get fails
		mov cx, 0x0100
		mov es, cx
		mov byte [es:0x0003], al ;Store number of read failures in 0x1003
		mov cx, segment_address
		mov es, cx
		
		;Continue onto start_boot

Re: INT 13h Returns 0x07

Posted: Wed Nov 20, 2013 10:51 am
by Antti

Code: Select all

   jmp 0x07C0:0x0001 ;Set CS to correct location
   ;Dissable interupts for stack operations
   cli
Interrupts are never disabled but you are running these unnecessary instructions:

Code: Select all

        add [bx+si],ax
        rol byte [bx],byte 0xfa
Be careful with the jump. This is what you would want to do:

Code: Select all

        jmp 0x07C0:0x0005
        cli
However, this was quite ugly. I recommend this:

Code: Select all

        jmp 0x07C0:.cs
.cs:    cli

Re: INT 13h Returns 0x07

Posted: Wed Nov 20, 2013 11:24 am
by tlf30
Thanks, I never caught the jump problem.
Still having problems reading though...

Re: INT 13h Returns 0x07

Posted: Wed Nov 20, 2013 2:04 pm
by M2004
You use jmp instruction before setting the stack.


Regards
M2004

Re: INT 13h Returns 0x07

Posted: Wed Nov 20, 2013 8:23 pm
by Minoto
tlf30 wrote:

Code: Select all

.boot_id_store0:
		;Store boot device ID in RAM at 0x1002
		mov ax, 0x0100
		mov es, ax
		mov ah, 0x01
		int 13h ;ah already has 0x01
		mov byte [es:0x0002], al
Int 13h with ah = 01 returns the status of the last disk operation, not the boot device ID. I would guess that it's returning 0, since the previous disk operation would have been the read of the boot sector, and your code wouldn't be running if that failed. In any case -- if your thumb drive shows up as the first floppy drive (device ID 00), then this could be returning the correct number, but purely by accident. The BIOS should have left the boot device ID in dl after loading and jumping to your code -- just save it before doing anything that trashes that register.

Re: INT 13h Returns 0x07

Posted: Wed Nov 20, 2013 9:12 pm
by tlf30
It is returning the correct value, I have got 0x00 and 0x80 from it... For some reason I have two computers that are fairly new that do not load the boot id into dl.

EDIT: I see now that is was a complete coincidence and that the int 13h ah=0x01 will not work, is there a way to get it??

Re: INT 13h Returns 0x07

Posted: Wed Nov 20, 2013 10:18 pm
by Minoto
tlf30 wrote:For some reason I have two computers that are fairly new that do not load the boot id into dl.

EDIT: I see now that is was a complete coincidence and that the int 13h ah=0x01 will not work, is there a way to get it??
I have yet to run across a machine that doesn't, so I truly don't know. I'd look at those two a little more closely, though...maybe try writing a boot sector that does nothing but print dl to the screen and then hang, to make sure there isn't something else going on.

Re: INT 13h Returns 0x07

Posted: Thu Nov 21, 2013 12:36 am
by mrstobbe
Minoto wrote:Int 13h with ah = 01 returns the status of the last disk operation, not the boot device ID
tlf30 wrote:It is returning the correct value, I have got 0x00 and 0x80 from it... For some reason I have two computers that are fairly new that do not load the boot id into dl.
Minoto is correct. Regardless of what you may-or-may-not be getting from that call you're absolutely using it incorrectly. Do not use it that way. Rely on what the BIOS gave you during the boot process (in DL if I can remember correctly off the top of my head) and don't deviate from that unless you have a really... exceptionally... good reason to and you can back up that reason with specific code.

Re: INT 13h Returns 0x07

Posted: Fri Nov 22, 2013 10:49 pm
by tlf30
OK, now loading drive from dl, still getting 0x07 return from read...

Code: Select all

;Set info for NASM
BITS 16 ;Code bitness
ORG 0x00 ;Start location of instructions in file 
;(Optional, the default is zero but this is included for clarity)
%define segment_address 0x07C0
%define stage1_address 0x5000
%define stage1_segment 0x0500
;
;Debugging switches, 0 = NO_DEBUG & 1 = DEBUG
%assign DEBUG_CLEAR_LOOP_PRINT_ADDRESS 0 ;Print the address that the ram clearing loop is at
%assign DEBUG_JERRY_RIG_JUMP 0 ;Force use of far return to accomplish jump into os loader
%assign DEBUG_DISABLE_JUMP 0 ;Disable jump into os loader
%assign DEBUG_HALT_JUMP 1 ;If jump is disabled and jerry rig jump is disabled then this will act as if it is on
%assign DEBUG_ENABLE_HANG_OVER_HALT 0 ;If hang is jumped to and this is enabled, then halt will be jumped to
%assign DEBUG_HALT_STRING 0 ;Print a string if halt is jumped to
%assign DEBUG_HANG_STRING 0 ;Print a string if hang is jumped to
;

;Boot Stage 0
main:
	jmp 0x07C0:0x0005 ;Set CS to correct location
	;Dissable interupts for stack operations
	cli

	;Setup stacks for kernel
	mov ax, segment_address ;Start address of stacks
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax

	;Setup ss and sp registers and stacks
	mov ax, 0x0600 ;0x6000
	mov ss, ax
	xor ax, ax
	mov sp, ax

	;Enable interupts, stack operations done
	sti
	
	pusha ;Store registers while we prep the video 
	
	;Setup video mode
	xor bx, bx
	xor cx, cx
	xor dx, dx
	mov ah, 0x00 ;Int 10h set video mode
	mov al, 0x12 ;640x480, 16 colors, VGA
	int 10h
		
	popa ;Restore registers, RAM is prepared
	
	.boot_id_store0:
		;Store boot device ID in RAM at 0x1002, device ID in DL
		mov ax, 0x0100
		mov es, ax
		mov byte [es:0x0002], dl
		mov ax, segment_address
		mov es, ax
	
	;Continue onto read_disk
	
read_disk:
	.prep:
		;Print string
		mov si, starting_stage1_s
		call update_status
		
		mov byte [errors_b], 0x07 ;Counter for errors, 7 trys
	
	.values:
		mov ax, 0x0100
		mov es, ax
		mov dl, [es:0x0002] ;Set drive number (boot device ID stored at 0x1002)
		mov ax, segment_address
		mov es, ax
		;Reset the disk and load it with disk geom' ... dl has disk BIOS ID already loaded above
		xor ax, ax ;Int 13 disk reset
		int 13h ;Reset disk
		;
		xor bx, bx ;0x0000, Location to write sectors at in relation to es
		mov ax, 0x0201 ;Int 13h read sector function, al; Number of sectors to read,
				 ;fills RAM allocated for Boot Stage 1 (3,584 bytes, 7 sectors) #### HAS BEEN CHANGED TO 01 FOR DEBUGGING!
		mov cx, 0x0002 ;Set cylinder + Set sector to start reading at... NOTE: Cylinders start at 0, Sectors start at 1 
		mov dh, 0x00 ;Set head
		;
		push bx
		mov bl, 0x02 ;Bios color green
		call print_dx ;#########################DEBUGGING OUTPUT
		pop bx
		;
		;Setup es for data transfer, segment for writing os loader
		mov ax, stage1_segment
		mov es, ax 
		
	.loop:
		;Read code
		int 13h ;Perform read
		jnc .done ;If read worked
		
		cmp byte [ds:errors_b], 0x00
		je .error ;Check if counter is zero
		;If not...
		dec byte [ds:errors_b]
		;Print errors
		pusha
		mov bl, 0x02 ;Bios color green
		mov dl, byte [ds:errors_b]
		call print_dx
		popa
		jmp .values ;Try to read again
		
	.error:
		xor ax,ax ;Int 13 disk reset
		int 13h ;Reset disk
		
		;Restore es to es address
		mov ax, segment_address
		mov es, ax
		
		mov si, disk_error_s
		mov bl, 0x04 ;Bios color red
		call update_status
		
		pusha
		mov dx,ax
		mov cl, 0x02
		call print_dx.calc
		
		jmp hang ;Stall system, cannot boot
		
	.done:
		
		;Restore es to ds address
		mov ax, segment_address
		mov es, ax
		
		;Calculate and store number of read failures
		pop cx ;Get counter out of stack
		mov ax, 0x0007 ;Store value to operate against
		sub ax, cx ;Get fails
		mov cx, 0x0100
		mov es, cx
		mov byte [es:0x0003], al ;Store number of read failures in 0x1003
		mov cx, segment_address
		mov es, cx
		
		;Continue onto start_boot

Re: INT 13h Returns 0x07

Posted: Sun Nov 24, 2013 12:03 am
by Minoto
tlf30 wrote:

Code: Select all

		;Reset the disk and load it with disk geom' ... dl has disk BIOS ID already loaded above
		xor ax, ax ;Int 13 disk reset
		int 13h ;Reset disk
		;
		xor bx, bx ;0x0000, Location to write sectors at in relation to es
		mov ax, 0x0201 ;Int 13h read sector function, al; Number of sectors to read,
				 ;fills RAM allocated for Boot Stage 1 (3,584 bytes, 7 sectors) #### HAS BEEN CHANGED TO 01 FOR DEBUGGING!
		mov cx, 0x0002 ;Set cylinder + Set sector to start reading at... NOTE: Cylinders start at 0, Sectors start at 1 
		mov dh, 0x00 ;Set head
		;
		push bx
		mov bl, 0x02 ;Bios color green
		call print_dx ;#########################DEBUGGING OUTPUT
		pop bx
		;
		;Setup es for data transfer, segment for writing os loader
		mov ax, stage1_segment
		mov es, ax 
		
	.loop:
		;Read code
		int 13h ;Perform read
		jnc .done ;If read worked
Assuming that print_dx does what its name implies, what does it say is in dl after the reset? And are you sure that it doesn't alter dl in the process of printing it? It's not shown here, so I can't tell. Personally, I'd play it safe and reload all necessary registers immediately before the read attempt.