Page 2 of 3

Re: Trouble with int 13h

Posted: Tue Mar 11, 2014 12:33 pm
by Gigasoft
Make sure that:
- You did not overwrite the IVT, BDA or any low memory location not reported in the memory map as available
- The stack does not overlap with a such location
- Interrupts are enabled
- You do not request a transfer such that addresses of the first and last byte are on different 64K pages

Here are some things to try:
- Install a keyboard ISR that dumps the current register state and stack contents to the screen when a key is pressed. Write down the information on a piece of paper.
- If the above does not work because the ISR doesn't get called, install a trace handler that does the same, and call the BIOS with pushf / call far instead of int 13h.
- Save the contents of 0e0000h-0fffffh to a file and open it up in a disassembler, to see where it's hanging

Re: Trouble with int 13h

Posted: Tue Mar 11, 2014 2:19 pm
by onlyonemac
I've tried all that you have suggested and all of it works under Bochs. All of it except anything involving int 13 works on my real hardware (which includes TWO machines of quite differant generations). So this is clearly specific to int 13.

Re: Trouble with int 13h

Posted: Tue Mar 11, 2014 2:44 pm
by h0bby1
does it fire any exception ?

Otherwise maybe you can track the execution from the timer interrupt to have a clue of where the code is hanging. Then dump machine code from this address and disassemble it.It might give some clue of the potential problem.

Re: Trouble with int 13h

Posted: Tue Mar 11, 2014 3:14 pm
by jnc100
Just to clarify, can you successfully call the particular int 13h function you are using before you make the first switch to protected mode?

This will help differentiate between a bug in your int 13h code and one in your return to real mode code.

Regards,
John.

Re: Trouble with int 13h

Posted: Wed Mar 12, 2014 12:04 pm
by DavidCooper
Try making EBP=ESP before calling Int 13 - there's a nasty BIOS bug on one of my machines that could also be causing your problem if EBP holds an address outside of the bottom 64K of mem.

Re: Trouble with int 13h

Posted: Wed Mar 12, 2014 2:06 pm
by onlyonemac
Yes, int 13 works to load the kernel code before I switch to protected mode and back again.

It's about time everyone stops mentioning disassembly/exceptions. As I have stated, this works fine under Bochs. Under real hardware, I cannot reasonably check for exceptions and/or carry out disassembly.

@DavidCooper: No it's not that because it works before switching to protected mode. I'll check anyway though. (Perhaps you could say what machine it is that's affected in your case? Also, I've got too quite differant ones and neither of them work.)

Re: Trouble with int 13h

Posted: Wed Mar 12, 2014 2:50 pm
by h0bby1
Even on real hardware, you can still get exceptions or getting the address from the timer or keyboard interrupt and dump opcodes from there a few bytes around the calling address, and then you can write them somewhere if you have only 1 comp and disassemble it, or make a quick disassembler , it's the first thing i'd try if i ran into a bios bug. It can give you an idea of what may be the problem. I don't see much other way to know what's going wrong. If you're going to get into os dev, you'll need something like that at some point.

Re: Trouble with int 13h

Posted: Wed Mar 12, 2014 3:10 pm
by onlyonemac
Well I've also checked int 0x0E (the floppy drive hardware interrupt). Under Bochs I get something from it; under real hardware it doesn't output my test character. But I know that hardware interrupts are enabled because the timer interrupt worked. Now what do I check?

Re: Trouble with int 13h

Posted: Wed Mar 12, 2014 10:34 pm
by Bender
Hi,
But I know that hardware interrupts are enabled because the timer interrupt worked. Now what do I check?
Your code.
We haven't seen it until now, many people are trying to help but they have to keep asking questions like Is this fine, is that fine etc. Once you show the code, then we may be able to investigate the problem rather than making assumptions.
-Bender

Re: Trouble with int 13h

Posted: Thu Mar 13, 2014 6:04 am
by h0bby1
If you have already checked everything that has been told in this thread (checking all 32 bit registers are cleared, that your stack is correctly setup with 16 bit registers, and all other register ds,es,bp are setup correctly) , as well as IDT, then you'll need more advanced debugging things to figure out what's wrong.

As mentioned before, BIOS functions are not supposed to be run after switch to protected mode, i'm not sure the intel is even really made to switch back to real mode, as can be seen with the 'unreal' mode, and certain number of internal registers that cannot be totally properly reset after a switch to real mode, or the huge number of things that a protected mode program can be doing that can then change the state of the computer in a way that some real mode code can bug.

