PE doesn't get set
PE doesn't get set
hello all,
i am a newbie to osd. the coding,
mov eax, cr0
or ax, 1h
mov cr0, eax
doesn't set the pe bit. so, i could not jump to the protected mode. i'm helpless. plz, help me.
thanks in advance
i am a newbie to osd. the coding,
mov eax, cr0
or ax, 1h
mov cr0, eax
doesn't set the pe bit. so, i could not jump to the protected mode. i'm helpless. plz, help me.
thanks in advance
RE:PE doesn't get set
your section of code looks fine, you may want to provide us with some context to help you with your problem
RE:PE doesn't get set
I have provided with the GDT structure and the coding needed to set the PE bit and install GDT. I use Nasm for windows.
cli
mov eax, cr0 ;
or ax, 1 ; Sets the PE bit
mov cr0, eax ;
xor ax, ax
mov ds, ax
lgdt [gdt_descriptor]
gdt:
null_descriptor:
dw 0 ; seg_length1_15
dw 0 ; base_addr0_15
db 0 ; base_addr16_23
db 0 ; dflags
db 0 ; access
db 0 ; base_addr24_31
code_descriptor:
dw 0xFFFF ; seg_length1_15
dw 0 ; base_addr0_15
db 0 ; base_addr16_23
db 0x9A ; dflags
db 0xCF ; access
db 0 ; base_addr24_31
data_descriptor:
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0
gdt_end:
gdt_descriptor:
db gdt_end - gdt - 1
dw gdt
cli
mov eax, cr0 ;
or ax, 1 ; Sets the PE bit
mov cr0, eax ;
xor ax, ax
mov ds, ax
lgdt [gdt_descriptor]
gdt:
null_descriptor:
dw 0 ; seg_length1_15
dw 0 ; base_addr0_15
db 0 ; base_addr16_23
db 0 ; dflags
db 0 ; access
db 0 ; base_addr24_31
code_descriptor:
dw 0xFFFF ; seg_length1_15
dw 0 ; base_addr0_15
db 0 ; base_addr16_23
db 0x9A ; dflags
db 0xCF ; access
db 0 ; base_addr24_31
data_descriptor:
dw 0xFFFF
dw 0
db 0
db 0x92
db 0xCF
db 0
gdt_end:
gdt_descriptor:
db gdt_end - gdt - 1
dw gdt
RE:PE doesn't get set
You set ds to segment 0 (which makes sense) but did you use org to set the base address of your code bock so that 0:gdt_descriptor and 0:gdt is actually right? It would be helpful if you posted the entire program (bootsector?). What do you do after "lgdt [gdt_descriptor]"? Do you actually load new segment descriptors?
RE:PE doesn't get set
AFAIK, the GDT should be loaded before setting the PE bit. Everything else looks fine.
RE:PE doesn't get set
yes, the gdt needs to be loaded before switching the PE bit on. also, correct me if i am wrong but i believe you need to load the segment registers (ds included) after switching to pmode for the processor to load the correct base and limit information. the order i follow is:
-cli
-lgdt
-set PE bit
-far jump to pmode code selector
switch to bits 32 if running in a 32 bit code segment
-reload all segment registers
-...
-cli
-lgdt
-set PE bit
-far jump to pmode code selector
switch to bits 32 if running in a 32 bit code segment
-reload all segment registers
-...
RE:PE doesn't get set
it doesn't really matter which order you do it in, setting the PE bit CR0 activates a king of deferred pmode, the CPU does not actually switch into pmode until you perform a far jump into your 32-bit code segment
RE:PE doesn't get set
I've been wondering about that, actually.
What would happen if you (in real mode) set up a pmode IDT and GDT, arranged for your code segment to be something that would be valid in both pmode and real mode, set the PE bit, didn't jump, and took an interrupt?
Seriously, what would happen?
My best guess is that it would either blow up because it tried to privelidge transition without a TSS or it would actually take the interrupt and return properly.
Now I'm curious, and may actually try to set this up this weekend...
--Jamethiel
What would happen if you (in real mode) set up a pmode IDT and GDT, arranged for your code segment to be something that would be valid in both pmode and real mode, set the PE bit, didn't jump, and took an interrupt?
Seriously, what would happen?
My best guess is that it would either blow up because it tried to privelidge transition without a TSS or it would actually take the interrupt and return properly.
Now I'm curious, and may actually try to set this up this weekend...
--Jamethiel
RE:PE doesn't get set
"My best guess is that it would either blow up because it tried to privelidge transition without a TSS or it would actually take the interrupt and return properly."
The TSS thing wouldn't be an issue because you would be int'ing from priv0 to priv0 code (real mode segments are all priv0), so it doesn't reference the TSS to switch stacks.
However, when an interrupt is serviced, the 16-bit visible portion is backed up on the stack, and when the iret is done it reloads CS with the stored value, which would be unlikely to be right or even valid when looked up in the [GL]DT. Aside from the documented issues, it is also likely that in some cases the interrupt handler would not be designed to work in pmode, and as it does change the addressing substantially, I would guess that it would not work.
The TSS thing wouldn't be an issue because you would be int'ing from priv0 to priv0 code (real mode segments are all priv0), so it doesn't reference the TSS to switch stacks.
However, when an interrupt is serviced, the 16-bit visible portion is backed up on the stack, and when the iret is done it reloads CS with the stored value, which would be unlikely to be right or even valid when looked up in the [GL]DT. Aside from the documented issues, it is also likely that in some cases the interrupt handler would not be designed to work in pmode, and as it does change the addressing substantially, I would guess that it would not work.
RE:PE doesn't get set
Which is why I said to load a pmode IDT and set up the real mode code segment to line up with a matching descriptor in the GDT.
It would certianly put the lie to the statement that you don't actually enter pmode until after that first jump.
It would certianly put the lie to the statement that you don't actually enter pmode until after that first jump.
RE:PE doesn't get set
You enter pmode after setting bit 0 in cr0. Being in pmode means that whenever a segment register is loader, it is done with the [GL]DT rather then by a simple computation. However, you need to actually load new values in the segment registers in order to see the change.
"Which is why I said to load a pmode IDT and set up the real mode code segment to line up with a matching descriptor in the GDT."
The problem with trying to set up your pmode segments as equivalent to real mode is that for each pmode segment descriptor table entry there are 8 real mode segments with distinct physical addresses. That will be a problem if you just vector to a real mode interrupt handler which (for example) uses several contiguous segments for its operation.
I do encourage you to post any interesting results from you experimenting.
"Which is why I said to load a pmode IDT and set up the real mode code segment to line up with a matching descriptor in the GDT."
The problem with trying to set up your pmode segments as equivalent to real mode is that for each pmode segment descriptor table entry there are 8 real mode segments with distinct physical addresses. That will be a problem if you just vector to a real mode interrupt handler which (for example) uses several contiguous segments for its operation.
I do encourage you to post any interesting results from you experimenting.