Page 2 of 3

Posted: Wed Nov 15, 2006 4:50 pm
by Phoenix
Combuster wrote: Setting PE in CR0 will immediately cause an entry to protected mode,
NO, It wont.
Please make a test and read manuals !
If you don't change CS, you are in real mode. It doesn't matter PE bit in cr0

This is in pmode
mov eax,cr0
or eax,1
mov cr0,eax
jmp far 08h:main32 ;08 code segment
main32:

BUT This is NOT !
mov eax,cr0
or eax,1
mov cr0,eax


If you want a sample, here take one
http://www.nondot.org/sabre/os/files/Pr ... voodoo.asm

Posted: Wed Nov 15, 2006 5:15 pm
by Combuster
Proof: A CPU dump after mov CR0 without a jump.

Code: Select all

00006786385i[     ] dbg: Quit
00006786385i[CPU0 ] protected mode
00006786385i[CPU0 ] CS.d_b = 16 bit
00006786385i[CPU0 ] SS.d_b = 16 bit
00006786385i[CPU0 ] | EAX=00000008  EBX=0001046a  ECX=00000607  EDX=00020000
00006786385i[CPU0 ] | ESP=0000fffe  EBP=00000000  ESI=4d490200  EDI=00000475
00006786385i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af PF cf
00006786385i[CPU0 ] | SEG selector     base    limit G D
00006786385i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00006786385i[CPU0 ] |  CS:1000( 1e00| 0|  0) 00010000 0000ffff 0 0
00006786385i[CPU0 ] |  DS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00006786385i[CPU0 ] |  SS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00006786385i[CPU0 ] |  ES:1000( 0000| 0|  0) 00010000 0000ffff 0 0
00006786385i[CPU0 ] |  FS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00006786385i[CPU0 ] |  GS:ffff( 0000| 0|  0) 000ffff0 0000ffff 0 0
00006786385i[CPU0 ] | EIP=00000155 (00000155)
00006786385i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00006786385i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00006786385i[CPU0 ] >> mov es, ax : 8EC0
00006786385i[SYS  ] Last time is 1163631660
Source:

Code: Select all

                MOV CR0, EAX
                MOV AX, gdtKDataSel
                MOV DS, AX
                MOV ES, AX
                MOV FS, AX
                MOV GS, AX
                MOV SS, AX
Notice that the limit of DS has been set to fffff, page granular - it wouldnt have done so if we wouldnt be in protected mode.
If i'd clear the PE bit at this point (instead of the rest of the initialization that follows right now), i'd be in unreal mode.

In case you wonder, this is from a real bootloader, it does not use undocumented stuff, and it works on all computers i've tested so far.

Besides, all the protected mode tutorials i've seen dont require any jump to get to unreal mode. And even that works on all computers i tested it on.
The jump is only required to enter 32-bit protected mode.

So setting PE in CR0 will immediately get you into protected mode: TRUE

Posted: Wed Nov 15, 2006 9:17 pm
by nitinjavakid

Code: Select all

00006786385i[     ] dbg: Quit
00006786385i[CPU0 ] protected mode
00006786385i[CPU0 ] CS.d_b = 16 bit
00006786385i[CPU0 ] SS.d_b = 16 bit
00006786385i[CPU0 ] | EAX=00000008  EBX=0001046a  ECX=00000607  EDX=00020000
00006786385i[CPU0 ] | ESP=0000fffe  EBP=00000000  ESI=4d490200  EDI=00000475
00006786385i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf zf af PF cf
00006786385i[CPU0 ] | SEG selector     base    limit G D
00006786385i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00006786385i[CPU0 ] |  CS:1000( 1e00| 0|  0) 00010000 0000ffff 0 0
00006786385i[CPU0 ] |  DS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00006786385i[CPU0 ] |  SS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00006786385i[CPU0 ] |  ES:1000( 0000| 0|  0) 00010000 0000ffff 0 0
00006786385i[CPU0 ] |  FS:0000( 0000| 0|  0) 00000000 0000ffff 0 0
00006786385i[CPU0 ] |  GS:ffff( 0000| 0|  0) 000ffff0 0000ffff 0 0
00006786385i[CPU0 ] | EIP=00000155 (00000155)
00006786385i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00006786385i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00006786385i[CPU0 ] >> mov es, ax : 8EC0
00006786385i[SYS  ] Last time is 1163631660
Combuster, from where did you get that useful information. Can you tell me the procedure of getting that please?

