'LBA out of range' error on loading sectors from bootloader

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
alethiophile
Member
Member
Posts: 90
Joined: Sat May 30, 2009 10:28 am

'LBA out of range' error on loading sectors from bootloader

Post by alethiophile »

I am trying to write a two-stage bootloader. The first stage is supposed to parse the FAT root directory, look for the second stage (2BOOT.BIN), and load it. I am having trouble with my read_sectors code, that uses BIOS interrupt 0x13, function 0x42, to read a given number of sectors from disk to memory. The relevant code:

Code: Select all

;; Method: read_sectors
;;--------------------------------------
;; cx = num sectors to read
;; eax = disk offset
;; es:bx => buffer to read to
;;--------------------------------------
;; Reads the number of sectors in cx from the disk offset in eax to the location es:bx.
;; Uses BIOS int 0x13. May not work if you have an old BIOS. The boot sector checks this.
;; Destroys values in eax, edx, esi, ecx
eoemsg	    db "Error in read_sectors, please reboot", 13, 10, 0

read_sectors:
	;; Make a disk address packet
	mov	byte [diskaddr],	0x10		;; packet size
	mov	byte [diskaddr+1],	0x00		;; reserved byte
	mov	word [diskaddr+2],	cx		;; num sectors
	mov	word [diskaddr+4],	es		;; offset to write to
	mov	word [diskaddr+6],	bx
	mov	dword [diskaddr+8],	eax		;; disk address (LBA)
	mov	dword [diskaddr+0x0b],	0x00

	xor	ecx,  ecx
	mov	cx,   5					;; try 5 times, then exit on error
try_again:
	mov	si,   diskaddr				;; address of disk packet
	mov	ah,   0x42				;; instruction code
	mov	dl,   0x80				;; disk to read (hard disk)
	
	int	0x13
	jnc	rs_done
	loop	try_again				;; try again on error
	jmp	exit_on_error			;; after 5 tries, exit	

rs_done:
	ret

exit_on_error:
	mov	si,	eoemsg
	call	print

	jmp	$
I run this to load the root directory of the FAT12 filesystem on the device. Every time the interrupt is called, it returns an error and Bochs outputs:

Code: Select all

int13_harddisk: function 42. LBA out of range
. The code runs 5 times, hence prints 5 errors, and then exits on error. I run it in the Bochs debugger. When I break at the start of the function and print the registers, the output is:

Code: Select all

eax: 0x00000013 19
ecx: 0x0000000e 14
edx: 0x00000000 0
ebx: 0x00000200 512
esp: 0x0000fffd 65533
ebp: 0x00000000 0
esi: 0x000e7c58 949336
edi: 0x0000ffac 65452
eip: 0x00007db3
eflags 0x00000246
id vip vif ac vm rf nt IOPL=0 of df IF tf sf ZF af PF cf
These don't look like unreasonable values. Does anyone have any idea what the problem is?
If I had an OS, there would be a link here.
User avatar
kmtdk
Member
Member
Posts: 263
Joined: Sat May 17, 2008 4:05 am
Location: Cyperspace, Denmark
Contact:

Re: 'LBA out of range' error on loading sectors from bootloader

Post by kmtdk »

well
i have found 1 (BIG) error , and you shoul have double cheked against code error when writing to memory :D

and i understand the hdd, because when you say "mov dword [diskaddr+0x08],eax you are writting the HIGH part of that Qword (tjek http://www.ctyme.com/intr/rb-0708.htm for a describing on packet strucktur). so in order to write to the low part, write :
mov dword [diskaddr+0x08+0x04] , eax
or just add 4 and 8, so it gives 0xc and write [diskaddr+0x0c] .....

KMT dk


edit:
and by the way, delete the line :
mov [diskaddr+0x0b],0x00
it will just make problems ! :P
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
User avatar
alethiophile
Member
Member
Posts: 90
Joined: Sat May 30, 2009 10:28 am

Re: 'LBA out of range' error on loading sectors from bootloader

Post by alethiophile »

Thanks for the help. I have not done much in assembly before this project, so I am liable to make fairly stupid errors. So, if I understand you correctly, the out-of-range error issue is a symptom of me not dealing with little/big-endianness? Also, what's this big error you refer to? And why should I delete the move to diskaddr+0x0b?

EDIT:
Reading it again, I now understand what you're talking about with the lba-out-of-range error. However, even having made the modification you suggest, I get the same error.
If I had an OS, there would be a link here.
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Re: 'LBA out of range' error on loading sectors from bootloader

Post by Dex »

Have you tryed
To read or write, first you need to set up a "Disk Address Packet Structure" in memory, on a DWORD (4 byte) boundary
User avatar
alethiophile
Member
Member
Posts: 90
Joined: Sat May 30, 2009 10:28 am

Re: 'LBA out of range' error on loading sectors from bootloader

Post by alethiophile »

Dex wrote:Have you tryed
To read or write, first you need to set up a "Disk Address Packet Structure" in memory, on a DWORD (4 byte) boundary
diskaddr points to a disk address packet. Its space is allocated in the bootloader, but not shown in the code snippet. All the mov instructions are used to set up the structure.

EDIT:
I ran through it byte by byte in memory, and it turned out that I had originally initialized the packet space to non-zero in order that I could find its offset in a dump of the file, and not set it to zero again. Having fixed that bug, I still had the same error. Groveling through memory dumps line by line, I remembered that the qword 'starting absolute block number' in the address packet is supposed to be little-endian. I undid the first change suggested, and it worked like a charm. *sigh...* Now on to a new and interested bug.
If I had an OS, there would be a link here.
User avatar
bewing
Member
Member
Posts: 1401
Joined: Wed Feb 07, 2007 1:45 pm
Location: Eugene, OR, US

Re: 'LBA out of range' error on loading sectors from bootloader

Post by bewing »

Um, you also have es and bx stored in reverse order in your disk address packet. I don't think anyone has mentioned that yet.
User avatar
kop99
Member
Member
Posts: 120
Joined: Fri May 15, 2009 2:58 am

Re: 'LBA out of range' error on loading sectors from bootloader

Post by kop99 »

Code: Select all

   mov   word [diskaddr+4],   es      ;; offset to write to
   mov   word [diskaddr+6],   bx
Are you going to read sectors in es:bx?
Then try that following code.

Code: Select all

   mov   word [diskaddr+4],   bx      ;; offset to write to
   mov   word [diskaddr+6],   es
Post Reply