Entering protected mode on x86, code segment

Discussions on more advanced topics such as monolithic vs micro-kernels, transactional memory models, and paging vs segmentation should go here. Use this forum to expand and improve the wiki!
Post Reply
angods
Member
Member
Posts: 26
Joined: Sat Oct 23, 2021 5:36 am

Entering protected mode on x86, code segment

Post by angods »

SOLVED

When we enter the protected mode, meaning of segment registers changes to index of a GDT entry.

Let's say the GDT has 2 entries: first being a NULL entry and second covering entire address space and starting at 0
Code to enter the protected mode looks like this:

Code: Select all

lgdt [DescriptorTable]
mov eax, cr0 ;Get current value of control register 0
or eax, 1 ;Enable the PM bit
mov cr0, eax ;Set control register 0 to value with PM bit set, enabling the protected mode
jmp 0x8:ProtectedModeMain ;How TF is this supposed to be executed?
[BITS 32]
ProtectedModeMain:
After CPU is done processing mov cr0, eax, it already is in protected mode. It means that current value CS register (assuming CS = 0) means the first GDT entry, which is the NULL descriptor.
Since the code segment descriptor is now invalid, how can the CPU continue executing instructions?

Changing the CS value before entering isn't a good solution either, because in real mode it isn't a valid CS value...

Does the CPU start using absolute addresses when we switch to protected mode? Otherwise I have no idea how it could work.

Thanks in advance :D
Last edited by angods on Mon Oct 25, 2021 1:03 pm, edited 1 time in total.
Octocontrabass
Member
Member
Posts: 5512
Joined: Mon Mar 25, 2013 7:01 pm

Re: Entering protected mode on x86, code segment

Post by Octocontrabass »

Segment registers are bigger than they look. They have a selector part, which you can directly read and write, and they have a descriptor part, which you can't access directly. Any time you write to the selector part, the descriptor part gets updated.

The trick here is that when you switch to protected mode, the descriptors inside the segment registers don't change. The CPU will load the next instruction using CS like it's in real mode.

Not all instructions will run correctly if you use real mode segments when the CPU is in protected mode, and the behavior can differ between CPUs. Intel says only two instructions are guaranteed to work: far JMP and far CALL. Any other use of real mode segments in protected mode is undefined behavior, so don't do it. (For details, see Intel SDM volume 3A section 9.9.1.)
angods
Member
Member
Posts: 26
Joined: Sat Oct 23, 2021 5:36 am

Re: Entering protected mode on x86, code segment

Post by angods »

Octocontrabass wrote:Segment registers are bigger than they look. They have a selector part, which you can directly read and write, and they have a descriptor part, which you can't access directly. Any time you write to the selector part, the descriptor part gets updated.

The trick here is that when you switch to protected mode, the descriptors inside the segment registers don't change. The CPU will load the next instruction using CS like it's in real mode.

Not all instructions will run correctly if you use real mode segments when the CPU is in protected mode, and the behavior can differ between CPUs. Intel says only two instructions are guaranteed to work: far JMP and far CALL. Any other use of real mode segments in protected mode is undefined behavior, so don't do it. (For details, see Intel SDM volume 3A section 9.9.1.)

That explains everything, thanks!
Post Reply