Page 3 of 3

Re: Unreal mode

Posted: Mon Nov 16, 2009 1:18 pm
by qw
Firestryke31 wrote:I thought reloading the segment registers in real mode flushed the "hidden parts" with the real mode compatible values (i.e. limit of 0xFFFFF and byte granularity). Perhaps I should read up on it though.
I thought so too but couldn't find it in the original 386 documentation. Google found this:
AllExperts wrote:Loading the segment register with any new value will disable this odd feature.
However, our favorite Wiki's example reloads DS after reentering real mode, and so does this example. Both examples load DS with zero, maybe that does matter?

Roel

Re: Unreal mode

Posted: Mon Nov 16, 2009 1:32 pm
by Combuster
As linked before: Descriptor Cache on how it really works...

As for clearing DS, what if an interrupt required that segment register and restored it afterwards? The limit would still be the same, but the restoration causes the base field to be updated so DS points to something like 0x80 or 0x100 (when DS was loaded with GDT entry 1 or 2 respectively) instead of 0x0 like protected mode left it.

Re: Unreal mode

Posted: Mon Nov 16, 2009 1:40 pm
by qw
Combuster, thanks for the link. If I understand the Wiki article correctly, then loading a value in a segment register in real mode does update the base field, but not the segment limit of the descriptor cache?

EDIT: changed "index field" to "segment limit"

Re: Unreal mode

Posted: Mon Nov 16, 2009 2:01 pm
by Combuster
There's no index field. If you meant the segment limit, then yes :wink:

Re: Unreal mode

Posted: Mon Nov 16, 2009 2:03 pm
by jal
Owen wrote:My (admittedly limited) understanding was that XMS managers ran the system in v8086 mode with paging - though of course this may be wrong - which therefore necessitated the introduction of VCPI to enter protected mode. (Then DPMI came along which is an altogether much cleaner solution)
You are completely mixing up XMS with EMS :). EMS (or rather, EMM386) is the one with v8086 and VCPI. DPMI is far from cleaner, but was needed with the introduction of protected mode OSes (read: Windows). I wrote something about this here.


JAL

Re: Unreal mode

Posted: Mon Nov 16, 2009 2:09 pm
by jal
Combuster wrote:As for clearing DS, what if an interrupt required that segment register and restored it afterwards? The limit would still be the same, but the restoration causes the base field to be updated so DS points to something like 0x80 or 0x100 (when DS was loaded with GDT entry 1 or 2 respectively) instead of 0x0 like protected mode left it.
I don't understand what you mean here. With "interrupt" I assume you mean a BIOS service? But those are in real mode, and as such changing the segment's value and restoring it would be no problem, as the base would, after restoring, be the same as it was before? Or am I missing something?


JAL

Re: Unreal mode

Posted: Mon Nov 16, 2009 2:15 pm
by Combuster
jal wrote:
Combuster wrote:As for clearing DS, what if an interrupt required that segment register and restored it afterwards? The limit would still be the same, but the restoration causes the base field to be updated so DS points to something like 0x80 or 0x100 (when DS was loaded with GDT entry 1 or 2 respectively) instead of 0x0 like protected mode left it.
I don't understand what you mean here. With "interrupt" I assume you mean a BIOS service? But those are in real mode, and as such changing the segment's value and restoring it would be no problem, as the base would, after restoring, be the same as it was before? Or am I missing something?
Loading a segment register in real mode will set its base to contents * 16. However if you drop back from protected mode, you don't reload the segment register, and thus its visible value will be a pointer to a GDT entry, and the base will (in the standard implementation) be zero, i.e. *not* contents * 16.
So if an IRQ happens and it needs to touch that register, then on return the base will suddenly be 0x8 (contents) * 16 = 0x80, and not zero like you left it.

Re: Unreal mode

Posted: Mon Nov 16, 2009 2:19 pm
by jal
Combuster wrote:Loading a segment register in real mode will set its base to contents * 16. However if you drop back from protected mode, you don't reload the segment register
True, but now you're talking about returning from protected mode. Afaik, the BIOS does not enter protected mode (I mentioned in a previous post in this thread that going back/forth protected mode may be the only way to screw up things).


JAL

Re: Unreal mode

Posted: Mon Nov 16, 2009 2:29 pm
by Combuster
I'm still talking about why you need to clear DS (and ES and whatever else you use):

Code: Select all

mov DX, 8
mov DS, DX ; DS: visible=8, base=0, limit=4G
mov eax, CR0
and AL, 0xfe
mov CR0, eax
sti

; interrupt happens, DS: visible=8, base=0x80, limit=4G

mov EDI, 0x100000 ; 1MB
mov ESI, 0x20000 ; the kernel was loaded to 0x2000:0x0000
mov ECX, kernel_size
a32 rep movsd ; oops, we just missed the first 128 bytes of the kernel
compare to:

Code: Select all

mov DX, 8
mov DS, DX ; DS: visible=8, base=0, limit=4G
mov eax, CR0
and AL, 0xfe
mov CR0, eax
sti

; interrupt happens, DS: visible=8, base=0x80, limit=4G

xor DX, DX
mov DS, DX ; DS: visible=0, base=0x0, limit=4G
mov ES, DX ; we'll be using ES too.

mov EDI, 0x100000 ; 1MB 
mov ESI, 0x20000 ; the kernel was loaded to 0x2000:0x0000
mov ECX, kernel_size
a32 rep movsd ; yay it works

Re: Unreal mode

Posted: Tue Nov 17, 2009 2:54 am
by tom9876543
Combuster wrote:I'm still talking about why you need to clear DS (and ES and whatever else you use)
There is no requirement to set the segment register to 0.

You have copied code without really understanding it.

The physical address in unreal mode = DS << 16 + offset.

If you make DS 0, then the offset is the same as the physical address.

DS was set to 0 for simplicity reasons only.

Re: Unreal mode

Posted: Tue Nov 17, 2009 2:58 am
by jal
tom9876543 wrote:You have copied code without really understanding it.
Hahaha. I doubt there's any code Combuster doesn't understand :). He's one of the most senior members here :).


JAL

Re: Unreal mode

Posted: Tue Nov 17, 2009 3:15 am
by Combuster
tom9876543 wrote:
Combuster wrote:I'm still talking about why you need to clear DS (and ES and whatever else you use)
There is no requirement to set the segment register to 0.

You have copied code without really understanding it.

The physical address in unreal mode = DS << 16 + offset.

If you make DS 0, then the offset is the same as the physical address.

DS was set to 0 for simplicity reasons only.
I take offence on this.
Line 1: Read the above example.
Line 2: I have written the example from scratch to illustrate my point.
Line 3: That is not true, see the example, the Descriptor Cache page, and given the amount of effort I already spent in this thread (after all the previous ones) explaining why, you should be glad I don't have moderator privileges - considering your posting history, you'd probably have earned the banhammer for sheer stupidity by now.
Line 4: I won't bother enumerating the many cases where that does not hold.
Line 5: You obviously can't read.
I have just reported your post since you apparently can't contribute anything meaningful and insult me without any cause.

Re: Unreal mode

Posted: Tue Nov 17, 2009 3:26 am
by qw
Tom9876543, where does your reaction come from? Of course there is no requirement to set the segment registers to zero, but they must have values corresponding to the assumed segment base, as Combuster demonstrated.

Re: Unreal mode

Posted: Tue Nov 17, 2009 3:54 am
by tom9876543
Sorry combuster I made a mistake. Your code is correct. I should read it more carefully. I didn't understand your comment so sorry for that.