switching back to real mode from GRUB
switching back to real mode from GRUB
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.
[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
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
There is no problem with LD linking 16-bit code.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).
*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
What would I do to my code to keep it below 64kb? Please modify my code to work. Thanx
- Pype.Clicker
- 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
* 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
* 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
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.
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
It looks like you're running it over your specified memory.
I mean if you have this:
You're running the code over > 10 MB...
I mean if you have this:
Code: Select all
megs: 10
- Pype.Clicker
- 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
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 ...
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
If I get that, I'm running it over the megs parameterPype.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 ...
Re:switching back to real mode from GRUB
So whats wrong with my code? How do I fix it and keep it within memory range?
Thanx
Thanx
Re:switching back to real mode from GRUB
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?
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?
- Pype.Clicker
- 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
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
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
Nasm won't accept that code, it says:
error: expression syntax error
thanx
error: expression syntax error
thanx
Re:switching back to real mode from GRUB
Code: Select all
and eax, 7FFFFFFE
Re:switching back to real mode from GRUB
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
[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