Long jump in gdt in the bootloader

flush_gdt: lgdt [gdtr] jmp 0x08:complete_flush complete_flush: mov ax, 0x10 mov ds, ax mov es, ax mov fs, ax mov gs, ax mov ss, ax ret 

I can not understand what this code does. flush_gdt is the label in order, then lgdt [gdtr] loads the 48-bit pointer into the gdtr register and then from jmp 0x08:complet_flush .

What does the jmp instruction do? and then why do we move 0x10 to ax and then to other registers

+6
source share
1 answer

x86 supports two virtual memory circuits ( read about it here ):

  • segmentation must be managed using the segment table, GDT.
  • paging, optional, page table driven, PDT.

Most operating systems want to use paging and do not want segmentation, but it is necessary and cannot just turn it off.

So, the trick is to turn off its effect, which was not there. This can usually be done by creating 4 large segment descriptors with overlapping (next to the zero segment):

  • segment index 0: zero segment descriptor
  • segment index 1: code segment descriptor for privileged mode (core)
  • segment index 2: data segment descriptor for privileged mode (core)
  • segment index 3: code segment descriptor for non-privileged mode (user)
  • segment index 4: data segment descriptor for non-privileged mode (user)

all of these segments start from 0x00000000 to 0xffffffff , so you end up with overlapping large segments, which are privileged code and data, as well as insecure code and data at the same time. This should open the virtual memory and disable the segmentation effect.

The processor uses the segment selector (segment registers cs , ds , ss ...) to find out the right segment (again, segmentation is required).

Each segment selector has a size of 16 bits and has the following layout ( source ):

enter image description here

  • The first two bits indicate that the x86 privilege level supports 4 levels, but only two of them are actually used ( 00 is the highest and 11 is the lowest).

  • The third bit indicates that the table should be used, mainly 0 , GDT.

  • The remaining 13 bits indicate the segment index.

If you interpreted 0x08 , which loads in cs , it will be in binary format:

 0000000000001 0 00 index 1 (code) GDT privileged 

and 0x10 , which loads in ds , ss , ...:

 0000000000010 0 00 index 2 (data) GDT privileged 

If you read the segment selector of any user-mode program, you should see that the cs value is 27 ( 0x1b ), which means:

 0000000000011 0 11 index 3 (code) GDT non-privileged 

and the data selectors ds , ss , ... should store 35 ( 0x23 ):

 0000000000100 0 11 index 4 (data) GDT non-privileged 

Data segment selectors (registers) can be easily changed using the simple mov instruction, but cs cannot be used with mov , so you use jmp 0x08:OFFSET to load the segment configurations into the code segment selector.

+11
source

Source: https://habr.com/ru/post/970140/


All Articles