OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 8:58 am

All times are UTC - 6 hours




Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: [Solved] BIOS Int 13/02h hangs the bootloader
PostPosted: Sat Jan 27, 2018 9:27 pm 
Offline

Joined: Sat Jan 27, 2018 2:02 pm
Posts: 8
I am writing a simple bootloader and currently having a problem loading the kernel into the memory from disk. When I try to read disk sectors, int13/02h never returns and hangs the execution of the program. I managed to make the bootloader print a hello-message prior to making the interrupt (int 10/Eh), so the boot signature is ok and the bootloader code is being run.

I'd like to read 1 sector, and here are my registers at the execution address of int13/02h (checked with debugging):

ax: 0x201
bx: 0x8000 (my kernel offset)
cx: 0x02
dx: 0x80
sp: 0xffff

ss: 0x9000
ds: 0x07c0 (will set to 0x0 before ljumping to kernel)
es: 0x0

It seems like I am experiencing something similar to this, except that I am setting up the es:bx buffer correctly, so the correct answer doesn't really help me.

Code:
   movw  $0x0, %bx
   movw  %bx, %es
   movw  $0x8000, %bx


Needless to say, I am pretty new to this. I hope anyone can point me in the right direction, and hopefully the information I've provided is sufficient.

Edit
ss: 0x9000 (previously 0x7000)


Last edited by PaulAche on Sun Jan 28, 2018 10:34 pm, edited 3 times in total.

Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sat Jan 27, 2018 11:43 pm 
Offline
Member
Member
User avatar

Joined: Sun Jan 13, 2013 6:24 pm
Posts: 90
Location: Grande Prairie AB
Post your entire code, that way those of us helping won't have to make so many assumptions about what it might be.


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 8:00 am 
Offline

Joined: Sat Jan 27, 2018 2:02 pm
Posts: 8
Edit: The code served no purpose in solving this issue. This was caused by the stack segment overriding the EBDA sector.


Last edited by PaulAche on Mon Jan 29, 2018 10:43 am, edited 2 times in total.

Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 9:51 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
What's the return code from the BIOS call?


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 10:32 am 
Offline

Joined: Sat Jan 27, 2018 2:02 pm
Posts: 8
iansjack wrote:
What's the return code from the BIOS call?

That is what I am getting at. There is no return, the bootloader just hangs when it tries to execute the int13/02h line.


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 11:33 am 
Offline
Member
Member
User avatar

Joined: Sat Mar 31, 2012 3:07 am
Posts: 4591
Location: Chichester, UK
How do you know it is "hanging"?


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 11:46 am 
Offline

Joined: Sat Jan 27, 2018 2:02 pm
Posts: 8
iansjack wrote:
How do you know it is "hanging"?


I've run bochs with gdb and set 2 breakpoints, one at
Code:
int $0x13
and another at
Code:
cmpb $0x0, %ah
(the instruction right after int13/2h).

It hits the first breakpoint at
Code:
int $0x13
I am able to interact with the debugger, e.g. "info registers", "continue". However, when I type "continue" to resume the execution, bochs hangs and the gdb becomes irresponsive. It never reaches the 2nd breakpoint:
Code:
cmpb $0x0, %ah


Bochs hangs without the gdb as well.


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 12:36 pm 
Offline

Joined: Sat Jan 27, 2018 2:02 pm
Posts: 8
PaulAche wrote:
Edit
ss: 0x9000 (previously 0x7000)


I am very sorry for confusing everyone. I had my %ss register set to 0x9000, not 0x7000 as stated previously. After actually changing it to 0x7000 the bootloader no longer hanged and I was able to read the sector (returned ah=0). My initial thought was that my read was somehow overwriting the stack. However, I was only reading 1 sector (512 bytes) at the address 0x8000, so that can't be the case. Could anyone explain?


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 1:04 pm 
Offline
Member
Member

Joined: Thu Jul 05, 2007 8:58 am
Posts: 223
After the complete read, you have only 512 bytes of stack space left. It is very well possible that your bios uses more than that internally.


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 1:16 pm 
Offline
Member
Member
User avatar

Joined: Sun Jan 13, 2013 6:24 pm
Posts: 90
Location: Grande Prairie AB
#1: Your string is not NULL terminated
#2: Don't hardcode DL, what it needs to be has already been passed by BIOS
#3: Trace into the code @ 8000H, cause that's probably where the problem is.

In Boch's, just single step to next instruction after BIOS function and see what's returned in AH or set your breakpoint @ cmp $0x0, %ah


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 1:58 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
PaulAche wrote:
Could anyone explain?

Your stack was colliding with the EBDA. Take a look at this memory map for example.

(You should also be setting SP to 0, not 0xFFFF.)


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 2:15 pm 
Offline