Also, it works with 0xB8000 without changing the video mode. Only problem is it isnt working for VESA ?

Posted: Thu Nov 16, 2006 1:44 am
by Combuster
This comes from Bochs - its an emulator. You can not do that easily with VMWare. What i did is find the location of the mov cr0 in the output file, then tell bochs to stop there so i can step through it and check if everything is functioning properly.

That said, i use bochs for my daily os development, and i generally only test other machines after bochs runs everything perfectly

Yesterdays debugging session: (slightly edited for readability)

Code: Select all

bochsdbg -q -f mos3-windows.conf    ; start bochs with debugger for my os

(...)

<bochs:1> lb 0x10000                ; set a brakepoint for 0x1000:0000, where the stage 2 bootloader is located
<bochs:2> c                         ; continue execution for now

(...)

(0) [0x00010000] 1000:0000 (unk. ctxt): jmp .+0x0003 (0x00010006) ; e90300
<bochs:4> x /h 0x10004              ; read a (half)word 4 bytes from the beginning of the file
[bochs]:                            ; i put a copy of the address to break here  
0x00010004 <bogus+       0>:    0x014d          ; this is where to stop
<bochs:5> lb 0x1014d                ; set another breakpoint at 1000:014d
<bochs:6> c                         ; and run to it
(0) Breakpoint 2, 0x0001014d in ?? ()
Next at t=6786382
(0) [0x0001014d] 1000:014d (unk. ctxt): mov cr0, eax              ; 0f22c0

(...)

<bochs:10> d 2                      ; delete breakpoint 2 (i cant step)
<bochs:11> s                        ; bochs wouldnt let me continue else
Next at t=6786383
(0) [0x00010150] 1000:00000150 (unk. ctxt): mov ax, 0x0008            ; b80800
<bochs:12> dump_cpu                 ; this is one instruction after mov cr0, dump processor
eax:0x00000011, ebx:0x0001046a, ecx:0x00000607, edx:0x00020000
ebp:0x00000000, esp:0x0000fffe, esi:0x4d490200, edi:0x00000475
eip:0x00000150, eflags:0x00000006, inhibit_mask:0
cs:s=0x1000, dl=0x0000ffff, dh=0x00009b01, valid=1
ss:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=7
ds:s=0x1000, dl=0x0000ffff, dh=0x00009301, valid=5
es:s=0x1000, dl=0x0000ffff, dh=0x00009301, valid=1
fs:s=0x0000, dl=0x0000ffff, dh=0x00009300, valid=3
gs:s=0xffff, dl=0xfff0ffff, dh=0x0000930f, valid=3
ldtr:s=0x0000, dl=0x0000ffff, dh=0x00008200, valid=1
tr:s=0x0000, dl=0x0000ffff, dh=0x00008300, valid=1
gdtr:base=0x0001053f, limit=0x18
idtr:base=0x00000000, limit=0xffff
dr0:0x00000000, dr1:0x00000000, dr2:0x00000000
dr3:0x00000000, dr6:0xffff0ff0, dr7:0x00000400
cr0:0x00000011, cr1:0x00000000, cr2:0x00000000
cr3:0x00000000, cr4:0x00000000
shame the better readable version of this output comes when you quit the emulator.

back to topic: since you are in unreal mode, the problem has something to do with you getting the lfb, or with vmware setting it. You could enter graphics mode, get the pointer, return to text mode then print the pointers address and see if it makes sense.

