Page 1 of 1

INT 0x13 AH=0x42 returns error

Posted: Sat Sep 08, 2018 5:03 pm
by thumble
I have been working on a simple bootloader for my OS, and I have encountered a problem.
I'm trying to use INT 0x13 AH=0x42 to load 8 sectors of code from the disk, but for some reason it always returns with AH=0x01 ("invalid function in AH or invalid parameter")

I think there is something wrong with this function, though I haven't been able to pinpoint anything:

Code: Select all

loadstage2:
	mov ah, 0x42
	mov si, dap
	mov dl, byte [drivenum]
	int 0x13
	jc .errloading
	ret
.errloading:
	jmp hang

dap:       
	size db 0x10
	zero db 0
	sectors db 8
	load_address dd 0x00007E00
	start_sec dq 1
My code does check whether BIOS extensions are available, so I don't think that is the problem.

Re: INT 0x13 AH=0x42 returns error

Posted: Sat Sep 08, 2018 5:22 pm
by thumble
I found out the problem.

Strangely enough, the first letter of startmsg was being copied into start_sec of the DAP. I added a filler so that this doesn't happen, and the problem is (seemingly) fixed now.
Here is my fixed code:

Code: Select all

dap:
[...]
	start_sec dq 1

	; For some reason this is necessary.
	filler db 0
	
startmsg db 'booted TestOS.',13,10,0

Re: INT 0x13 AH=0x42 returns error

Posted: Sat Sep 08, 2018 6:00 pm
by BenLunt
I would look into that. It sounds funny. Why would the first letter of the string, 8 bytes away, be copied into start_sec.

1) Assembler has a bug (doubtful)
2) You have a pointer issue somewhere
3) You are loading the code and skipping something.
4) Just about anything.

I would run it through Bochs, set a break point for when that byte gets changed, and see where you are.

Just for fun, you don't have to set up a separate place for the DAP. You can use the stack. For an example, see my code at https://github.com/fysnet/FYSOS/blob/ma ... ad_ext.inc.

Code: Select all

  // edx:eax = LBA to read
  // ebx = physical address to read it to
  // cx = count of sectors to read (should not be more than 7Fh, as well as this makes CH = 0)
           push edx        ; offset 12
           push eax        ; offset 8
           shl  ebx,12
           shr  bx,12
           push ebx        ; offset 4
           push cx         ; offset 2 (ch = 0)
           push 10h        ; offset 0
           mov  si,sp
           mov  ah,42h     ; read
           mov  dl, ...
           int    13h
Just make sure you adjust the stack afterward. ( add sp,16 )

You can call another service to see if the MSEXT services are available.

Depending on the BIOS manufacturer, I have seen this service available for floppies as well, go figure. Most BIOSes will return the carry set when checking for this service when DL points to a floppy, but will return TRUE (carry clear and BX=sig, etc.) when DL points to a hard drive.

Ben
- http://www.fysnet.net/osdesign_book_series.htm