Joined: Sat Jan 27, 2018 2:02 pm
Posts: 8
Octocontrabass wrote:
PaulAche wrote:
Could anyone explain?

Your stack was colliding with the EBDA. Take a look at this memory map for example.

(You should also be setting SP to 0, not 0xFFFF.)

Could you please elaborate a bit more? I fail to grasp how changing my stack segment to 0x7000 will prevent EBDA collision. Also, why should the sp be set to 0?


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 2:27 pm 
Offline

Joined: Sat Jan 27, 2018 2:02 pm
Posts: 8
TightCoderEx wrote:
#1: Your string is not NULL terminated
#2: Don't hardcode DL, what it needs to be has already been passed by BIOS
#3: Trace into the code @ 8000H, cause that's probably where the problem is.


#1. asciz, z stands for zero. They are null terminated.
#2. I was taught never to assume any register values in bootblock, DL included. Hardcoding 80h shouldn't be a problem, I am not trying to boot from a CD-ROM.
#3. It would be nice if I could, but the gdb hangs during the execution.

TightCoderEx wrote:
In Boch's, just single step to next instruction after BIOS function and see what's returned in AH or set your breakpoint @ cmp $0x0, %ah


I couldn't single step/trace/info registers because both Bochs and the GDB hung during (not after) the execution of 0x13.


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 2:47 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5099
PaulAche wrote:
Could you please elaborate a bit more? I fail to grasp how changing my stack segment to 0x7000 will prevent EBDA collision.

With SS set to 0x9000, your stack segment covers the entire (linear) address range from 0x90000 to 0x9FFFF, which includes the small section reserved for use by the EBDA. You put your stack right at the top, where the EBDA goes.

PaulAche wrote:
Also, why should the sp be set to 0?

In the x86 architecture, SP always points to the item at the top of the stack. When the stack is completely empty, SP should point just past the topmost space in the stack. If the first byte to be filled by a push is at 0xFFFF, then SP should point to one byte higher: 0.

Wasting one byte of stack space is no big deal, but having the stack misaligned can be a big performance hit, and compiled code requires the stack to be aligned.

(For contrast, some non-x86 CPU architectures have their equivalent of SP pointing to the empty space at the top of the stack. In these architectures, setting the stack pointer to 0xFFFF would be correct.)

PaulAche wrote:
#2. I was taught never to assume any register values in bootblock, DL included. Hardcoding 80h shouldn't be a problem, I am not trying to boot from a CD-ROM.

Almost all BIOSes will set DL for you, including every PnP BIOS (which is everything from the mid-90s onward). Hardcoding it means you'll have problems the first time you encounter a BIOS that doesn't assign 0x80 to your boot disk.


Top
 Profile  
 
 Post subject: Re: BIOS Int 13/02h hangs the bootloader
PostPosted: Sun Jan 28, 2018 3:18 pm 
Offline

Joined: Sat Jan 27, 2018 2:02 pm
Posts: 8
Octocontrabass wrote:
PaulAche wrote:
Could you please elaborate a bit more? I fail to grasp how changing my stack segment to 0x7000 will prevent EBDA collision.

With SS set to 0x9000, your stack segment covers the entire (linear) address range from 0x90000 to 0x9FFFF, which includes the small section reserved for use by the EBDA. You put your stack right at the top, where the EBDA goes.

PaulAche wrote:
Also, why should the sp be set to 0?

In the x86 architecture, SP always points to the item at the top of the stack. When the stack is completely empty, SP should point just past the topmost space in the stack. If the first byte to be filled by a push is at 0xFFFF, then SP should point to one byte higher: 0.

Wasting one byte of stack space is no big deal, but having the stack misaligned can be a big performance hit, and compiled code requires the stack to be aligned.

(For contrast, some non-x86 CPU architectures have their equivalent of SP pointing to the empty space at the top of the stack. In these architectures, setting the stack pointer to 0xFFFF would be correct.)

PaulAche wrote:
#2. I was taught never to assume any register values in bootblock, DL included. Hardcoding 80h shouldn't be a problem, I am not trying to boot from a CD-ROM.

Almost all BIOSes will set DL for you, including every PnP BIOS (which is everything from the mid-90s onward). Hardcoding it means you'll have problems the first time you encounter a BIOS that doesn't assign 0x80 to your boot disk.


Your explanation makes perfect sense! The only thing I'm struggling with is understanding how you got the linear address range from 0x9000. If I remember correctly, I can get the linear address by SS * 16 + SP. That would make the address range start at (0h * 16h) + 9000h = 0x90000 (20-bit value). How did you get the upper range value 0x9FFFF?


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 18 posts ]  Go to page 1, 2  Next

All times are UTC - 6 hours


Who is online

Users browsing this forum: DotBot [Bot] and 76 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group