Page 1 of 2

switching back to real mode from GRUB

Posted: Sun Jun 06, 2004 2:32 pm
by EclipseOS
Hey can anyopne tell me how I can get back into real mode? I'm booting my kernel with GRUB. I tried to write a code from other threads in this forum here's my code:

[global _atx_halt]

_atx_halt:

[BITS 32]

cli

mov eax, cr0
xor eax, 0x80000000
mov cr0, eax

xor eax, eax
mov cr3, eax

mov eax, cr0
xor eax, 1
mov cr0, eax

jmp word 0x00:real_mode

[BITS 16]

real_mode:

xor ax,ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

mov ax, 0x9000
mov ss, ax
mov esp, 0x8000

I tried to link this code and ld says:

atx_halt.o(.text+0x1e): relocation truncated to fit: 16 text

I've tried everything to get rid of this but nothing helps. Is there somthing wrong with my code? Thanx.

Re:switching back to real mode from GRUB

Posted: Thu Jun 10, 2004 9:09 pm
by GT
I believe the problem is with GNU ld's inability to link 16 bit code. In my own pet OS, I assemble my protected->real mode code into a flat-form binary file rather than an ELF file ("realmode.bin", not "realmode.o"), then have the kernel copy those bytes into lower memory (your prot->real code can't be located above 1MB or it'll crash during execution).

Re:switching back to real mode from GRUB

Posted: Fri Jun 11, 2004 12:37 am
by Candy
GT wrote: I believe the problem is with GNU ld's inability to link 16 bit code. In my own pet OS, I assemble my protected->real mode code into a flat-form binary file rather than an ELF file ("realmode.bin", not "realmode.o"), then have the kernel copy those bytes into lower memory (your prot->real code can't be located above 1MB or it'll crash during execution).
There is no problem with LD linking 16-bit code.

*BUT* LD can't handle segments. This means that if your code is below 64k, it works without a warning. If it's above, you get a warning because you can't keep any of the first four bits. This also gives a problem when you use a non-0 base.

If your segment base & 0xFFF == 0x000, then the linking still works (the bits are stripped off, but your segment base copes for that). If it isn't, you got a problem and LD can't handle it.

Re:switching back to real mode from GRUB

Posted: Mon Jun 14, 2004 3:25 pm
by EclipseOS
What would I do to my code to keep it below 64kb? Please modify my code to work. Thanx

Re:switching back to real mode from GRUB

Posted: Tue Jun 15, 2004 1:53 am
by Pype.Clicker
* write your 'shutdown' function as an independent .asm file, that will have (for instance) [tt]ORG 0x10000[/tt] and can be called by jumping its first byte
* assemble it as a standalone binary file
* include it in your kernel as raw bytes (for instance using the incbin directive of nasm)
* when time comes to shut down, copy the bytes towards 0x10000 and jump there

Re:switching back to real mode from GRUB

Posted: Mon Jun 28, 2004 1:10 pm
by EclipseOS
Okay here's what I've got:

shutdown1.asm
------------------------
[global _shutdown]

_shutdown:
incbin "shutdown.bin"
------------------------
end shutdown1.asm

shutdown.asm
------------------------
[BITS 32]

cli

mov eax, cr0
xor eax, 0x80000000
mov cr0, eax

xor eax, eax
mov cr3, eax

mov eax, cr0
xor eax, 1
mov cr0, eax

jmp word 0x00:real_mode

[BITS 16]

real_mode:

xor ax,ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

mov ax, 0x9000
mov ss, ax
mov esp, 0x8000
ect......
------------------------
end shutdown.asm


I call _shutdown in my main.cpp like:

extern "C" void shutdown();

and it still doesn't work, bochs gives me:

[CPU ] prefetch: running in bogus memory

This is driving me crazy, what am I doing wrong!
please help me.

Re:switching back to real mode from GRUB

Posted: Mon Jun 28, 2004 1:21 pm
by DennisCGc
It looks like you're running it over your specified memory.
I mean if you have this:

