switching back to real mode from GRUB

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
EclipseOS

switching back to real mode from GRUB

Post 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.
GT

Re:switching back to real mode from GRUB

Post 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).
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re:switching back to real mode from GRUB

Post 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.
EclipseOS

Re:switching back to real mode from GRUB

Post by EclipseOS »

What would I do to my code to keep it below 64kb? Please modify my code to work. Thanx
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:switching back to real mode from GRUB

Post 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
EclipseOS

Re:switching back to real mode from GRUB

Post 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.
DennisCGc

Re:switching back to real mode from GRUB

Post 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...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:switching back to real mode from GRUB

Post 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 ...
DennisCGc

Re:switching back to real mode from GRUB

Post 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
EclipseOS

Re:switching back to real mode from GRUB

Post by EclipseOS »

So whats wrong with my code? How do I fix it and keep it within memory range?

Thanx
EclipseOS

Re:switching back to real mode from GRUB

Post 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?
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:switching back to real mode from GRUB

Post 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
EclipseOS

Re:switching back to real mode from GRUB

Post by EclipseOS »

Nasm won't accept that code, it says:

error: expression syntax error

thanx
Curufir

Re:switching back to real mode from GRUB

Post by Curufir »

Code: Select all

and eax, 7FFFFFFE
0x7FFFFFFE or 7FFFFFFEh
EclipseOS

Re:switching back to real mode from GRUB

Post 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
Post Reply