- - The system will only switch back to real mode if the program's start address is under 0x8000. I thought I was not working with a 1:1 page, but after identity paging the first 0x100000 bytes, I still get the same result.
- Bochs will throw different errors depending on what the start address and what sp is set to after switching to real mode: the closest I've gotten was the start address at 0x6000 and sp at 0x9000. However, any interrupt made to 0x10 after interrupts are restored will switch the VGA mode to 13h under Bochs, and has no result under VirtualBox. I assume this is because it's executing random code.
[solved] Real Mode Confusion
[solved] Real Mode Confusion
I've followed the instructions at the Real Mode wiki page and the appropriate section for the IA-32 Developer's Manual for switching back to real mode from protected mode. However, it's been giving me troubles, and I'm sure I'm missing something:
Last edited by RobertF on Tue Nov 01, 2011 5:05 pm, edited 1 time in total.
-
- Posts: 20
- Joined: Sat Oct 22, 2011 4:17 pm
Re: Real Mode Confusion
Not an expert on the topic, but here's a stab at it:
In real mode, you have access to 32bit memory, but only have a 16 bit IP register. So if you try going to real mode with IP set to a 32bit address, it's going to go to the instruction at the address in the lower 16 bits -- explains why you see random instructions being executed.
[edit] just re-read your post and see that the above probably doesn't apply to what you're doing [/edit]
Also, double check the memory map for low memory as there are some restrictions as to where you can load things. Make sure what you're loading fits and doesn't start overriding EBDA and video, etc
http://wiki.osdev.org/Memory_Map_%28x86%29
In real mode, you have access to 32bit memory, but only have a 16 bit IP register. So if you try going to real mode with IP set to a 32bit address, it's going to go to the instruction at the address in the lower 16 bits -- explains why you see random instructions being executed.
[edit] just re-read your post and see that the above probably doesn't apply to what you're doing [/edit]
Also, double check the memory map for low memory as there are some restrictions as to where you can load things. Make sure what you're loading fits and doesn't start overriding EBDA and video, etc
http://wiki.osdev.org/Memory_Map_%28x86%29
Re: Real Mode Confusion
I'm probably wrong in saying the program is executing random instructions—bochs switches to mode 13h regardless of what mode I specify. If I don't interrupt 0x10, nothing happens.theseankelly wrote:Not an expert on the topic, but here's a stab at it:
In real mode, you have access to 32bit memory, but only have a 16 bit IP register. So if you try going to real mode with IP set to a 32bit address, it's going to go to the instruction at the address in the lower 16 bits -- explains why you see random instructions being executed.
[edit] just re-read your post and see that the above probably doesn't apply to what you're doing [/edit]
Also, double check the memory map for low memory as there are some restrictions as to where you can load things. Make sure what you're loading fits and doesn't start overriding EBDA and video, etc
http://wiki.osdev.org/Memory_Map_%28x86%29
However, loading at 0x6000 has been the only location which was semi-sucessful (where bochs switched graphics modes, even though I was switching to 40x25 text mode). 0x6000 shouldn't overwrite any memory, but I moved the program down to 0x7E00 just in case. I feel the sp is part of the problem here, and when set to 0x500, the system goes to real mode but doesn't seem to handle interrupts or changing the real mode segment selector. When set to a value like 0x8000, bochs will throw errors—how should I appropriately set sp?
-
- Member
- Posts: 95
- Joined: Thu Jan 29, 2009 9:13 am
Re: Real Mode Confusion
how big is your program? you only have 0x00000 to 0x9FFFF(640KB)
if you go into 0xa0000 and up you may run into problems.
if you go into 0xa0000 and up you may run into problems.
Re: Real Mode Confusion
Returning back to Real Mode involves restoring the complete real mode environment. This includes remapping the PIC to the default real mode vectors, reloading the GDT with 64 kb segment limit and reverting any other hardware changes you made(for example, you may need to restore the Floppy controller to default PIO mode). You didn't mention what you've done so far, so it's hard to tell what's happening with the code.RobertF wrote:- The system will only switch back to real mode if the program's start address is under 0x8000. I thought I was not working with a 1:1 page, but after identity paging the first 0x100000 bytes, I still get the same result.
- Bochs will throw different errors depending on what the start address and what sp is set to after switching to real mode: the closest I've gotten was the start address at 0x6000 and sp at 0x9000. However, any interrupt made to 0x10 after interrupts are restored will switch the VGA mode to 13h under Bochs, and has no result under VirtualBox. I assume this is because it's executing random code.
That's because randomly setting up SP may corrupt the Stack. If your code overwrites the stack, that's the worst you can get to.RobertF wrote:The Real Mode wiki page notes that sp should be set so that the program doesn't interfere with it—this confuses me.
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
Re: Real Mode Confusion
That's absolutely normal behavior in real mode. You have 64k segments, addressed by segment registers. I'm quite sure you didn't set ss, so it's 0, thus creates a memory window at 0-65535. Because offsets are signed values, you can use -32767..+32768 (that is 8000h in hex).
No wonder your code acts strange if you put your stack outside of the window, the pointer will be truncated and you address a different part of memory.
Solutions:
1. put your stack in the window, like before your code at 800h or 600h. It's quite common, although provides a small stack only (which should be more than enough by the way) because 4FFh is BIOS area that should not be messed up. Most boot loaders do this (stack at 800h, growing downwards, code at 800h, growing upwards).
2. set up cs (for your code), ds (for your data) and ss (for the stack), and you'll have 3 different (maybe overlapping) 64k windows.
And read this: http://wiki.osdev.org/Segmentation
No wonder your code acts strange if you put your stack outside of the window, the pointer will be truncated and you address a different part of memory.
Solutions:
1. put your stack in the window, like before your code at 800h or 600h. It's quite common, although provides a small stack only (which should be more than enough by the way) because 4FFh is BIOS area that should not be messed up. Most boot loaders do this (stack at 800h, growing downwards, code at 800h, growing upwards).
2. set up cs (for your code), ds (for your data) and ss (for the stack), and you'll have 3 different (maybe overlapping) 64k windows.
And read this: http://wiki.osdev.org/Segmentation
Re: Real Mode Confusion
No good; putting the stack inside the window still gives me errors (and sometimes I get an invalid opcode interrupt, depending on whether I test it in VirtualBox or Bochs). I've also tried setting up ds and ss (since I read that you can't modify cs, and when I do, bochs complains) for different 64K windows, but that didn't solve the problem either.turdus wrote:That's absolutely normal behavior in real mode. You have 64k segments, addressed by segment registers. I'm quite sure you didn't set ss, so it's 0, thus creates a memory window at 0-65535. Because offsets are signed values, you can use -32767..+32768 (that is 8000h in hex).
No wonder your code acts strange if you put your stack outside of the window, the pointer will be truncated and you address a different part of memory.
Solutions:
1. put your stack in the window, like before your code at 800h or 600h. It's quite common, although provides a small stack only (which should be more than enough by the way) because 4FFh is BIOS area that should not be messed up. Most boot loaders do this (stack at 800h, growing downwards, code at 800h, growing upwards).
2. set up cs (for your code), ds (for your data) and ss (for the stack), and you'll have 3 different (maybe overlapping) 64k windows.
And read this: http://wiki.osdev.org/Segmentation
I've also remapped the PIC to its original offsets like Chandra suggested but that didn't work, either.
Re: Real Mode Confusion
Can you post the related code? We may find something there.RobertF wrote:No good; putting the stack inside the window still gives me errors (and sometimes I get an invalid opcode interrupt, depending on whether I test it in VirtualBox or Bochs). I've also tried setting up ds and ss (since I read that you can't modify cs, and when I do, bochs complains) for different 64K windows, but that didn't solve the problem either.
I've also remapped the PIC to its original offsets like Chandra suggested but that didn't work, either.
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
Re: Real Mode Confusion
Agree with Chandra, show your code. I'm pretty sure you have a bug somewhere that ruins the stack.
In the meanwhile, some reading: http://forum.osdev.org/viewtopic.php?f=1&t=23125
it's a working code example that switches from long to real and back to long again. I know you need prot to real, but you can spot what has to be done (setting idt, turning paging off, remapping pic, loading segment registers etc.)
In the meanwhile, some reading: http://forum.osdev.org/viewtopic.php?f=1&t=23125
it's a working code example that switches from long to real and back to long again. I know you need prot to real, but you can spot what has to be done (setting idt, turning paging off, remapping pic, loading segment registers etc.)
Re: Real Mode Confusion
Code: Select all
[bits 32]
[org 0x7E00]
PMode32:
cli ; disable interrupts
mov eax, cr0
and eax, 0x7FFFFFFF ; clear pg bit
mov cr0, eax
xor eax, eax
mov cr3, eax ; flush TLB
jmp 0x18:PMode16 ; far jump to 16-bit protected mode
[bits 16]
RealIDT:
dw 0x3FF
dd 0
PMode16:
mov ax, 0x20 ; load 16-bit gdt data segment
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
lidt [RealIDT]
mov eax, cr0
and eax, 0xFFFFFFFE ; clear pe bit
mov cr0, eax
jmp 0:RMode ; far jump to real mode
RMode:
mov sp, 0x600
mov ax, 0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
sti
mov ah,0x0
mov al,0x2 ; 40x25 text mode
int 0x10
ret
Re: Real Mode Confusion
Code: Select all
ret
Plain Trouble. The most likely cause of the code failure.RobertF wrote:mov sp, 0x600
Hint: Reserve some static space for the stack.
Code: Select all
lidt [RealIDT]
mov eax, cr0
and eax, 0xFFFFFFFE ; clear pe bit
mov cr0, eax
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
Re: Real Mode Confusion
Hmm, I tried that and now Bochs (and Virtual Box) doesn't seemingly do anything/report any errors, although it's still switching to real mode.Chandra wrote:Plain Trouble. The most likely cause of the code failure.RobertF wrote:mov sp, 0x600
Hint: Reserve some static space for the stack.
What I changed (along with your other suggestions):
Code: Select all
RMode:
mov sp, stack
mov ax, 0
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
mov ss, ax
sti ; now in real mode with proper segments—done
mov ah,0x0
mov al,13h ; 40x25 text mode
int 0x10
[section .bss]
stack:
resb 0x600
-
- Posts: 20
- Joined: Sat Oct 22, 2011 4:17 pm
Re: Real Mode Confusion
I think that since the stack grows downward, what you want is this:RobertF wrote: What I changed (along with your other suggestions):I feel like I'm missing something very very simple here.Code: Select all
RMode: mov sp, stack mov ax, 0 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax sti ; now in real mode with proper segments—done mov ah,0x0 mov al,13h ; 40x25 text mode int 0x10 [section .bss] stack: resb 0x600
Code: Select all
[section .bss]
resb 0x600
stack:
-
- Posts: 20
- Joined: Sat Oct 22, 2011 4:17 pm
Re: Real Mode Confusion
Also I'm a little confused as to why everyone thinks the stack is the problem. I agree it will be eventually, but the code shown that's failing doesn't actually use the stack yet right?
Re: Real Mode Confusion
theseankelly wrote:Also I'm a little confused as to why everyone thinks the stack is the problem. I agree it will be eventually, but the code shown that's failing doesn't actually use the stack yet right?
Code: Select all
int 0x10
Code: Select all
ret
If a trainstation is where trains stop, what is a workstation ?