OSDev.org

The Place to Start for Operating System Developers
It is currently Thu Mar 28, 2024 5:59 pm

All times are UTC - 6 hours




Post new topic Reply to topic  [ 7 posts ] 
Author Message
 Post subject: Can't jump into protected mode after INT13 on real hardware
PostPosted: Mon Dec 17, 2018 11:05 am 
Offline

Joined: Mon Dec 17, 2018 11:01 am
Posts: 2
My OS wasn't working on my computer, even though it worked on every emulator I've tested it (many). Now I've managed to narrow the problem down to any call to interrupt 13h.

I've put a jump instruction to the protected mode loader right before the interrupt call:

Code:
[...]
cmp dl, [DriveNumber]
je drive_number_ok
mov [DriveNumber], dl
mov ah, 8
jmp ent_pmode       ; SKIP LOADING KERNEL
int 0x13
[...]


And it works just fine, I can load into protected mode and print some debug strings. Now, if I put it just after my call to the interrupt, like this:

Code:
[...]
cmp dl, [DriveNumber]
je drive_number_ok
mov [DriveNumber], dl
mov ah, 8
int 0x13
jmp ent_pmode
[...]


It suddenly doesn't work anymore, my computer reboots. I've tried everything, set up EVERY general register and segment register to their EXACT values before the interrupt call, and nothing.

I've also tried to skip this interrupt call, by setting my disk variables manually, but then in my next interrupt call (INT13/2, to actually read information from the disk) the same problem occurs.

I can't make any sense out of this, especially because INT13/8 shouldn't change anything else except a few registers that have no influence whatsoever on the protected mode code/jump.

If it changes anything, I have a Gigabyte G31M-ES2L motherboard with an Intel Core 2 Duo E7500 processor.

Thanks.


Top
 Profile  
 
 Post subject: Re: Can't jump into protected mode after INT13 on real hardw
PostPosted: Mon Dec 17, 2018 12:46 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
Your bug is not in the section of code you've posted.

tiago wrote:
set up EVERY general register and segment register to their EXACT values before the interrupt call,

Including the FLAGS register?


Top
 Profile  
 
 Post subject: Re: Can't jump into protected mode after INT13 on real hardw
PostPosted: Mon Dec 17, 2018 2:53 pm 
Offline

Joined: Mon Dec 17, 2018 11:01 am
Posts: 2
Octocontrabass wrote:
Your bug is not in the section of code you've posted.

Yeah, I just posted a little bit of code to give minimal context to the interrupt.

Octocontrabass wrote:
Including the FLAGS register?

Yes, here's my updated attempt (still not working):
Code:
[...]
cmp dl, [DriveNumber]
je drive_number_ok
mov [DriveNumber], dl
mov ah, 8

push ax
push bx
push cx
push dx
push es
push di
pushf

int 0x13

popf
pop di
pop es
pop dx
pop cx
pop bx
pop ax

jmp ent_pmode
[...]


EDIT: I've attached my full stage 2 from the bootloader, hope it helps.


Attachments:
boot1.asm [8.45 KiB]
Downloaded 19 times
Top
 Profile  
 
 Post subject: Re: Can't jump into protected mode after INT13 on real hardw
PostPosted: Mon Dec 17, 2018 4:38 pm 
Offline
Member
Member

Joined: Mon Mar 25, 2013 7:01 pm
Posts: 5100
Some BIOS functions switch to protected mode.

They probably don't restore the previous value of the GDTR when they're done.

Perhaps move your LGDT instruction a bit closer to the point where you enter protected mode.


Top
 Profile  
 
 Post subject: Re: Can't jump into protected mode after INT13 on real hardw
PostPosted: Mon Dec 17, 2018 5:42 pm 
Offline
Member
Member

Joined: Fri Aug 26, 2016 1:41 pm
Posts: 671
I'm going to go in a slightly different direction with this. On your real computer are you booting this off USB drive? If you are do you happen to be using Floppy Disk Drive (FFD) emulation in the BIOS for USB?

I ask these questions because if you are using USB with FDD emulation you almost certainly need to create a BIOS Parameter Block (BPB_. Many modern legacy BIOSes using USB FDD emulation will blindly write the drive geometry into your bootloader with the assumption that a BPB (or space for one) has been set aside. After your bootloader is read into memory by the BIOS, the drive geometry may be written into the area where the BPB would be and then the BIOS transfers control to your bootloader at physical address 0x07c00. Without a BPB, this could in effect overwrite instructions or data of your bootloader causing it to do unexpected things.

I have written a Stackoverflow answer about this very common issue.

I just noticed this:
Code:
    mov ax, 0x9000
    mov ss, ax
    mov sp, 0xffff


SP should really be an even number for performance reasons on some CPUs, however more problematic is that 0x9000:0xffff may actually be on top of the Enhanced BIOS Data Area (EBDA) that sits below 0x0A000. Often this area is on kilobyte (the size can be queried through the BDA memory area). For safety sake you could use:
Code:
    mov ax, 0x8000
    mov ss, ax
    mov sp, 0xfffe


Top
 Profile  
 
 Post subject: Re: Can't jump into protected mode after INT13 on real hardw
PostPosted: Sat Dec 29, 2018 3:15 am 
Offline

Joined: Sat Dec 29, 2018 3:09 am
Posts: 10
Not an answer to your question but one general assumption I program by:
If it works on real hardware it won't work on an emulator,
If it works on an emulator it won't work on real hardware.


Top
 Profile  
 
 Post subject: Re: Can't jump into protected mode after INT13 on real hardw
PostPosted: Fri Jan 11, 2019 12:11 pm 
Offline

Joined: Fri Jan 04, 2019 6:05 am
Posts: 9
I had a very similar problem with my build. The problem is likely that you are not resetting your segment registers. If you do not initialize your segment registers at the beginning they will be holding garbage values from the BIOS and your 16bit code will likely never get run or operate on unexpected locations of memory. The same thing will happen again in the 32 bit protected if you do not re initialize them once again. When you make the long-jump necessary to break into 32bit protected the registers will be flushed. I will attach a link to my posting of the problem as the original poster of the solution states it better than me.

viewtopic.php?f=1&t=33416

specifically I am talking about this answer

quirck wrote:
You seem to be ignoring the segment registers altogether. DS is implicitly used when you store boot_device, for example, so you don't know what you overwrite there. Then, SS controls stack location. Finally, int 0x13 loads sectors at ES:BX, not just BX. On emulators these segment registers are likely to contain good values like zeroes, but on real hardware they will contain something left after BIOS startup code, so you need to set them manually.

Actually, the pdf you linked discusses it at the end of the third chapter, but the code it presents still does not set them, which is incorrect. You need to initialize them at the beginning:
Code:
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00 ; I wouldn't say that 0x8000 is "safely out of the way"


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 7 posts ] 

All times are UTC - 6 hours


Who is online

Users browsing this forum: No registered users and 63 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