Posted: Thu Nov 16, 2006 1:59 am
by nitinjavakid
Thanks a lot. One thing is clear now. "VMWare is buggy".
First, comment out the "mov [ds:edx],bx" instruction and see if those grey dots disappear. If they do, then the screen is being cleared. If they're still there then you've probably got a buggy emulator.
Yup those dots disappear in Bochs(This thing rocks).

Here are the results.

That dot is still not there although the screen is cleared. :(

Posted: Thu Nov 16, 2006 3:13 am
by Phoenix
Combuster, I understand your concern, but there is facts too.
I will write as soon as posible a working example of this unreal vesa thing and I hope we will see the problem.

[quote="Combuster"]Proof: A CPU dump after mov CR0 without a jump.

Code: Select all

00006786385i[CPU0 ] |  CS:1000( 1e00| 0|  0) 00010000 0000ffff 0 0
Well, but this is pointless. If we are pmode, how could it be CS a real mode segment ??? :)

Probably, bochs's fault

Posted: Thu Nov 16, 2006 4:10 am
by Combuster
You didnt get the point, did you?

Protected mode is about how instructions are executed, NOT the values that happen to be in some of the registers.

I could for instance write a GDT with a 64k code segment at 0x10000 at that index and you wouldnt be able to see the difference.

Unreal mode works without a jump, javakid just showed it works that way on both vmware and bochs, i know it works on real machines that way, my OS depends on this behaviour, and you didnt give any arguments of yourself and i'm pretty certain you wont find the proof for it.

I suggest you read http://ringzero.free.fr/os/protected%20mode/Pm/PM5.ASM, which is about where i started with os assembly

[edit:]From AMD's "Big Book of Patterns":
After the protected-mode data structures are initialized, system software must load the IDTR and
GDTR (and optionally, the LDTR and TR) with pointers to those data structures. Once these registers
are initialized, protected mode can be enabled by setting CR0.PE to 1.
[/edit]

Posted: Thu Nov 16, 2006 7:50 am
by nitinjavakid
Ok lets skip the Unreal part for now. In protected, the result is the same(blank screen) :roll:

Posted: Thu Nov 16, 2006 9:47 am
by JAAman
Phoenix wrote:
Combuster wrote: Setting PE in CR0 will immediately cause an entry to protected mode,
NO, It wont.
Please make a test and read manuals !
If you don't change CS, you are in real mode. It doesn't matter PE bit in cr0

This is in pmode
mov eax,cr0
or eax,1
mov cr0,eax
jmp far 08h:main32 ;08 code segment
main32:

BUT This is NOT !
mov eax,cr0
or eax,1
mov cr0,eax

the intel manuals are very clear (check section 2.5)

immediately when you activate the PE bit you are in PMode -- before the switch, your CS hidden portion is duplicated from the internal GDT which the CPU uses in RMode, which is: 16bit, 64k length, base = 0x10*CS, ring 0
this is exactly why UMode works

the only reason you would ever need to do a jump upon entering PMode, is to change to 32bit, or enlarge the segment (or change the base)

even in RMode, every time the segment selectors are loaded, the hidden portion is loaded from the GDT, but in RMode it is redirected to an internal table, instead of the normal GDT pointer


2)Switch back to real mode
Now your TLBs were filled and you will be unreal mode...
(P.S.: And ofcourse only clearing 0.bit of cr0 doesn't make any changes, you must change CS too)
also untrue:
you are in RMode -- even if it is 32bit, 4GB length, base=0 RMode
it is still RMode (although if your segment is not 16bit/64k/base = 0x10*CS you should change it -- because the first interrupt or call will trash the current state, and on ret/iret it will resume executing in invalid memory (and the TLBs are never filled with anything unless paging is enabled)


i recommend rereading intel manuals volume3, chapter 2&3

section 9.9.1 is a little misleading, and prob where your getting that information:

1) the book assumes you want 32bit PMode
2) the book assumes you care if the instructions are translated improperly on the P5