If you really want to run interrupt after a switch in protected mode, you just can't expect that everything will run smoothly, even running bios from totally legit real mode can lead to some problem, after a switch to protected mode, there are just too many thing that can go wrong. Maybe the bios code do a switch itself in protected mode and then use some area in 'high memory' at boot time, that you erase them. Maybe some internal state of the cpu, either it's flags, internal registers, or something else is not reset properly.

There can be trick to do run interrupt from protected mode, but none of them are really safe or anything, and if you really want to be using this, then really you need to have a solid way to debug what's going on, to be able to work at machine code level, and yet i assume your os is still quite new, and things are yet relatively simple to debug, now imagine you already are in multi tasking os, that there are bios interrupt can be called a bit anywhere, (either with a complete switch to full real mode or not), and then the code start to hang up, then you'll do what ? you'll try to figure out with lucky guess ?

You need some kind of way to able to debug everything, dump state of all registers, memory, stack, execution location, stack frames, exceptions, it's one of the first thing you should be doing, it can a bit boring to do it specially at the beginning, but it's something that can save you hours of tedious debugging. Specially if you want to toy with switch between protected mode/real mode and using bios functions in such way. You NEED to have some kind of way to know what's going on in any code that you attempt to run, to dump state of memory, registers, stack, opcodes, exceptions, if you don't have anything like that at all, and you want to get into more complex os dev in multi tasked protected mode, well really good luck.

I've made a system like that, didn't really test it extensively on real hardware, but some other people used similar stuff to run bios functions in protected mode in real hardware, it's not all that hard to do, you just need to catch the return address from an interrupt or an exceptions, with a pusha it store all registers in memory, then you can grab the address where the code is hanging, dump opcode, and eventually writing simple debugger to monitor state of registers, and memory location, on the disassembled code quickly from either real mode or protected mode. Having something like that is really necessary if you want to deal with bios function after a switch to pmode.

Re: Trouble with int 13h

Posted: Thu Mar 13, 2014 6:20 am
by Bender
i'm not sure the intel is even really made to switch back to real mode
I guess the 386 real mode is same as protected mode except that the segment limits are 64KB and memory protection mechanisms are limited. That's the reason I think is the explanation for the existence of FRM (Flat Real Mode) or Unreal.
Maybe I am wrong.

Re: Trouble with int 13h

Posted: Thu Mar 13, 2014 6:41 am
by h0bby1
Bender wrote:
i'm not sure the intel is even really made to switch back to real mode
I guess the 386 real mode is same as protected mode except that the segment limits are 64KB and memory protection mechanisms are limited. That's the reason I think is the explanation for the existence of FRM (Flat Real Mode) or Unreal.
Maybe I am wrong.
The 'unreal mode' as far as i understood is because some internal registers that are set during a 'mov to segment register' related to memory bounds are not updated properly when you switch in real mode and don't set a proper value into a segment register.

There are some internal registers in the intel that are not really accessible directly, you can just change their value indirectly when executing some instructions. And the way those instruction will impact internal register depend on the mode the cpu is in. In protected mode, when you change the value of a segment register, the cpu load some infos from the gdt table into internal registers.

Not sure how many of those internal registers can be involved by a switch to pmode, or by any instruction run in any of rmode or pmode. it's not very well documented. Neither how that can potentially impact the execution of real mode code after the cpu has been switched to pmode. I'm not sure what kind of software bios designer can really use to test their implementation. I guess they mostly test it against most commonly found bootloader, because there is not that much widely used piece of software that really use bios function outside of bootloaders.

Given the current context, i guess it's safe to assume intel/amd cpu designer, as well as probably motherboard/bios designed just assume the real mode will only be used at boot time, and never used again after a switch to pmode.

The unreal mode is just an example, i don't think it's this who create a bug in the case, but it show that the intent of intel is not to allow easy switch to real mode, and that everything will be totally restored in sort to be able to execute real mode code when you set back the control register bit to zero. And effectively, it's not.

It gets even more complicated when you take in account real mode code that is known to run on cpu that has a protected mode, and can also use protected mode, like probably most bios assume they run on a cpu that has 32 bit protected mode. In the absolute, a bios could perfectly setup it's own gdt at boot time, and have part of the bios code that run in protected mode using this gdt.

Maybe the A20 gate state can be an issue as well.

