Help with activating pmode

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.
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Post by tadada »

Sorry about that. If I use the code shown to print a "P" on a purple background it works in Real Monde only. When I try to use it in Protected Mode it doesn't work.

Code: Select all

mov ax,0xb800 
mov es,ax 
mov word [es:0],0x5050
My OS: SOS (Simple Operating System).
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Post by neon »

Try this instead:

Code: Select all

mov ebx,0xb8000
mov byte [ebx],'A'
mov byte [ebx+1], 1
This prints a blue 'A' character on the upper left corner of display. This assumes that DS contains the correct data descriptor. Not doing so will result in #GPF.

Remember that protected mode does NOT use segment:offset addressing as in real mode. It uses desc:linear, where desc is the offset in your GDT (Code descriptor, data descriptor, et al..); while linear is a 32 bit linear address.

Looking at the code you posted, you set ES to 0 (Null selector). Referencing any data using ES will generate a #GPF.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
DrLink
Member
Member
Posts: 25
Joined: Wed May 21, 2008 6:10 pm
Contact:

Post by DrLink »

I think you can use to copy it to a disk in Linux

dd if=./floppy.img of=/dev/fd0

If that doesn't work, re-build the floppy image and try reversing the if= and of= parameters.
svdmeer
Member
Member
Posts: 87
Joined: Tue May 06, 2008 9:32 am
Location: The Netherlands

Post by svdmeer »

tadada wrote:Sorry about that. If I use the code shown to print a "P" on a purple background it works in Real Monde only. When I try to use it in Protected Mode it doesn't work.

Code: Select all

mov ax,0xb800 
mov es,ax 
mov word [es:0],0x5050
True.

In protectedmode you need only mov word [es:0xb8000],0x5050
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Would you try running the program in bochs' debugger. Stop it at the mov [0xb8000], 0x5050, close it and post the resulting logfile.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Post by tadada »

I have two files:

OSDEV.log (the log. Big. 7.25 MBs. had to use a link it said the file was empty...)
http://www.mediafire.com/?nmyfuuxxbxr

Error.txt (The last thing on the Bochs debug console.)

In the Log I saw this which I thought was interesting:

00002643656d[KBD ] keyboard: 8-bit write to 0064 = ad
00002643656d[KBD ] keyboard disabled
00002643663d[KBD ] keyboard: 8-bit write to 0064 = d0
00002643663d[KBD ] io write to port 64h, command d0h (partial)
00002643663d[KBD ] controller_enQ(03) source=00
00002643669d[IOAP ] set_irq_level(): INTIN1: level=0
00002643669d[KBD ] READ(60) = 03
00002643677d[KBD ] keyboard: 8-bit write to 0064 = d1
00002643677d[KBD ] write output port
00002643685d[KBD ] keyboard: 8-bit write to 0060 = 03
00002643685d[KBD ] write output port with value 03h
00002643685d[KBD ] write output port : enable A20
00002643685d[SYS ] A20: set() = 1
00002643692d[KBD ] keyboard: 8-bit write to 0064 = ae
00002643692d[KBD ] keyboard enabled
00002643700d[CPU0 ] BxError: i with opcode=0xff
00002643700d[CPU0 ] mod was c0, nnn was 7, rm was 7
00002643700d[CPU0 ] WARNING: Encountered an unknown i (signalling illegal i)
00002643700d[CPU0 ] UndefinedOpcode: 0xff causes exception 6
00002643700d[CPU0 ] exception(0x06): error_code=0000
00002643700d[CPU0 ] interrupt(): vector = 6, INT = 0, EXT = 1

If I understood it correctly it activated A20 and then hit an error. This would mean that the loading pmode problem was never fixed and that would exsplain why it never printed.
Attachments
ERROR.txt
The error file
(110 Bytes) Downloaded 16 times
My OS: SOS (Simple Operating System).
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Post by neon »

Post your current code, in full if it is not too large.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
kmtdk
Member
Member
Posts: 263
Joined: Sat May 17, 2008 4:05 am
Location: Cyperspace, Denmark
Contact:

Post by kmtdk »

As neon said, we need to see the current code, or else we cant find the error.
for me it looks like a BIG loop- everything is reapeaded


