Page 2 of 2
Re:switching back to real mode from GRUB
Posted: Mon Jun 28, 2004 9:01 pm
by Curufir
EclipseOS wrote:
[ORG 0x10000]
[BITS 32]
...
mov eax, cr0
xor eax, 1
mov cr0, eax
...
jmp word 0x00:real_mode
...
[BITS 16]
real_mode:
This isn't going to work. There might be errors elsewhere, but
this isn't going to work.
The assembler can't take your 32-bit org statement and intelligently create a 16 bit label for a long jump using it. Second problem is that you've turned the PE bit back on. Third problem is that you've shown us nothing to say that 0x0 is actually a 16-bit code descriptor (Which you'll need for the switch back).
Re:switching back to real mode from GRUB
Posted: Tue Jun 29, 2004 12:45 am
by EclipseOS
Okay, well thats why I need help. Everybody keeps telling me what to do, but not how to do it. I have been searching the internet on google and other search engines for a code that will do this for me. I boot my kernel with GRUB which sets up protected mode for me and I don't have a chance to save real mode values to get back into real mode for a graphics switch or a ATX poweroff. So could someone please give me code that actually works? thanx.
Re:switching back to real mode from GRUB
Posted: Tue Jun 29, 2004 4:03 am
by Pype.Clicker
The Mobius can do this. you can find it at mobius.sf.net, iirc ... Explaining
why rather than showing
how is one of the principles of this forum. I cannot show you
how with 100% accuracy as i don't have code that make it, still i can provide you advices that have been helpful for other people ...
This one is redundant. I suggest you take time to figure out how AND, OR, XOR etc. really work before going any further (except if you're already slamming your forhead repeating "how could i have left such an horror").
-- @ schol-r-lea: don't you had a tutorial on these in the General Programming Forum ?
As the "AND eax, 7FFFFFFE" == "AND eax, ~80000001" already switched off the PG and the PE bit, "XOR eax, 00000001" toggles it back to on and so the jmp you take after cannot work ...
Re:switching back to real mode from GRUB
Posted: Tue Jun 29, 2004 1:36 pm
by EclipseOS
Okay, I did some more research and got this code. Sorry for my rudeness before, I was just frustrated at my code.
Here it is:
[BITS 32]
start:
cli
mov eax,cr0
and eax,0x7FFFFFFF
mov cr0,eax
xor eax,eax
mov cr3,eax
jmp 0x0008:prot16
[BITS 16]
prot16:
mov ax,0x0010
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov ax,0x03FF
mov [newidt],ax
xor ax,ax
mov [newidt+2],ax
mov [newidt+4],ax
lidt [newidt]
mov eax,cr0
and eax,0xFFFFFFFE
mov cr0,eax
jmp dword 0x0000:real16
real16:
xor ax,ax
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
sti
mov ax,5304h
sub bx,bx
int 15h
mov ax,5301h
sub bx,bx
int 15h
mov ax,5308h
mov bx,1
mov cx,bx
int 15h
mov ax,530Dh
mov bx,1
mov cx,bx
int 15h
mov ax,530Fh
mov bx,1
mov cx,bx
int 15h
mov ax,530Eh
sub bx,bx
mov cx,102h
int 15h
mov ax,5307h
mov bx,1
mov cx,3
int 15h
My only problem is the place I got the code from didn't specify what newidt is. What is newidt? thanx.
Re:switching back to real mode from GRUB
Posted: Tue Jun 29, 2004 2:41 pm
by Pype.Clicker
EclipseOS wrote:
My only problem is the place I got the code from didn't specify what newidt is. What is newidt? thanx.
that shouldn't really matter as long as its some memory you can access through the descriptor 0x10 as read/write data.
Note that obviously, this code assume that 0x08 and 0x10 will be 16 bits code and data segments while most of us use them as the *32bits* segments. make sure it is consistent with your environment.
Re:switching back to real mode from GRUB
Posted: Tue Jun 29, 2004 3:28 pm
by EclipseOS
Question 1. Would 0x1000 work for newidt?
Qyestion 2. What would be a 16-bit descriptor if mine are not?
thanx
Re:switching back to real mode from GRUB
Posted: Tue Jun 29, 2004 4:47 pm
by Pype.Clicker
i didn't said yours were not. So far you're the only one to know as only you know what's in your GDT.
0x1000 could be a nice newidt, if you have nothing else there.
Re:switching back to real mode from GRUB
Posted: Tue Jun 29, 2004 6:46 pm
by EclipseOS
Well I compiled and ran my code and my OS picked it up as an "Invalid Opcode". I don't understand why this code isn't working, I got it from a guy who said he used it before. I didn't setup my GDT or IDT, I am using GRUB which sets all that up and I have no way of changing it. Thanx
Re:switching back to real mode from GRUB
Posted: Tue Jun 29, 2004 9:15 pm
by Curufir
So just setup your own GDT with some 16-bit code/data selectors. The multiboot specification (AFAIK) actually says that you should setup your own GDT as soon as possible and not rely on the one from GRUB.
Re:switching back to real mode from GRUB
Posted: Wed Jun 30, 2004 1:33 am
by Pype.Clicker
when executing [bits 16] with a 32 bits code selector, some operations will be mis-interpreted as arguments for the previous instruction
will be read as
no need to say "invalid opcodes" are *very* likely to occur in such conditions
Re:switching back to real mode from GRUB
Posted: Wed Jun 30, 2004 9:54 pm
by EclipseOS
Should this code work correctly?
Codestart
----------------------------------------------------------
[BITS 32]
; See IA-32 Dev vol 3 sec 8.9.2 & 1 for explanation of steps mentioned below
cli ; 8.9.2. Step 1.
mov eax,cr0 ; 8.9.2. Step 2.
and eax,0x7FFFFFFF
mov cr0,eax
xor eax,eax
mov cr3,eax
jmp 0x007:prot16 ; 8.9.2. Step 3.
[BITS 16]
prot16:
mov ax,0x0010 ; 8.9.2. Step 4.
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov ax,0x03FF ; 8.9.2. Step 5.
mov [newidt],ax
xor ax,ax
mov [newidt+2],ax
mov [newidt+4],ax
lidt [newidt]
mov eax,cr0 ; 8.9.2. Step 6.
and eax,0xFFFFFFFE
mov cr0,eax
jmp dword 0x0000:real16 ; 8.9.2. Step 7.
real16:
xor ax,ax ; 8.9.2. Step 8.
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
sti ; 8.9.2. Step 9.
newidt equ 0x632
---------------------------------------------------------
Code end.
Please could someone try it and see if they can get it to work for them because it sure doesn't seem to be working for me.
Thanx.
Re:switching back to real mode from GRUB
Posted: Thu Jul 01, 2004 1:14 am
by Brendan
Hi,
EclipseOS wrote:
Should this code work correctly?
Please could someone try it and see if they can get it to work for them because it sure doesn't seem to be working for me.
I didn't try it, but you'd need to set up a real mode stack before enabling interrupts. Also you'd have to make sure that the state of every device in the computer is the same as what the BIOS is expecting.
Cheers,
Brendan