If there was an easy to way to do this, there would not be a need for the vm86 mode.

Maybe getting a look into dos extender or that kind of things could give more clue about how to effectively switch to and back from pmode, while leaving cpu in state that is totally set back to real mode environment, and run bios functions, but i'm not even sure if those piece of code are really up to date with nowdays x86 cpus. But i guess they'd first save a certain number of things related to the current real mode state before to do anything else in protected mode, and restore them before the program leave the protected mode.

Grub also have plenty of code to use harddrive/usb key, and anything disk loading, and it's quite simple and well tested C code, to do this kind of things in protected mode.

Re: Trouble with int 13h

Posted: Thu Mar 13, 2014 11:51 am
by Nable
Bender wrote:
i'm not sure the intel is even really made to switch back to real mode
I guess the 386 real mode is same as protected mode except that the segment limits are 64KB and memory protection mechanisms are limited. That's the reason I think is the explanation for the existence of FRM (Flat Real Mode) or Unreal.
Maybe I am wrong.
Maybe I've already posted this link on osdev forum but I think it's worth posting it again: http://www.os2museum.com/wp/?p=319 (Title: Will the real Real Mode please stand up?)

Re: Trouble with int 13h

Posted: Thu Mar 13, 2014 11:57 am
by h0bby1
Nable wrote:
Bender wrote:
i'm not sure the intel is even really made to switch back to real mode
I guess the 386 real mode is same as protected mode except that the segment limits are 64KB and memory protection mechanisms are limited. That's the reason I think is the explanation for the existence of FRM (Flat Real Mode) or Unreal.
Maybe I am wrong.
Maybe I've already posted this link on osdev forum but I think it's worth posting it again: http://www.os2museum.com/wp/?p=319 (Title: Will the real Real Mode please stand up?)

Processor evolution helped to obscure matters some more. With the 286, the programmer could not switch from protected mode back to real mode (not even using the undocumented LOADALL instruction). After reset, the CPU always started in real mode, and the processor took care of setting everything up. Starting with the 386, switching from protected back to real mode was possible without a processor reset.


can be important thing to notice :) maybe things would have been clearer if it stayed that way, because i believe it's more how pmode switch is supposed to be used.

Re: Trouble with int 13h

Posted: Thu Mar 13, 2014 1:43 pm
by DavidCooper
Still no code on view, but maybe it would be too complex for us to make anything of it in any case, so it's possible you're in the same position I was in when I had a similar problem which no one else could have helped solve. Here's how I tracked down the EBP BIOS bug (in an American Megatrends BIOS):-

Step 1. Simplify the problem. In your code where you switch to protected mode, insert some test code immediately after the jump into protected mode to jump straight back into real mode, then call Int 13 to load a sector somewhere and make sure it works (displaying a result to the screen before halting). If it doesn't work, the bug is somewhere prior to your jump into protected mode (or in your test code if you aren't jumping back into real mode in the right way - I do it in two steps, first jumping to 16-bit protected mode, then changing to real mode and jumping again to load CS with a real mode segment, and this process depends on my 16-bit GDT entry being correctly designed). Note that I'm assuming here that you will simplify everything down to nothing but a jump into protected mode, so you're doing it with the interrupts disabled and without fiddling with IDT or the PIC.

Step 2. If Int 13 worked after jumping into protected mode and back, now move your test code a little further on. If you're setting up an IDT, write some code to put it back the way it was before and add that to your test code, then run this new test code with an Int 13 call at the end as before. If it fails, you aren't restoring the IDT correctly. (There is no need to enable interrupts while in protected mode at this stage).

Step 3. If Int 13 still worked, now remap the PIC and add some code to your test code to un-remap it back to where it started. Again there is no need to enable the interrupts while in protected mode yet.

Step 4. Etc. - whatever it is you're changing move your test code past each new thing and write code to undo it immediately after it's been done. At some point you will find that Int 13 fails, and as soon as that happens you'll be able to pin down where the fault must lie.

In my case, all these tests worked right the way through the whole process of getting into the state I wanted my OS to run in, but it left me with a test tool which I could insert anywhere in my OS where it was running in protected mode to see if Int 13 still worked, so I then had to relocate it into many different places until it hit a point where it failed, and then I narrowed down the point where it was failing and found that it still worked immediately before an instruction involving loading EBP, but then failed immediately after it.

If you follow this procedure, you will find your bug.