{"componentChunkName":"component---src-templates-post-template-js","path":"/linux-memory-protect-gdt-ldt-en","result":{"data":{"markdownRemark":{"id":"c463abc8-2fe4-5c44-9b51-0d3df391def3","html":"<blockquote>\n<p>This page has been machine-translated from the <a href=\"/linux-memory-protect-gdt-ldt\">original page</a>.</p>\n</blockquote>\n<p>While reading UNIX source code, I became curious about the process of transitioning to protected mode during boot, so I’ve compiled my findings.</p>\n<p>I’ve tried to ensure technical accuracy, but if there are any errors, I would appreciate your feedback.</p>\n<p>This article targets Intel’s x86 CPU.</p>\n<!-- omit in toc -->\n<h2 id=\"table-of-contents\" style=\"position:relative;\"><a href=\"#table-of-contents\" aria-label=\"table of contents permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Table of Contents</h2>\n<ul>\n<li>\n<p><a href=\"#real-mode-and-protected-mode\">Real Mode and Protected Mode</a></p>\n<ul>\n<li><a href=\"#real-mode\">Real Mode</a></li>\n<li><a href=\"#protected-mode\">Protected Mode</a></li>\n</ul>\n</li>\n<li><a href=\"#memory-protection-in-protected-mode\">Memory Protection in Protected Mode</a></li>\n<li>\n<p><a href=\"#about-descriptor-tables\">About Descriptor Tables</a></p>\n<ul>\n<li><a href=\"#gdt-global-descriptor-table\">GDT (Global Descriptor Table)</a></li>\n<li><a href=\"#ldt-local-descriptor-table\">LDT (Local Descriptor Table)</a></li>\n</ul>\n</li>\n<li><a href=\"#summary\">Summary</a></li>\n<li><a href=\"#references\">References</a></li>\n</ul>\n<h2 id=\"real-mode-and-protected-mode\" style=\"position:relative;\"><a href=\"#real-mode-and-protected-mode\" aria-label=\"real mode and protected mode permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Real Mode and Protected Mode</h2>\n<h3 id=\"real-mode\" style=\"position:relative;\"><a href=\"#real-mode\" aria-label=\"real mode permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Real Mode</h3>\n<p>Real mode in x86 CPUs is an operating mode for <code class=\"language-text\">Intel 8086</code> CPU compatibility.</p>\n<p>For x86, it is the initial operating mode at boot, and the BIOS also operates in real mode.</p>\n<p>Due to <code class=\"language-text\">Intel 8086</code> CPU compatibility, real mode restricts all register address lengths to 16 bits.</p>\n<p>Reference: <a href=\"https://ja.wikipedia.org/wiki/%E3%83%AA%E3%82%A2%E3%83%AB%E3%83%A2%E3%83%BC%E3%83%89\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Real Mode - Wikipedia</a></p>\n<p>When referencing memory addresses, segment register values are used to access a 20-bit address space.</p>\n<p>Additionally, by enabling the A20 Line, a 21-bit address space can be used.</p>\n<p>Real mode does not have hardware-based memory protection or virtual memory, which exist in protected mode described later.</p>\n<p>Reference: <a href=\"https://wiki.osdev.org/Real_Mode\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Real Mode - OSDev Wiki</a></p>\n<h3 id=\"protected-mode\" style=\"position:relative;\"><a href=\"#protected-mode\" aria-label=\"protected mode permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Protected Mode</h3>\n<p>Protected mode is an operating mode in x86 CPUs where the memory space is extended to 32 bits and memory and I/O protection becomes possible.</p>\n<p>Hierarchical privilege management (ring protection) and memory protection between tasks are possible.</p>\n<p>Reference: <a href=\"https://ja.wikipedia.org/wiki/%E3%83%97%E3%83%AD%E3%83%86%E3%82%AF%E3%83%88%E3%83%A2%E3%83%BC%E3%83%89\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Protected Mode - Wikipedia</a></p>\n<p>Reference: <a href=\"https://wiki.osdev.org/Protected_Mode\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Protected Mode - OSDev Wiki</a></p>\n<p>As mentioned earlier, since the BIOS operates in real mode on x86 CPUs, BIOS interrupts cannot be used after transitioning to protected mode.</p>\n<p>The mechanism of memory protection in protected mode is described later.</p>\n<h2 id=\"memory-protection-in-protected-mode\" style=\"position:relative;\"><a href=\"#memory-protection-in-protected-mode\" aria-label=\"memory protection in protected mode permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Memory Protection in Protected Mode</h2>\n<p>In protected mode, it is necessary to define the memory regions that a program can reference. This applies to kernel programs as well.</p>\n<p>First, x86 CPUs handle programs and data in units of contiguous memory regions called segments.</p>\n<p>Segment units come in two sizes: 64KB or 4GB.</p>\n<p>In memory protection in protected mode, the starting point and size of a memory region, as well as the read/write/execute permissions for that memory region, are called segment descriptors and are managed by descriptor tables.</p>\n<p>When a program references memory in protected mode, the DS register does not directly point to a memory address value.</p>\n<p>Instead, the DS register references the descriptor table to obtain segment information.</p>\n<p>This mechanism makes it essential to rewrite the descriptor table for a program to reference arbitrary memory regions.</p>\n<p>However, since the descriptor table cannot be rewritten by programs, as a result, programs cannot reference memory regions other than those predetermined, achieving memory protection.</p>\n<p>Reference: <a href=\"https://amzn.to/3JVSphh\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">How Windows Works</a></p>\n<p>Reference: <a href=\"https://ascii.jp/elem/000/000/649/649680/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">ASCII.jp: Understanding Windows Memory Management from x86 Mechanisms (1/4)</a></p>\n<h2 id=\"about-descriptor-tables\" style=\"position:relative;\"><a href=\"#about-descriptor-tables\" aria-label=\"about descriptor tables permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>About Descriptor Tables</h2>\n<p>There are two types of descriptor tables: GDT (Global Descriptor Table) and LDT (Local Descriptor Table).</p>\n<h3 id=\"gdt-global-descriptor-table\" style=\"position:relative;\"><a href=\"#gdt-global-descriptor-table\" aria-label=\"gdt global descriptor table permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>GDT (Global Descriptor Table)</h3>\n<p>The GDT is a descriptor table that is typically defined only once per system.</p>\n<p>The GDT manages multiple LDTs.</p>\n<p>x86 CPUs have a register called GDTR for pointing to the starting address of the GDT.</p>\n<p>Reference: <a href=\"https://en.wikipedia.org/wiki/Global_Descriptor_Table\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Global Descriptor Table - Wikipedia</a></p>\n<p>Reference: <a href=\"https://wiki.osdev.org/Global_Descriptor_Table\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Global Descriptor Table - OSDev Wiki</a></p>\n<h3 id=\"ldt-local-descriptor-table\" style=\"position:relative;\"><a href=\"#ldt-local-descriptor-table\" aria-label=\"ldt local descriptor table permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>LDT (Local Descriptor Table)</h3>\n<p>LDTs are descriptor tables created for each program.</p>\n<p>In x86 CPUs, programs cannot access regions other than those defined in descriptor tables.</p>\n<p>Therefore, by having the OS manage non-conflicting descriptor tables for each program, it is possible to prevent each program from referencing other programs’ memory regions, achieving memory protection.</p>\n<p>Similar to GDTR, x86 CPUs have a register called LDTR for specifying the starting address of the currently used LDT.</p>\n<p>When a program tries to set a value in a segment register, the CPU references LDTR to obtain the address the program is trying to access and verifies access permission.</p>\n<h2 id=\"summary\" style=\"position:relative;\"><a href=\"#summary\" aria-label=\"summary permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Summary</h2>\n<p>To organize the flow during program execution on x86 CPUs: first, when a program transitions to an execution state, the CPU identifies the index of the target program’s LDT from the GDT referenced via GDTR and stores it in LDTR.</p>\n<p>When a program requests a reference to a specific segment, the CPU references the LDT from LDTR to obtain the reference address and verify reference permission.</p>\n<p>Through this series of processes, programs cannot reference memory regions other than those predefined, achieving memory protection.</p>\n<h2 id=\"references\" style=\"position:relative;\"><a href=\"#references\" aria-label=\"references permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>References</h2>\n<ul>\n<li><a href=\"https://amzn.to/3JVSphh\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">How Windows Works</a></li>\n<li><a href=\"https://amzn.to/3qZSCY7\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">OS Development in 30 Days!</a></li>\n<li><a href=\"https://amzn.to/3qXYsZX\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">OS Development from Scratch</a></li>\n<li><a href=\"https://amzn.to/3JRUdI2\" target=\"_blank\" rel=\"nofollow noopener noreferrer\">Understanding OS by Building: Theory and Implementation for Operating x86 Systems</a></li>\n</ul>","fields":{"slug":"/linux-memory-protect-gdt-ldt-en","tagSlugs":["/tag/linux-en/","/tag/os-en/","/tag/kernel-en/","/tag/english/"]},"frontmatter":{"date":"2022-01-09","description":"While reading UNIX source code, I became curious about the process of transitioning to protected mode during boot, so I've compiled my findings.","tags":["Linux (en)","OS (en)","Kernel (en)","English"],"title":"Notes on x86 CPU Memory Protection Mechanisms (GDT and LDT)","socialImage":{"publicURL":"/static/93ee63f2a992cec8ea2a833117345df4/linux-memory-protect-gdt-ldt.png"}}}},"pageContext":{"slug":"/linux-memory-protect-gdt-ldt-en"}},"staticQueryHashes":["251939775","401334301","825871152"]}