KMT
well, what to say, to much to do in too little space.
when it goes up hill, increase work, when it goes straight, test yourself but when going down, slow down.
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Post by tadada »

I posted everything as one file but normally the GDT is in its own file, enable pmode is in its own file, and enable A20 is in its own file. (.inc files) during assembly I have nasm load them into the kernel as one file using this: %include <file name>

Other then the fact that everything is in one file it is the same as my current kernel.

I thought of something. No matter what on shutdown bochs prints out the register values. So in that thinking I can test how far it gets by putting a value in a register at certain points. The further it gets the higher the value goes. The question here is this: Can I use 64 bit registers even though I'm in 32 bit? If so I would use register R8, It is unused by my OS so is a perfect canidate. If I can't I will use register ebp because it is unused so far.
Attachments
KERNEL_.asm.txt
The kernel
(3.24 KiB) Downloaded 58 times
My OS: SOS (Simple Operating System).
Martijn
Posts: 22
Joined: Tue Feb 26, 2008 3:43 am
Location: The Netherlands

Post by Martijn »

A few bugs i found so far:
1. 'bits 32' must appear after your far jump to 'Kernel'.
2. Your far jump to 'Kernel' must have the linear address of 'Kernel' as its offset.
3. There is no linear address to the gdt in your gdt_ptr.
Last edited by Martijn on Tue May 27, 2008 4:04 pm, edited 1 time in total.
User avatar
JAAman
Member
Member
Posts: 879
Joined: Wed Oct 27, 2004 11:00 pm
Location: WA

Post by JAAman »

The question here is this: Can I use 64 bit registers even though I'm in 32 bit?
no, you cant -- to use the 64bit registers, requires removing existing instructions to turn them into prefixes -- which makes it incompatible with 16/32 bit software (the same is not true for 32bit registers, therefore those work in 16bit modes, but 64bit registers cannot work in 16/32bit modes)

while most code can run unaltered in 64bit mode, not all can, which is why there is a 32bit LMode
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Post by tadada »

ok I think I got somewhere. Now it says that it indeed loads the GDT and activates pmode. The problem is now with the jump to my kernel.

The exact log:
  • 00001796618i[BIOS ] Booting from 0000:7c00
    00002626616e[CPU0 ] fetch_raw_descriptor: GDT: index (f)1 > limit (0)
    00002626616i[CPU0 ] CPU is in protected mode (active)
    00002626616i[CPU0 ] CS.d_b = 16 bit
    00002626616i[CPU0 ] SS.d_b = 16 bit

    ; few lines later

    00002626616i[CPU0 ] >> jmp far 0008:0587 : EA87050800
    00002626616e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
I don't understand the error but I'm sure that I can find some Boch docs that exsplain what it means. (hafta look tomorrow though)
My OS: SOS (Simple Operating System).
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Post by neon »

You are getting a General Protection Fault (#GPF) exception. I can't help much without looking at your current code though..
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
tadada
Member
Member
Posts: 42
Joined: Sun Apr 20, 2008 5:32 pm
Location: Index 0 of the nearest Array

Post by tadada »

I was running through everything in the debugger again and I come to the far jump. When it far jumps it goes to 0008:0587 (EA87050800) but right after it far jumps again. (wrong) If it jumps correctly then it should jump once and then set ds, ss, and es to 0x10. (shouldn't that be to GDT entries that correspond to something more... correct? like for SS to where I want the stack to be and for ds the data entry in the GDT? ES being "extra segment" I believe can be to where I chose though...) I think the second jump might be from the fact that it is loaded into 0x500 BUT is ORG [0x000]. Can someone verify whether that could cause the problem or not?
My OS: SOS (Simple Operating System).
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Post by neon »

ss,es,ds,gs,fs all should contain the data segment selector offset in your GDT. Normally its usually at offset 0x10. It depends on your GDT though.

As for the second far jump, where does it jump to? Does it set CS to anything besides your 0x8? If it does, then that very well can be the cause of your #GPF.
ES being "extra segment" I believe can be to where I chose though...
As long as its a valid descriptor offset in your GDT, then yes. If not, it will #GPF as soon as you use it.
I think the second jump might be from the fact that it is loaded into 0x500 BUT is ORG [0x000].
Wait... 0x500? What is loaded at 0x500? Your kernel?
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
Post Reply