the warning about steps 3&4 refer to the P5 -- the translation engine wouldnt know that it was in PMode until after the mov had been completed, and would therefore occasionally translate them improperly, an absolute jump, would clear the instruction cache and pipeline, and force all instructions to be reloaded and retranslated -- however, absolute jumps are now executed by the prefetch engine (rather than the execution core) and only reloaded if the GDT was altered between the prefetch and the execution of the jump, and translation engine is notified of the switch, so no manual clearing is necessary -- if you were going to stay in PMode, you should probably switch to 32bit 0-based segment anyway, and if your not, then it doesnt matter (for setting up UMode, it is unnecessary)

Posted: Thu Nov 16, 2006 11:37 am
by nitinjavakid
Please dont confuse me further friends :? Already VESA has confused me to a lot extent with blank screens :roll:

Brendan:
Let me know how it goes, and depending on results there might be some VGA registers to play....
Brendan, what has to be done with the VGA registers?

Posted: Thu Nov 16, 2006 11:57 am
by Brendan
Hi,
nitinjavakid wrote:
Let me know how it goes, and depending on results there might be some VGA registers to play....
Brendan, what has to be done with the VGA registers?
Ah - sorry... When I wrote that I was thinking you were trying to use a 16 colour mode, rather than a 16-bit colour mode. For 16-bit colour modes, you shouldn't need to change any I/O ports for LFB.

To be honest, I've been quiet because I can't find anything actually wrong with your code (assuming that the mode is supported). I'll do a quick cut & paste and run it through Bochs - see if I can find something wrong that way... :)


Cheers,

Brendan

Posted: Thu Nov 16, 2006 12:21 pm
by nitinjavakid
Thanks for putting in efforts to solve the problem.

Posted: Thu Nov 16, 2006 12:25 pm
by Brendan
Hi,

Found it!

Ok, this line:

Code: Select all

flatdesc    db 0xff, 0xff, 0, 0, 0, 10010010b, 01001111b, 0
Needs to change to something like this:

Code: Select all

flatdesc    db 0xff, 0xff, 0, 0, 0, 10010010b, 10001111b, 0
Can you see the difference? ;)

The original version had the "granularity" bit clear and the "big" flag set. This means that the limit is 0x100000 bytes (not 0x100000 pages). The "big" flag is only used for code segments (determines if the it's for 16-bit code or 32-bit code), for stack segments (determines if the stack is 16-bit or 32-bit) and for "expand down segments" (don't ask - I've never seen anyone use them and there's strange rules for what happens to the base and limit).

The end result was that DS had a 64 KB limit, and the "mov word [ds:edx], bx" caused a general protection fault (trying to access past the segment limit). Because you're in real mode the general protection fault handler is in the BIOS, and does nothing (probably returns with the carry flag set), which causes the same "mov word [ds:edx], bx" instruction to try again. This makes an infinite loop of general protection faults...

I had a thought about those grey dots too - does the general protection fault handler in VMware try to display some sort of text string to let you know the computer crashed? I'd guess it does, and I'd also guess VMWare thought you were in text mode still. :)


[EDIT: I was wrong above - for the original version, DS would have had a 1 MB limit, not a 64 KB limit...[/edit]


Cheers,

Brendan

Posted: Thu Nov 16, 2006 12:51 pm
by nitinjavakid
No idea about VMware. But I will stick to bochs as it has better debugging facilities.

Ok so big bit was not set because we were still in 16bit mode and that granuality was set so that we have access to 4gb right?

Thanks a lot dude! Great help
=D> =D> =D> =D> =D>

Posted: Thu Nov 16, 2006 1:04 pm
by nitinjavakid
:roll: VMware still shows the grey dots even after getting the fixing gdt. With bochs it works fine. :)