2

After a long read, I am really confused. From what I read:

  1. Modern OS does not use segments at all.

  2. The GDT is used to define a segment in the memory (including constraints).

  3. The page table has a supervisor bit that indicates if the current location is for the kernel.

  4. Wikipedia says that "The GDT is still present in 64-bit mode; a GDT must be defined but is generally never changed or used for segmentation."

Why do we need it at all? And how linux uses it?

Moshe Levy
  • 174
  • 9

1 Answers1

3
  1. Modern OS does not use segments at all.

A modern OS (for 64-bit 80x86) still uses segment registers; it's just that their use is "mostly hidden" from user-space (and most user-space code can ignore them). Specifically; the CPU will determine if the code is 64-bit (or 32-bit or 16-bit) from whatever the OS loads (from GDT or LDT) into CS, interrupts still save CS and SS for the interrupted code (and load them again at iret), GS and/or FS are typically used for thread-local and/or CPU local storage, etc.

  1. The GDT is used to define a segment in the memory (including constraints).

Code and data segments are just one of the things that GDT is used for. The other main use is defining where the Task State Segment is (which is used to find IO port permission map, values to load into CS, SS and RSP when there's a privilege level change caused by an interrupt, etc). It's also still possible for 64-bit code (and 32-bit code/processes running under a 64-bit kernel) to use call gates defined in the GDT, but most operating systems don't use that feature for 64-bit code (they use syscall instead).

  1. The page table has a supervisor bit that indicates if the current location is for the kernel.

Yes. The page table's supervisor bit determines if code running at CPL=3 can/can't access the page (or if the code must be CPL=2, CPL=1 or CPL=0 to access the page).

  1. Wikipedia says that "The GDT is still present in 64-bit mode; a GDT must be defined but is generally never changed or used for segmentation."

Yes - Wikipedia is right. Typically an OS will set up a GDT early during boot (for TSS, CS, SS, etc) and then not have any reason to modify it after boot; and the segment registers aren't used for "segmented memory protection" (but are used for other things - determining code size, if an interrupt handler should return to CPL=0 or not, etc).

Brendan
  • 35,656
  • 2
  • 39
  • 66
  • Thanks! 1.Can you give example when we check the GDT? 2.The DPL is saved in the GDT, so when we check it?(if we have the memory protection from the paging, why do we need it?) – Moshe Levy Nov 09 '20 at 06:04
  • 3.When do we check the code size? and why do we need to do it? 4.does every memory reference goes through the GDT? for example CS::1000, goes to the GDT and checks the relevant bits? and what about 1000(memory reference)? – Moshe Levy Nov 09 '20 at 06:10
  • @MosheLevy: When most things (explicit load, interrupt, "far" control transfers, but not `syscall`) cause a value to be loaded into a segment register; the CPU fetches info from GDT (or LDT) and checks that info. If there's no problem (no general protection fault) the info is cached in the CPU (in a "hidden" part of the segment register) for subsequent use (e.g. so CPU doesn't have to continually check the GDT entry for the code segment every time it decodes an instruction). – Brendan Nov 09 '20 at 18:58
  • @MosheLevy: The DPL is only used as part of that "CPU checks info from GDT/LDT when value is loaded into segment register" check; to determine if the currently running code does/doesn't have the privilege needed to use the GDT/LDT entry. – Brendan Nov 09 '20 at 18:59