Code: Select all

megs: 10
You're running the code over > 10 MB...

Re:switching back to real mode from GRUB

Posted: Mon Jun 28, 2004 1:29 pm
by Pype.Clicker
no. The 'bogus memory' thing is just coming from the fact you're running code from a memory page that has never been written to.

That being said, make sure the code you're running is 1:1 mapped if you don't want to have bad surprises when disabling paging ...

Re:switching back to real mode from GRUB

Posted: Mon Jun 28, 2004 1:58 pm
by DennisCGc
Pype.Clicker wrote: no. The 'bogus memory' thing is just coming from the fact you're running code from a memory page that has never been written to.

That being said, make sure the code you're running is 1:1 mapped if you don't want to have bad surprises when disabling paging ...
If I get that, I'm running it over the megs parameter

Re:switching back to real mode from GRUB

Posted: Mon Jun 28, 2004 2:03 pm
by EclipseOS
So whats wrong with my code? How do I fix it and keep it within memory range?

Thanx

Re:switching back to real mode from GRUB

Posted: Mon Jun 28, 2004 2:18 pm
by EclipseOS
I made these changes:

from:

mov eax, cr0
xor eax, 0x80000000
mov cr0, eax

to:

mov eax, cr0
xor eax, 0
mov cr0, eax

and my kernel freezes and bochs says:

00071760133i[CPU ] BxError: instruction with op1=0xfe
00071760133i[CPU ] nnn was 4
00071760133i[CPU ] WARNING: Encountered an unknown instruction (signalling illegal instruction):
00072114595i[CPU ] BxError: instruction with op1=0xff
00072114595i[CPU ] nnn was 7
00072114595i[CPU ] WARNING: Encountered an unknown instruction (signalling illegal instruction):

whats wrong now?

Re:switching back to real mode from GRUB

Posted: Mon Jun 28, 2004 2:46 pm
by Pype.Clicker
1 xor 0 == 1
0 xor 0 == 0

so having cr0 := cr0 XOR cr0 is simply useless ... In order to clear both 'PG' and 'PE' flags from CR0, proper code is

Code: Select all

mov eax,cr0
and eax, 7FFFFFFE
mov cr0,eax

Re:switching back to real mode from GRUB

Posted: Mon Jun 28, 2004 2:54 pm
by EclipseOS
Nasm won't accept that code, it says:

error: expression syntax error

thanx

Re:switching back to real mode from GRUB

Posted: Mon Jun 28, 2004 3:12 pm
by Curufir

Code: Select all

and eax, 7FFFFFFE
0x7FFFFFFE or 7FFFFFFEh

Re:switching back to real mode from GRUB

Posted: Mon Jun 28, 2004 3:17 pm
by EclipseOS
I changed that and now bochs says:

[CPU ] jump_protected: cs = 0

my shutdown.asm is:

[ORG 0x10000]
[BITS 32]

cli
mov eax,cr0
and eax, 7FFFFFFEh
mov cr0,eax

xor eax, eax
mov cr3, eax

mov eax, cr0
xor eax, 1
mov cr0, eax

jmp word 0x00:real_mode

[BITS 16]

real_mode:

xor ax,ax
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax

mov ax, 0x9000
mov ss, ax
mov esp, 0x8000
sti
mov ax,5304h ; disconnect interface
sub bx,bx
int 15h

mov ax,5301h ; connect real mode interface
sub bx,bx
int 15h

mov ax,5308h ; enable power management
mov bx,1
mov cx,bx
int 15h

mov ax,530Dh ; enable device power management
mov bx,1
mov cx,bx
int 15h

mov ax,530Fh ; engage power management
mov bx,1
mov cx,bx
int 15h

mov ax,530Eh ; driver version
sub bx,bx
mov cx,102h
int 15h

mov ax,5307h ; set power state
mov bx,1
mov cx,3
int 15h