assemblyx86bootloaderprotected-mode

Problem understanding far jump after entering protected mode


In my bootloader code there is a section in which we switch the cpu to protected mode by loading the GDT and enabling the control register bit.

This is the portion of bootloader code:

init_pm:
    ...
    cli
    lgdt [GDT_descriptor]

    mov eax, cr0
    or eax, 1
    mov cr0, eax

    ; far jump
    jmp CODE_SEG:start_protected_mode

[bits 32]
start_protected_mode:
    ...

and these are the constants:

CODE_SEG equ code_descriptor - GDT_start
DATA_SEG equ data_descriptor - GDT_start

So my questions are the following:

  1. what is a far jump ?

  2. what exactly does moving to protected mode do to the cpu ?

  3. what is CODE_SEG and why we use it with the offset start_protected_mode ? Can't we just do a normal jump like jmp start_protected_mode ? I know it's the location of code descriptor in GDT but does this automatically get recognised by the cpu as the location of the bootloader code ?


Solution

    1. A far jump is one that loads the CS register as well as E/RIP.

    2. Setting bit 0 of CR0 changes the way segment register loads are performed by the CPU. It also changes the way many other instructions operate. However, it does not change the cached CS descriptor information. So after entering protected mode, the CPU is still executing instructions in 16-bit mode.

    3. The code segment descriptor in the GDT is a 32-bit code segment. Loading this descriptor into CS causes the processor to start executing instructions in 32-bit mode. If you used a near jump instead of a far jump, the processor would try to interpret the instructions as 16-bit instructions.