[SOLVED] Int 0x13, AH=0x42 works only once

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.
Post Reply
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

[SOLVED] Int 0x13, AH=0x42 works only once

Post by AlfaOmega08 »

Any idea of why the following code, supposed to load the GPT header, then the partition table, then the BIOS Boot Partition doesn't work?
Stepping through bochs I see that only the first time the INT 0x13 is called for extended read works. The second time bochs outputs "int13_harddisk: function 42, error 01 !". AH is set to 0x0C.

I tought the problem was that in the first read I did read too many sectors at once... so I made the ReadSector function split up in "ecx" reads, but still that won't work.... Any help?

Code: Select all

[BITS	16]
[ORG	0x7C00]

	cli
	xor	ax, ax
	mov	ds, ax
	mov	ss, ax

	jmp	0:Start

Start:	
	mov sp, 0x7C00
	sti

	mov si, DiskPacket

	mov [DxBackup], dx

	; INT13 Extensions Setup Check (save boot disk number)
	mov ah, 0x41
	mov bx, 0x55AA
	int	0x13
	jc PrintError

	mov dx, [DxBackup]

	; Read the GPT Header
	mov ecx, 1
	mov ebx, 0x200
	mov eax, 1
	call ReadSector

	; Look for GPT Signature
	cmp dword [0x200], 0x20494645
	jne	PrintError
	cmp dword [0x204], 0x54524150
	jne	PrintError

	; Read partition table LBA
	mov	eax, [0x248]
	push eax
	
	; Sectors to read = ((number of entries * size of entries) + 511) >> 9;
	mov eax, [0x250]
	mov ebx, [0x254]
	mov [PartEntrySize], ebx
	mov [PartEntryCount], eax
	mul ebx
	add eax, 511
	shr eax, 9
	
	mov ecx, eax
	pop eax
	mov ebx, 0x200
	mov dx, [DxBackup]
	call ReadSector
	
	mov ebx, 0x200
	mov ecx, [PartEntryCount]

CheckPartition:
	cmp dword [ebx], 0x21686148
	jne	.Next
	cmp	dword [ebx + 4], 0x6e6f6449
	jne	.Next
	cmp	dword [ebx + 8], 0x65654e74
	jne .Next
	cmp dword [ebx + 12], 0x49464564
	jne	.Next

	jmp .Found

.Next:
	add ebx, [PartEntrySize]
	loop CheckPartition
	jmp PrintError

.Found:
	mov dx, [DxBackup]
	mov ebx, [ebx + 32]
	push ebx

	mov ecx, 1
	mov eax, ebx
	mov ebx, 0x200
	call ReadSector
	
	cmp dword [0x200], 0x6F4E6D49
	jne PrintError
	cmp dword [0x204], 0x49464574
	jne PrintError

	pop eax
	inc eax
	mov ecx, [0x208]
	dec ecx
	mov ebx, 0x400
	mov dx, [DxBackup]
	call ReadSector

	mov dx, [DxBackup]	
	jmp 0x20C

ReadSector:
	pusha
	mov [DiskPacket], word 0x10
	mov word [DiskPacket + 2], 1
	mov [DiskPacket + 4], ebx
	mov [DiskPacket + 8], eax
	mov [DiskPacket + 12], dword 0
	
.ReadNext:
	xor eax, eax
	mov ah, 0x42
	push ecx
	int	0x13
	jc PrintError
	pop ecx
	
	loop .Next
	
	popa
	ret
	
.Next:
	inc dword [DiskPacket + 8]
	add word [DiskPacket + 4], 0x200
	cmp word [DiskPacket + 4], 0x200
	jl .NextSeg
	jmp .ReadNext
	
.NextSeg:
	add word [DiskPacket + 6], 0x1000
	jmp .ReadNext	

PrintError:
	mov si, ErrorMessage
	call message
	
stop:
	hlt
	jmp	stop
	
ErrorMessage DB "Error!", 0
GoodMessage	 DB "Good!", 10, 13, 0

message:
	lodsb
	cmp al, 0
	je .done
	mov	bx, 1
	mov	ah, 0xE
	int	0x10
	jmp message
.done:
	ret

DxBackup		DW 0
PartEntrySize	DD 0
PartEntryCount	DD 0

ALIGN 4
DiskPacket:
	DW 0	; Size and reserved
	DW 0	; Blocks count
	DD 0	; Buffer
	DQ 0	; Starting LBA

	times (446 - ($ - $$)) DB 0

	; Partition table: 1 GPT partition
	DD 0x00010000
	DD 0xFFFFFEEE
	DD 1
	DD 0xFFFFFFFF

	times (510 - ($ - $$)) DB 0

	DW 0xAA55
Thanks in advance.
Last edited by AlfaOmega08 on Sat Jul 14, 2012 4:08 pm, edited 1 time in total.
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
Antti
Member
Member
Posts: 923
Joined: Thu Jul 05, 2012 5:12 am
Location: Finland

Re: Int 0x13, AH=0x42 works only once

Post by Antti »

I have not fully analyzed your code but I would suggest that you set the SI register to point your DiskPacket just before the interrupt 0x13 call. Every time.
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Int 0x13, AH=0x42 works only once

Post by egos »

Reset "Number of sectors to read" in DAP structure everytime.
If you have seen bad English in my words, tell me what's wrong, please.
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Re: Int 0x13, AH=0x42 works only once

Post by AlfaOmega08 »

Still no luck. After some refactoring, now the error is LBA out of range :( :(

Code: Select all

[BITS	16]
[ORG	0x7C00]

	cli
	xor ax, ax
	mov ds, ax
	mov ss, ax

	jmp 0:Start

Start:	
	mov sp, 0x7C00
	sti

	mov [DxBackup], dx

	call CheckInt13
	call ReadGPTHeader
	call GetPartitionTableLength
	mov ecx, eax
	
	; Read partition table LBA
	mov eax, [0x248]
	mov ebx, 0x200
	call ReadSectors

	call FindBBP	

	mov eax, [eax + 32]
	mov ebx, 0x200
	push eax
	call ReadSingleSector
	pop eax
	
	; Check the signature of the second stage loader (not related to GPT in any way)
	cmp dword [0x200], 0x6F4E6D49
	jne PrintError
	cmp dword [0x204], 0x49464574
	jne PrintError

	; Read remaining sectors (offset 8 in the 2nd stage contains the size in sectors of the 2nd stage itself)
	inc eax
	mov ecx, [0x208]
	dec ecx
	mov ebx, 0x400
	call ReadSectors

	mov dx, [DxBackup]

	; Executable code starts at 0x20C
	jmp 0x20C

; EAX = LBA of first sector
; EBX = Segment and offset of buffer
; ECX = Number of sectors to read
ReadSectors:
	cmp ecx, 0
	je .Finally

	call ReadSingleSector
	add bx, 0x200
	cmp bx, 0x200
	jl .NextSeg
	jmp .Finally
	
.NextSeg:
	add ebx, 0x10000000	
	
.Finally:
	loop ReadSectors
	ret

; EAX = LBA of first sector
; EBX = Segment and offset of buffer
ReadSingleSector:
	pusha
	
	; Disk packet here
	push dword 0
	push eax
	push ebx
	push word 0x0001
	push word 0x0010
	
	mov ah, 0x42
	mov dx, [DxBackup]
	mov si, sp
	int 0x13
	jc PrintError
	add sp, 0x10
	popa
	ret

PrintError:
	mov si, ErrorMessage
	call PutMessage
	
stop:
	hlt
	jmp	stop
	
PutMessage:
	lodsb
	cmp al, 0
	je .done
	mov	bx, 1
	mov	ah, 0xE
	int	0x10
	jmp PutMessage
.done:
	ret

CheckInt13:
	; INT13 Extensions Setup Check (save boot disk number)
	mov ah, 0x41
	mov bx, 0x55AA
	int 0x13
	jc PrintError
	ret

ReadGPTHeader:
	; Read the GPT Header
	mov ebx, 0x200
	mov eax, 1
	call ReadSingleSector

	; Look for GPT Signature
	cmp dword [0x200], 0x20494645
	jne PrintError
	cmp dword [0x204], 0x54524150
	jne PrintError
	ret
	
GetPartitionTableLength:
	; Sectors to read = ((number of entries * size of entries) + 511) >> 9;

	mov eax, [0x250]
	mov ebx, [0x254]
	mov [PartEntrySize], ebx
	mov [PartEntryCount], eax
	mul ebx
	add eax, 511
	shr eax, 9
	ret

FindBBP:
	mov ebx, 0x200
	mov ecx, [PartEntryCount]

CheckPartition:
	cmp dword [ebx], 0x21686148
	jne .Next
	cmp dword [ebx + 4], 0x6e6f6449
	jne .Next
	cmp dword [ebx + 8], 0x65654e74
	jne .Next
	cmp dword [ebx + 12], 0x49464564
	jne .Next

	jmp .Found

.Next:
	add ebx, [PartEntrySize]
	loop CheckPartition
	jmp PrintError

.Found:
	mov eax, ebx
	ret

DxBackup		DW 0
PartEntrySize	DD 0
PartEntryCount	DD 0
ErrorMessage	DB "Error!", 0

times (446 - ($ - $$)) DB 0

; Partition table: 1 GPT partition
DD 0x00010000
DD 0xFFFFFEEE
DD 1
DD 0xFFFFFFFF

times (510 - ($ - $$)) DB 0

DW 0xAA55
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
egos
Member
Member
Posts: 612
Joined: Fri Nov 16, 2007 1:59 pm

Re: Int 0x13, AH=0x42 works only once

Post by egos »

Don't destroy IVT & BDA.
If you have seen bad English in my words, tell me what's wrong, please.
User avatar
Firestryke31
Member
Member
Posts: 550
Joined: Sat Nov 29, 2008 1:07 pm
Location: Throw a dart at central Texas
Contact:

Re: Int 0x13, AH=0x42 works only once

Post by Firestryke31 »

Don't forget that the packet has to be dword-aligned. Here's what I do to align the stack:

Code: Select all

;; Save previous stack frame
	push bp
;; Set the stack frame
	mov bp, sp
;; Align the stack to a dword boundary (I chose to 16 bytes 'cause it's simple)
	and sp, 0xFFF0
;; Put the structure on the stack

	;; ...

;; Remove the structure & alignment padding from the stack
	mov sp, bp
;; Restore the old stack frame
	pop bp
	ret
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
User avatar
AlfaOmega08
Member
Member
Posts: 226
Joined: Wed Nov 07, 2007 12:15 pm
Location: Italy

Re: Int 0x13, AH=0x42 works only once

Post by AlfaOmega08 »

egos wrote:Don't destroy IVT & BDA.
Oh hell. You're absolutely right. For some insane reason I tought IVT ends at 0x1FF instead of 0x3FF. And I totaly forgot about BDA...

Thanks egos, that solved my problem
Please, correct my English...
Motherboard: ASUS Rampage II Extreme
CPU: Core i7 950 @ 3.06 GHz OC at 3.6 GHz
RAM: 4 GB 1600 MHz DDR3
Video: nVidia GeForce 210 GTS... it sucks...
Post Reply