การเพจ x86 ทำงานอย่างไร


92

คำถามนี้มีขึ้นเพื่อเติมเต็มสุญญากาศของข้อมูลฟรีที่ดีเกี่ยวกับเรื่องนี้

ฉันเชื่อว่าคำตอบที่ดีจะเข้ากันได้กับคำตอบ SO ขนาดใหญ่หนึ่งคำหรืออย่างน้อยก็ในสองสามคำตอบ

เป้าหมายหลักคือการให้ข้อมูลที่เพียงพอแก่ผู้เริ่มต้นที่สมบูรณ์เพื่อให้พวกเขาสามารถใช้คู่มือได้ด้วยตนเองและสามารถเข้าใจแนวคิดพื้นฐานของระบบปฏิบัติการที่เกี่ยวข้องกับการเพจ

แนวทางที่แนะนำ:

  • คำตอบควรเป็นมิตรกับผู้เริ่มต้น:
    • ตัวอย่างที่เป็นรูปธรรม แต่อาจทำให้เข้าใจง่ายมีความสำคัญมาก
    • ยินดีต้อนรับการประยุกต์ใช้แนวคิดที่แสดง
  • การอ้างแหล่งข้อมูลที่มีประโยชน์เป็นสิ่งที่ดี
  • ยินดีต้อนรับการพูดนอกเรื่องเล็กน้อยเกี่ยวกับวิธีการที่ระบบปฏิบัติการใช้คุณสมบัติการเพจ
  • ยินดีต้อนรับคำอธิบาย PAE และ PSE
  • ยินดีต้อนรับการพูดนอกเรื่องขนาดเล็กเป็น x86_64

คำถามที่เกี่ยวข้องและเหตุใดฉันจึงคิดว่าไม่ใช่สิ่งที่ถูกหลอก:


1
ควรติดแท็ก "faq" และระบุว่า "community-wiki"
Kerrek SB

@KerrekSB ฉันไม่รู้จริงๆว่าจะจัดการคำถามแบบนี้ยังไง คำตอบควรเป็นวิกิชุมชนใช่หรือไม่ ฉันไม่พบfaqแท็ก
Ciro Santilli 郝海东冠状病六四事件法轮功

3
ฉันจะบอกว่าคำตอบสั้น ๆ คือ "อ่านเล่มที่ 3 บทที่ 4: การเพจในคู่มือ Intel" ค่อนข้างชัดเจนกระชับและเขียนได้ดีและไม่ได้รับความเชื่อถืออีกต่อไป
Kerrek SB

4
@KerrekSB ฉันยอมรับว่าคู่มือนั้นชัดเจนและเชื่อถือได้ แต่มันค่อนข้างรุนแรงเกินไปเมื่ออ่านครั้งแรกสำหรับฉันฉันต้องการตัวอย่างที่เรียบง่ายและเป็นรูปธรรม + เหตุผลเพื่อให้เข้าใจสิ่งต่างๆได้ดีขึ้น
Ciro Santilli 郝海东冠状病六四事件法轮功

คำตอบ:


144

รุ่นของคำตอบนี้กับ TOC ดีและเนื้อหาเพิ่มเติม

ฉันจะแก้ไขข้อผิดพลาดที่รายงาน หากคุณต้องการปรับเปลี่ยนขนาดใหญ่หรือเพิ่มแง่มุมที่ขาดหายไปให้ทำตามคำตอบของคุณเองเพื่อรับตัวแทนที่สมควรได้รับ การแก้ไขเล็กน้อยสามารถรวมเข้าด้วยกันได้โดยตรง

โค้ดตัวอย่าง

ตัวอย่างน้อยที่สุด: https://github.com/cirosantilli/x86-bare-metal-examples/blob/5c672f73884a487414b3e21bd9e579c67cd77621/paging.S

เช่นเดียวกับสิ่งอื่น ๆ ในการเขียนโปรแกรมวิธีเดียวที่จะเข้าใจสิ่งนี้คือการเล่นกับตัวอย่างน้อยที่สุด

สิ่งที่ทำให้เรื่องนี้ "ยาก" ก็คือตัวอย่างที่เรียบง่ายนั้นมีขนาดใหญ่เนื่องจากคุณต้องสร้าง OS ขนาดเล็กของคุณเอง

คู่มือ Intel

แม้ว่าจะเป็นไปไม่ได้ที่จะเข้าใจหากไม่มีตัวอย่างในใจให้พยายามทำความคุ้นเคยกับคู่มือโดยเร็วที่สุด

Intel อธิบายการเพจในคู่มือการเขียนโปรแกรมระบบ Intel Manual Volume 3 - 325384-056US กันยายน 2015บทที่ 4 "การเพจ"

ที่น่าสนใจเป็นพิเศษคือ Figure 4-4 "Formats of CR3 and Paging-Structure Entries with 32-Bit Paging" ซึ่งให้โครงสร้างข้อมูลที่สำคัญ

MMU

การเพจทำได้โดยส่วนMemory Management Unit (MMU) ของ CPU เช่นเดียวกับคนอื่น ๆ อีกมากมาย (เช่นx87 co-processor , APIC ) สิ่งนี้เคยเป็นโดยชิปแยกในช่วงแรก ๆ ซึ่งต่อมาได้รวมเข้ากับ CPU แต่ยังคงใช้คำนี้อยู่

ข้อเท็จจริงทั่วไป

โลจิคัลแอดเดรสคือที่อยู่หน่วยความจำที่ใช้ในรหัสที่ดินของผู้ใช้ "ปกติ" (เช่นเนื้อหาของrsiin mov eax, [rsi])

การแบ่งส่วนแรกจะแปลเป็นที่อยู่เชิงเส้นจากนั้นการแบ่งหน้าจะแปลที่อยู่เชิงเส้นเป็นที่อยู่ทางกายภาพ

(logical) ------------------> (linear) ------------> (physical)
             segmentation                 paging

โดยส่วนใหญ่เราสามารถคิดว่าที่อยู่จริงเป็นดัชนีเซลล์หน่วยความจำฮาร์ดแวร์ RAM จริง แต่สิ่งนี้ไม่เป็นความจริง 100% เนื่องจาก:

เพจใช้ได้เฉพาะในโหมดป้องกันเท่านั้น การใช้เพจในโหมดป้องกันเป็นทางเลือก เพจเปิดอยู่ iff PGบิตของcr0รีจิสเตอร์ถูกตั้งค่า

การแบ่งหน้าและการแบ่งส่วน

ความแตกต่างที่สำคัญอย่างหนึ่งระหว่างการแบ่งหน้าและการแบ่งส่วนคือ:

  • การแบ่งหน้าแบ่ง RAM ออกเป็นส่วนขนาดเท่า ๆ กันที่เรียกว่าเพจ
  • การแบ่งส่วนแบ่งหน่วยความจำออกเป็นชิ้นส่วนขนาดตามอำเภอใจ

นี่เป็นข้อได้เปรียบหลักของการเพจเนื่องจากชิ้นส่วนที่มีขนาดเท่ากันทำให้จัดการสิ่งต่างๆได้ง่ายขึ้น

การเพจได้รับความนิยมมากขึ้นจนการรองรับการแบ่งส่วนลดลงใน x86-64 ในโหมด 64 บิตซึ่งเป็นโหมดหลักของการทำงานสำหรับซอฟต์แวร์ใหม่ซึ่งมีเฉพาะในโหมดความเข้ากันได้ซึ่งเลียนแบบ IA32

ใบสมัคร

การเพจถูกใช้เพื่อปรับใช้พื้นที่แอดเดรสเสมือนของกระบวนการบนระบบปฏิบัติการสมัยใหม่ ด้วยที่อยู่เสมือนระบบปฏิบัติการสามารถปรับกระบวนการทำงานพร้อมกันสองกระบวนการขึ้นไปบน RAM เดียวในลักษณะที่:

  • ทั้งสองโปรแกรมไม่จำเป็นต้องรู้อะไรเกี่ยวกับโปรแกรมอื่น ๆ
  • หน่วยความจำของทั้งสองโปรแกรมสามารถขยายและลดขนาดได้ตามต้องการ
  • การสลับระหว่างโปรแกรมนั้นรวดเร็วมาก
  • โปรแกรมหนึ่งไม่สามารถเข้าถึงหน่วยความจำของกระบวนการอื่นได้

ในอดีตการแบ่งหน้าเกิดขึ้นหลังจากการแบ่งส่วนและส่วนใหญ่ถูกแทนที่สำหรับการใช้งานหน่วยความจำเสมือนในระบบปฏิบัติการสมัยใหม่เช่น Linux เนื่องจากง่ายต่อการจัดการหน่วยความจำขนาดคงที่ของหน้าแทนที่จะเป็นส่วนความยาวที่หลากหลาย

การใช้งานฮาร์ดแวร์

เช่นเดียวกับการแบ่งส่วนในโหมดป้องกัน (ซึ่งการแก้ไขการลงทะเบียนเซ็กเมนต์จะทริกเกอร์การโหลดจาก GDT หรือ LDT) ฮาร์ดแวร์การเพจจะใช้โครงสร้างข้อมูลในหน่วยความจำเพื่อทำงานของมัน (ตารางเพจไดเร็กทอรีเพจ ฯลฯ )

รูปแบบของโครงสร้างข้อมูลเหล่านั้นได้รับการแก้ไขโดยฮาร์ดแวร์แต่ขึ้นอยู่กับระบบปฏิบัติการที่จะตั้งค่าและจัดการโครงสร้างข้อมูลเหล่านั้นบน RAM อย่างถูกต้องและเพื่อบอกฮาร์ดแวร์ว่าจะหาได้จากที่ใด (ผ่านcr3)

สถาปัตยกรรมอื่น ๆ บางส่วนปล่อยให้เพจอยู่ในมือของซอฟต์แวร์เกือบทั้งหมดดังนั้น TLB miss จึงเรียกใช้ฟังก์ชันที่มาจาก OS เพื่อเดินตารางเพจและแทรกการแมปใหม่ลงใน TLB นี้รูปแบบตารางใบหน้าจะได้รับเลือกโดย OS แต่ทำให้มันไม่น่าฮาร์ดแวร์เพื่อให้สามารถทับซ้อนเดินหน้ากับการดำเนินการออกจากคำสั่งของคำแนะนำอื่น ๆ วิธีที่สามารถ

ตัวอย่าง: โครงร่างการเพจระดับเดียวที่เรียบง่าย

นี่คือตัวอย่างของวิธีการดำเนินการเพจบนสถาปัตยกรรม x86 เวอร์ชันที่เรียบง่ายเพื่อใช้พื้นที่หน่วยความจำเสมือน

ตารางหน้า

ระบบปฏิบัติการสามารถให้ตารางหน้าต่อไปนี้:

ตารางหน้าที่กำหนดให้กับกระบวนการ 1 โดยระบบปฏิบัติการ:

RAM location        physical address   present
-----------------   -----------------  --------
PT1 + 0       * L   0x00001            1
PT1 + 1       * L   0x00000            1
PT1 + 2       * L   0x00003            1
PT1 + 3       * L                      0
...                                    ...
PT1 + 0xFFFFF * L   0x00005            1

ตารางหน้าที่กำหนดให้กับกระบวนการ 2 โดยระบบปฏิบัติการ:

RAM location       physical address   present
-----------------  -----------------  --------
PT2 + 0       * L  0x0000A            1
PT2 + 1       * L  0x0000B            1
PT2 + 2       * L                     0
PT2 + 3       * L  0x00003            1
...                ...                ...
PT2 + 0xFFFFF * L  0x00004            1

ที่ไหน:

  • PT1และPT2: ตำแหน่งเริ่มต้นของตาราง 1 และ 2 บน RAM

    ค่าตัวอย่าง: 0x00000000, 0x12345678ฯลฯ

    เป็นระบบปฏิบัติการที่ตัดสินค่าเหล่านั้น

  • L: ความยาวของรายการตารางหน้า

  • present: แสดงว่าเพจอยู่ในหน่วยความจำ

ตารางหน้าตั้งอยู่บน RAM ตัวอย่างเช่นอาจตั้งอยู่เป็น:

--------------> 0xFFFFFFFF


--------------> PT1 + 0xFFFFF * L
Page Table 1
--------------> PT1


--------------> PT2 + 0xFFFFF * L
Page Table 2
--------------> PT2

--------------> 0x0

ตำแหน่งเริ่มต้นบน RAM สำหรับทั้งสองตารางเพจเป็นไปตามอำเภอใจและควบคุมโดย OS ขึ้นอยู่กับระบบปฏิบัติการเพื่อให้แน่ใจว่าจะไม่ทับซ้อนกัน!

แต่ละกระบวนการไม่สามารถสัมผัสกับตารางหน้าใด ๆ ได้โดยตรงแม้ว่าจะสามารถร้องขอไปยังระบบปฏิบัติการที่ทำให้ตารางเพจถูกแก้ไขได้เช่นขอให้มีสแต็กที่ใหญ่ขึ้นหรือส่วนฮีป

เพจเป็นกลุ่ม 4KB (12 บิต) และเนื่องจากแอดเดรสมี 32 บิตจึงต้องใช้เพียง 20 บิต (20 + 12 = 32 ดังนั้น 5 อักขระในสัญกรณ์ฐานสิบหก) เพื่อระบุแต่ละเพจ ค่านี้ได้รับการแก้ไขโดยฮาร์ดแวร์

รายการตารางหน้า

ตารางหน้าคือ ... ตารางหน้ารายการตาราง!

รูปแบบที่แน่นอนของรายการตารางได้รับการแก้ไขโดยฮาร์ดแวร์

ในตัวอย่างที่เรียบง่ายนี้รายการตารางเพจมีเพียงสองฟิลด์:

bits   function
-----  -----------------------------------------
20     physical address of the start of the page
1      present flag

ดังนั้นในตัวอย่างนี้นักออกแบบฮาร์ดแวร์สามารถเลือกL = 21ได้

รายการตารางหน้าจริงส่วนใหญ่มีฟิลด์อื่น ๆ

การจัดตำแหน่งสิ่งต่าง ๆ ที่ 21 บิตเป็นไปไม่ได้เนื่องจากหน่วยความจำสามารถระบุแอดเดรสได้โดยไบต์ไม่ใช่บิต ดังนั้นแม้ในกรณีนี้จะต้องการเพียง 21 บิต แต่นักออกแบบฮาร์ดแวร์อาจเลือกที่L = 32จะเข้าถึงได้เร็วขึ้นและเพียงแค่จองบิตที่เหลือไว้เพื่อใช้งานในภายหลัง ค่าจริงสำหรับLบน x86 คือ 32 บิต

การแปลที่อยู่ในรูปแบบระดับเดียว

เมื่อตารางหน้าได้รับการจัดตั้งขึ้นโดย OS ที่แปลที่อยู่ระหว่างที่อยู่เส้นตรงและทางกายภาพจะทำโดยฮาร์ดแวร์

เมื่อระบบปฏิบัติการต้องการขั้นตอนการเปิดใช้งาน 1 ก็กำหนดcr3ที่จะPT1เริ่มต้นของตารางสำหรับกระบวนการหนึ่ง

หากกระบวนการ 1 ต้องการเข้าถึงที่อยู่เชิงเส้นวงจรฮาร์ดแวร์การ0x00000001เพจจะทำสิ่งต่อไปนี้สำหรับระบบปฏิบัติการโดยอัตโนมัติ:

  • แบ่งที่อยู่เชิงเส้นออกเป็นสองส่วน:

    | page (20 bits) | offset (12 bits) |
    

    ดังนั้นในกรณีนี้เราจะมี:

    • หน้า = 0x00000
    • ชดเชย = 0x001
  • ดูในตารางหน้า 1 เพราะcr3ชี้ไปที่มัน

  • ดูรายการ0x00000เพราะนั่นคือส่วนของหน้า

    ฮาร์ดแวร์รู้ว่ารายการนี้จะอยู่ที่ RAM PT1 + 0 * L = PT1ที่อยู่

  • เนื่องจากมีอยู่การเข้าถึงจึงถูกต้อง

  • โดยตารางหน้าตั้งของหมายเลขหน้าอยู่ที่0x000000x00001 * 4K = 0x00001000

  • ในการค้นหาที่อยู่จริงสุดท้ายเราต้องเพิ่มออฟเซ็ต:

      00001 000
    + 00000 001
      -----------
      00001 001
    

    เนื่องจาก00001เป็นที่อยู่จริงของหน้าเว็บที่ค้นหาบนตารางและ001เป็นค่าชดเชย

    ตามชื่อที่ระบุออฟเซ็ตจะถูกเพิ่มเพียงที่อยู่จริงของเพจเสมอ

  • จากนั้นฮาร์ดแวร์จะได้รับหน่วยความจำที่ตำแหน่งทางกายภาพนั้น

ในทำนองเดียวกันการแปลต่อไปนี้จะเกิดขึ้นสำหรับกระบวนการ 1:

linear     physical
---------  ---------
00000 002  00001 002
00000 003  00001 003
00000 FFF  00001 FFF
00001 000  00000 000
00001 001  00000 001
00001 FFF  00000 FFF
00002 000  00002 000
FFFFF 000  00005 000

ตัวอย่างเช่นเมื่อเข้าถึงที่อยู่00001000ส่วนของหน้าคือ00001ฮาร์ดแวร์ที่รู้ว่ารายการตารางเพจอยู่ที่ที่อยู่ RAM: PT1 + 1 * L( 1เนื่องจากส่วนของหน้า) และนั่นคือที่ที่จะค้นหา

เมื่อระบบปฏิบัติการต้องการเปลี่ยนไปใช้กระบวนการ 2 สิ่งที่ต้องทำคือcr3ชี้ไปที่หน้า 2 ง่ายๆแค่นั้นเอง!

ตอนนี้การแปลต่อไปนี้จะเกิดขึ้นสำหรับกระบวนการที่ 2:

linear     physical
---------  ---------
00000 002  00001 002
00000 003  00001 003
00000 FFF  00001 FFF
00001 000  00000 000
00001 001  00000 001
00001 FFF  00000 FFF
00003 000  00003 000
FFFFF 000  00004 000

ที่อยู่เชิงเส้นเดียวกันจะแปลเป็นที่อยู่ทางกายภาพที่แตกต่างกันสำหรับกระบวนการที่แตกต่างกันขึ้นอยู่กับค่าภายในcr3เท่านั้น

ด้วยวิธีนี้ทุกโปรแกรมสามารถคาดหวังว่าข้อมูลจะเริ่มต้น0และสิ้นสุดที่FFFFFFFFโดยไม่ต้องกังวลเกี่ยวกับที่อยู่จริงที่แน่นอน

ความผิดของเพจ

จะเกิดอะไรขึ้นถ้ากระบวนการ 1 พยายามเข้าถึงที่อยู่ภายในหน้าที่ไม่มีอยู่

ฮาร์ดแวร์จะแจ้งซอฟต์แวร์ผ่านข้อยกเว้นของ Page Fault

โดยปกติแล้วระบบปฏิบัติการจะต้องลงทะเบียนตัวจัดการข้อยกเว้นเพื่อตัดสินใจว่าจะต้องทำอะไร

เป็นไปได้ว่าการเข้าถึงหน้าที่ไม่ได้อยู่บนโต๊ะนั้นเป็นข้อผิดพลาดในการเขียนโปรแกรม

int is[1];
is[2] = 1;

แต่อาจมีบางกรณีที่ยอมรับได้เช่นใน Linux เมื่อ:

  • โปรแกรมต้องการเพิ่มสแต็ก

    เพียงแค่พยายามเข้าถึงไบต์ที่กำหนดในช่วงที่เป็นไปได้ที่กำหนดและหากระบบปฏิบัติการพอใจก็จะเพิ่มหน้านั้นในพื้นที่แอดเดรสของกระบวนการ

  • หน้าถูกสลับไปยังดิสก์

    ระบบปฏิบัติการจะต้องทำงานบางอย่างเบื้องหลังกระบวนการต่างๆเพื่อดึงหน้ากลับเข้าสู่ RAM

    ระบบปฏิบัติการสามารถค้นพบว่ากรณีนี้ขึ้นอยู่กับเนื้อหาของรายการตารางหน้าส่วนที่เหลือเนื่องจากหากค่าสถานะปัจจุบันชัดเจนรายการอื่น ๆ ของรายการตารางหน้าจะถูกทิ้งไว้อย่างสมบูรณ์เพื่อให้ระบบปฏิบัติการเป็นไปตามที่ต้องการ

    บน Linux เช่นเมื่อปัจจุบัน = 0:

    • หากฟิลด์ทั้งหมดของรายการตารางเพจเป็น 0 แสดงว่าที่อยู่ไม่ถูกต้อง

    • มิฉะนั้นเพจจะถูกสลับไปยังดิสก์และค่าจริงของฟิลด์เหล่านั้นจะเข้ารหัสตำแหน่งของเพจบนดิสก์

ไม่ว่าในกรณีใด OS จำเป็นต้องทราบว่าที่อยู่ใดสร้าง Page Fault เพื่อให้สามารถจัดการกับปัญหาได้ นี่คือเหตุผลที่นักพัฒนา IA32 ที่ดีตั้งค่าcr2เป็นที่อยู่นั้นเมื่อใดก็ตามที่เกิด Page Fault ขึ้น ตัวจัดการข้อยกเว้นสามารถตรวจสอบcr2เพื่อรับที่อยู่ได้

การลดความซับซ้อน

ความเรียบง่ายสู่ความเป็นจริงที่ทำให้ตัวอย่างนี้เข้าใจง่ายขึ้น:

  • วงจรการเพจจริงทั้งหมดใช้การเพจหลายระดับเพื่อประหยัดเนื้อที่ แต่สิ่งนี้แสดงให้เห็นถึงรูปแบบระดับเดียวที่เรียบง่าย

  • ตารางเพจมีเพียงสองฟิลด์: แอดเดรส 20 บิตและแฟล็กปัจจุบัน 1 บิต

    ตารางหน้าจริงมีทั้งหมด 12 ช่องดังนั้นคุณลักษณะอื่น ๆ ที่ถูกละเว้น

ตัวอย่าง: โครงร่างการเพจหลายระดับ

ปัญหาเกี่ยวกับรูปแบบการเพจระดับเดียวคือจะใช้ RAM มากเกินไป: 4G / 4K = 1M รายการต่อกระบวนการ หากแต่ละรายการมีความยาว 4 ไบต์นั่นจะทำให้ 4M ต่อกระบวนการซึ่งมากเกินไปสำหรับคอมพิวเตอร์เดสก์ท็อป: ps -A | wc -lบอกว่าตอนนี้ฉันใช้ 244 กระบวนการดังนั้นจะต้องใช้ RAM ประมาณ 1GB!

ด้วยเหตุนี้นักพัฒนา x86 จึงตัดสินใจใช้รูปแบบหลายระดับที่ลดการใช้ RAM

ข้อเสียของระบบนี้คือมีเวลาในการเข้าถึงที่สูงขึ้นเล็กน้อย

ในรูปแบบการเพจแบบ 3 ระดับที่ใช้สำหรับโปรเซสเซอร์ 32 บิตที่ไม่มี PAE บิตแอดเดรส 32 บิตจะถูกแบ่งออกเป็นดังนี้:

| directory (10 bits) | table (10 bits) | offset (12 bits) |

แต่ละกระบวนการต้องมีไดเร็กทอรีเพจเดียวและหนึ่งเพจเท่านั้นที่เชื่อมโยงอยู่ดังนั้นจึงจะมี2^10 = 1Kรายการไดเร็กทอรีเพจเป็นอย่างน้อยซึ่งดีกว่า 1M ขั้นต่ำที่จำเป็นในรูปแบบระดับเดียว

ตารางหน้าจะถูกจัดสรรตามที่ OS ต้องการเท่านั้น แต่ละตาราง2^10 = 1Kเพจมีรายการไดเร็กทอรีเพจ

ไดเรกทอรีหน้าประกอบด้วย ... รายการไดเรกทอรีหน้า! รายการไดเรกทอรีหน้าเป็นเช่นเดียวกับรายการตารางเพจยกเว้นว่าพวกเขาชี้ไปยังที่อยู่ของตาราง RAM หน้าแทนการอยู่ทางกายภาพของตาราง เนื่องจากแอดเดรสเหล่านี้มีความกว้างเพียง 20 บิตตารางเพจจึงต้องอยู่ที่จุดเริ่มต้นของเพจ 4KB

cr3 ตอนนี้ชี้ไปที่ตำแหน่งบน RAM ของไดเรกทอรีเพจของกระบวนการปัจจุบันแทนที่จะเป็นตารางเพจ

รายการตารางหน้าไม่เปลี่ยนแปลงเลยจากโครงร่างระดับเดียว

ตารางหน้าเปลี่ยนจากโครงร่างระดับเดียวเนื่องจาก:

  • แต่ละกระบวนการอาจมีได้ถึง 1K ตารางเพจหนึ่งรายการต่อหน้า
  • แต่ละตารางหน้าจะมีรายการ 1K แทนรายการ 1 ล้านรายการ

เหตุผลในการใช้ 10 บิตในสองระดับแรก (ไม่ใช่เช่นนั้น12 | 8 | 12) คือแต่ละรายการของตารางเพจมีความยาว 4 ไบต์ จากนั้นรายการ 2 ^ 10 ของไดเรกทอรีหน้าและตารางหน้าจะพอดีกับหน้า 4Kb ซึ่งหมายความว่าจะจัดสรรและยกเลิกการจัดสรรเพจสำหรับวัตถุประสงค์นั้นได้เร็วและง่ายขึ้น

การแปลที่อยู่ในรูปแบบหลายระดับ

ไดเร็กทอรีเพจที่กำหนดให้กับกระบวนการ 1 โดย OS:

RAM location     physical address   present
---------------  -----------------  --------
PD1 + 0     * L  0x10000            1
PD1 + 1     * L                     0
PD1 + 2     * L  0x80000            1
PD1 + 3     * L                     0
...                                 ...
PD1 + 0x3FF * L                     0

ตารางหน้าที่กำหนดให้กับกระบวนการ 1 โดยระบบปฏิบัติการที่PT1 = 0x10000000( 0x10000* 4K):

RAM location      physical address   present
---------------   -----------------  --------
PT1 + 0     * L   0x00001            1
PT1 + 1     * L                      0
PT1 + 2     * L   0x0000D            1
...                                  ...
PT1 + 0x3FF * L   0x00005            1

ตารางหน้าที่กำหนดให้กับกระบวนการ 1 โดยระบบปฏิบัติการที่PT2 = 0x80000000( 0x80000* 4K):

RAM location      physical address   present
---------------   -----------------  --------
PT2 + 0     * L   0x0000A            1
PT2 + 1     * L   0x0000C            1
PT2 + 2     * L                      0
...                                  ...
PT2 + 0x3FF * L   0x00003            1

ที่ไหน:

  • PD1: ตำแหน่งเริ่มต้นของไดเรกทอรีหน้าของกระบวนการ 1 บน RAM
  • PT1และPT2: ตำแหน่งเริ่มต้นของตารางหน้า 1 และตารางหน้า 2 สำหรับกระบวนการ 1 บน RAM

ดังนั้นในตัวอย่างนี้ไดเร็กทอรีเพจและตารางเพจสามารถเก็บไว้ใน RAM ได้เช่น:

----------------> 0xFFFFFFFF


----------------> PT2 + 0x3FF * L
Page Table 1
----------------> PT2

----------------> PD1 + 0x3FF * L
Page Directory 1
----------------> PD1


----------------> PT1 + 0x3FF * L
Page Table 2
----------------> PT1

----------------> 0x0

มาแปลที่อยู่เชิงเส้น0x00801004ทีละขั้นตอน

เราคิดว่าcr3 = PD1นั่นคือมันชี้ไปที่ไดเรกทอรีเพจที่อธิบายไว้

ในไบนารีแอดเดรสเชิงเส้นคือ:

0    0    8    0    1    0    0    4
0000 0000 1000 0000 0001 0000 0000 0100

การจัดกลุ่มตามที่10 | 10 | 12ให้:

0000000010 0000000001 000000000100
0x2        0x1        0x4

ซึ่งจะช่วยให้:

  • รายการไดเรกทอรีหน้า = 0x2
  • รายการตารางหน้า = 0x1
  • ชดเชย = 0x4

ดังนั้นฮาร์ดแวร์จึงมองหารายการ 2 ของไดเรกทอรีเพจ

0x80000 * 4K = 0x80000000ตารางไดเรกทอรีหน้ากล่าวว่าตารางหน้าตั้งอยู่ที่ นี่เป็นการเข้าถึง RAM ครั้งแรกของกระบวนการ

ตั้งแต่รายการตารางหน้าเป็น0x1ฮาร์ดแวร์ที่มีลักษณะที่รายการ 1 ของตารางหน้าที่ซึ่งจะบอกว่าที่หน้าทางกายภาพตั้งอยู่ที่อยู่0x80000000 0x0000C * 4K = 0x0000C000นี่เป็นการเข้าถึง RAM ครั้งที่สองของกระบวนการ

0x0000C004สุดท้ายฮาร์ดแวร์เพจเพิ่มชดเชยและที่อยู่สุดท้ายคือ

ตัวอย่างอื่น ๆ ของที่อยู่ที่แปล ได้แก่ :

linear    10 10 12 split   physical
--------  ---------------  ----------
00000001  000 000 001      00001001
00001001  000 001 001      page fault
003FF001  000 3FF 001      00005001
00400000  001 000 000      page fault
00800001  002 000 001      0000A001
00801008  002 001 008      0000C008
00802008  002 002 008      page fault
00B00001  003 000 000      page fault

ข้อบกพร่องของเพจเกิดขึ้นหากไม่มีรายการไดเร็กทอรีเพจหรือรายการตารางเพจ

หากระบบปฏิบัติการต้องการเรียกใช้กระบวนการอื่นไปพร้อมกันระบบจะให้กระบวนการที่สองแยกไดเรกทอรีหน้าและเชื่อมโยงไดเรกทอรีนั้นเพื่อแยกตารางหน้า

สถาปัตยกรรม 64 บิต

64 บิตยังคงเป็นแอดเดรสที่มากเกินไปสำหรับขนาด RAM ในปัจจุบันดังนั้นสถาปัตยกรรมส่วนใหญ่จะใช้บิตน้อยลง

x86_64 ใช้ 48 บิต (256 TiB) และ PAE ของโหมดดั้งเดิมอนุญาตที่อยู่ 52 บิต (4 PiB) แล้ว

12 จาก 48 บิตเหล่านั้นถูกสงวนไว้สำหรับออฟเซ็ตซึ่งเหลือ 36 บิต

หากใช้แนวทาง 2 ระดับการแบ่งที่ดีที่สุดคือสองระดับ 18 บิต

แต่นั่นหมายความว่าไดเร็กทอรีเพจจะมี2^18 = 256Kรายการซึ่งจะใช้ RAM มากเกินไป: ใกล้เคียงกับการเพจระดับเดียวสำหรับสถาปัตยกรรม 32 บิต!

ดังนั้นสถาปัตยกรรม 64 บิตจึงสร้างระดับหน้าได้มากขึ้นโดยทั่วไปคือ 3 หรือ 4

x86_64 ใช้ 4 ระดับใน9 | 9 | 9 | 12แบบแผนดังนั้นระดับบนจะขึ้นเฉพาะ2^9รายการระดับที่สูงกว่าเท่านั้น

PAE

ส่วนขยายที่อยู่ทางกายภาพ

ด้วย 32 บิตแรม 4GB เท่านั้นที่สามารถจัดการได้

สิ่งนี้เริ่มกลายเป็นข้อ จำกัด สำหรับเซิร์ฟเวอร์ขนาดใหญ่ดังนั้น Intel จึงนำกลไก PAE มาใช้กับ Pentium Pro

เพื่อบรรเทาปัญหา Intel ได้เพิ่มบรรทัดที่อยู่ใหม่ 4 บรรทัดเพื่อให้สามารถแก้ไขปัญหาได้ที่ 64GB

โครงสร้างตารางหน้าจะเปลี่ยนแปลงด้วยหากเปิด PAE วิธีที่แน่นอนในการเปลี่ยนแปลงนั้นขึ้นอยู่กับว่า PSE เปิดหรือปิดอยู่

PAE เปิดและปิดผ่านทางPAEบิตของcr4.

แม้ว่าหน่วยความจำแอดเดรสทั้งหมดจะเป็น 64GB แต่แต่ละกระบวนการก็ยังสามารถใช้งานได้สูงสุด 4GB เท่านั้น อย่างไรก็ตามระบบปฏิบัติการสามารถวางกระบวนการที่แตกต่างกันในชิ้น 4GB ที่แตกต่างกัน

PSE

ส่วนขยายขนาดหน้า

อนุญาตให้เพจมีความยาว 4M (หรือ 2M ถ้า PAE เปิดอยู่) แทนที่จะเป็น 4K

PSE เปิดและปิดผ่านPAEบิตของcr4.

โครงร่างตารางเพจ PAE และ PSE

หาก PAE และ PSE ทำงานอยู่จะใช้รูปแบบระดับการเพจที่แตกต่างกัน:

  • ไม่มี PAE และไม่มี PSE: 10 | 10 | 12

  • ไม่มี PAE และ 10 | 22PSE:

    22 คือค่าชดเชยภายในเพจ 4Mb เนื่องจาก 22 บิตแอดเดรส 4Mb

  • PAE และไม่มี PSE: 2 | 9 | 9 | 12

    เหตุผลในการออกแบบว่าทำไมต้องใช้ 9 สองครั้งแทนที่จะเป็น 10 คือตอนนี้รายการไม่สามารถใส่เป็น 32 บิตได้อีกต่อไปซึ่งทั้งหมดถูกเติมด้วยบิตแอดเดรส 20 บิตและบิตแฟล็กที่มีความหมายหรือสงวนไว้ 12 บิต

    เหตุผลก็คือ 20 บิตไม่เพียงพอที่จะแสดงที่อยู่ของตารางเพจอีกต่อไปแล้วตอนนี้จำเป็นต้องใช้ 24 บิตเนื่องจากมีการเพิ่มสายไฟพิเศษ 4 สายลงในโปรเซสเซอร์

    ดังนั้นนักออกแบบจึงตัดสินใจเพิ่มขนาดรายการเป็น 64 บิตและเพื่อให้พอดีกับตารางหน้าเดียวจึงจำเป็นต้องลดจำนวนรายการลงเหลือ 2 ^ 9 แทนที่จะเป็น 2 ^ 10

    2 เริ่มต้นคือระดับเพจใหม่ที่เรียกว่า Page Directory Pointer Table (PDPT) เนื่องจากชี้ไปที่ไดเรกทอรีเพจและกรอกแอดเดรสเชิงเส้น 32 บิต PDPT ยังมีความกว้าง 64 บิต

    cr3ตอนนี้ชี้ไปที่ PDPT ซึ่งต้องอยู่ในหน่วยความจำ 4GB สี่กำปั้นและจัดเรียงบน 32 บิตทวีคูณเพื่อประสิทธิภาพในการจัดการ ซึ่งหมายความว่าตอนนี้cr3มี 27 บิตสำคัญแทนที่จะเป็น 20: 2 ^ 5 สำหรับ 32 ทวีคูณ * 2 ^ 27 เพื่อทำให้ 2 ^ 32 ของ 4GB แรกสมบูรณ์

  • PAE และ PSE: 2 | 9 | 21

    นักออกแบบตัดสินใจที่จะเก็บช่องกว้าง 9 บิตเพื่อให้พอดีกับหน้าเดียว

    ซึ่งจะเหลือ 23 บิต การออกจาก 2 สำหรับ PDPT เพื่อให้สิ่งต่าง ๆ สม่ำเสมอด้วยเคส PAE โดยไม่มี PSE ออกจาก 21 สำหรับออฟเซ็ตหมายความว่าหน้ากว้าง 2M แทนที่จะเป็น 4M

TLB

Translation Lookahead Buffer (TLB) เป็นแคชสำหรับเพจแอดเดรส

เนื่องจากเป็นแคชจึงแชร์ปัญหาการออกแบบหลายอย่างของแคชของ CPU เช่นระดับการเชื่อมโยง

ส่วนนี้จะอธิบาย TLB ที่เชื่อมโยงอย่างสมบูรณ์แบบง่ายพร้อมด้วยรายการที่อยู่เดียว 4 รายการ โปรดทราบว่าเช่นเดียวกับแคชอื่น ๆ TLB จริงมักจะไม่เชื่อมโยงกันอย่างสมบูรณ์

การทำงานพื้นฐาน

หลังจากการแปลระหว่างที่อยู่เชิงเส้นและที่อยู่จริงเกิดขึ้นจะถูกจัดเก็บไว้ใน TLB ตัวอย่างเช่น TLB 4 รายการเริ่มต้นในสถานะต่อไปนี้:

  valid   linear   physical
  ------  -------  ---------
> 0       00000    00000
  0       00000    00000
  0       00000    00000
  0       00000    00000

>บ่งชี้รายการปัจจุบันจะถูกแทนที่

และหลังจากที่อยู่เชิงเส้นของหน้า00003ถูกแปลเป็นที่อยู่จริง00005TLB จะกลายเป็น:

  valid   linear   physical
  ------  -------  ---------
  1       00003    00005
> 0       00000    00000
  0       00000    00000
  0       00000    00000

และหลังจากแปลเป็นครั้งที่สอง00007จะ00009กลายเป็น:

  valid   linear   physical
  ------  -------  ---------
  1       00003    00005
  1       00007    00009
> 0       00000    00000
  0       00000    00000

ตอนนี้ถ้า00003ต้องมีการแปลอีกครั้งฮาร์ดแวร์แรกมีลักษณะขึ้น TLB 00003 --> 00005และพบว่าที่อยู่ที่มีการเข้าถึง

แน่นอน00000ว่าไม่ได้อยู่ใน TLB เนื่องจากไม่มีรายการที่ถูกต้อง00000เป็นคีย์

นโยบายการเปลี่ยน

เมื่อเติม TLB แล้วที่อยู่เก่าจะถูกเขียนทับ เช่นเดียวกับแคชของ CPU นโยบายการแทนที่คือการดำเนินการที่อาจซับซ้อน แต่การหาสาเหตุที่เรียบง่ายและสมเหตุสมผลคือการลบรายการที่ใช้น้อยที่สุด (LRU)

ด้วย LRU เริ่มต้นจากรัฐ:

  valid   linear   physical
  ------  -------  ---------
> 1       00003    00005
  1       00007    00009
  1       00009    00001
  1       0000B    00003

การเพิ่ม0000D -> 0000Aจะให้:

  valid   linear   physical
  ------  -------  ---------
  1       0000D    0000A
> 1       00007    00009
  1       00009    00001
  1       0000B    00003

ลูกเบี้ยว

การใช้ TLB ทำให้การแปลเร็วขึ้นเนื่องจากการแปลเริ่มต้นใช้การเข้าถึงหนึ่งครั้งต่อระดับ TLBซึ่งหมายถึง 2 ในรูปแบบ 32 บิตแบบธรรมดา แต่ 3 หรือ 4 ในสถาปัตยกรรม 64 บิต

TLB มักจะใช้เป็นแรมราคาแพงที่เรียกว่า content-addressable memory (CAM) CAM ใช้การเชื่อมโยงแผนที่บนฮาร์ดแวร์นั่นคือโครงสร้างที่กำหนดคีย์ (ที่อยู่เชิงเส้น) ดึงค่า

นอกจากนี้ยังสามารถใช้การแมปกับที่อยู่ RAM ได้ แต่การแมป CAM อาจต้องใช้รายการน้อยกว่าการแมป RAM

ตัวอย่างเช่นแผนที่ที่:

  • ทั้งคีย์และค่ามี 20 บิต (ในกรณีของโครงร่างการเพจทั่วไป)
  • ต้องจัดเก็บไม่เกิน 4 ค่าในแต่ละครั้ง

สามารถจัดเก็บใน TLB ได้ 4 รายการ:

linear   physical
-------  ---------
00000    00001
00001    00010
00010    00011
FFFFF    00000

อย่างไรก็ตามในการใช้สิ่งนี้กับ RAM จำเป็นต้องมีที่อยู่ 2 ^ 20 :

linear   physical
-------  ---------
00000    00001
00001    00010
00010    00011
... (from 00011 to FFFFE)
FFFFF    00000

ซึ่งจะแพงกว่าการใช้ TLB ด้วยซ้ำ

รายการไม่ถูกต้อง

เมื่อมีcr3การเปลี่ยนแปลงรายการ TLB ทั้งหมดจะไม่ถูกต้องเนื่องจากจะมีการใช้ตารางหน้าใหม่สำหรับกระบวนการใหม่ดังนั้นจึงไม่น่าเป็นไปได้ที่รายการเก่า ๆ จะมีความหมาย

x86 ยังมีinvlpgคำสั่งที่ทำให้รายการ TLB รายการเดียวเป็นโมฆะอย่างชัดเจน สถาปัตยกรรมอื่นเสนอคำแนะนำเพิ่มเติมสำหรับรายการ TLB ที่ไม่ถูกต้องเช่นการทำให้รายการทั้งหมดในช่วงที่กำหนด

บางซีพียู x86 ไปเกินความต้องการของสเปค x86 และให้การเชื่อมโยงกันมากขึ้นกว่าที่รับประกัน, ระหว่างการปรับเปลี่ยนรายการตารางหน้าและใช้มันเมื่อมันถูกไม่แคแล้วใน TLB เห็นได้ชัดว่า Windows 9x ใช้สิ่งนั้นเพื่อความถูกต้อง แต่ซีพียู AMD ที่ทันสมัยไม่ได้ให้การเดินหน้าที่สอดคล้องกัน ซีพียูของ Intel ทำได้แม้ว่าจะต้องตรวจจับการคาดเดาที่ผิดพลาดเพื่อทำเช่นนั้น การใช้ประโยชน์จากสิ่งนี้อาจเป็นความคิดที่ไม่ดีเนื่องจากอาจมีไม่มากนักที่จะได้รับและมีความเสี่ยงสูงที่จะก่อให้เกิดปัญหาที่ละเอียดอ่อนเกี่ยวกับเวลาซึ่งยากที่จะแก้ไขข้อบกพร่อง

การใช้งานเคอร์เนล Linux

เคอร์เนลลินุกซ์ใช้ประโยชน์จากคุณสมบัติการเพจของ x86 อย่างกว้างขวางเพื่อให้สามารถสลับกระบวนการที่รวดเร็วด้วยการกระจายข้อมูลขนาดเล็ก

ในv4.2ดูภายใต้arch/x86/:

  • include/asm/pgtable*
  • include/asm/page*
  • mm/pgtable*
  • mm/page*

ดูเหมือนว่าจะไม่มีโครงสร้างที่กำหนดเพื่อแสดงเพจมีเพียงมาโครเท่านั้นที่include/asm/page_types.hน่าสนใจเป็นพิเศษ ข้อความที่ตัดตอนมา:

#define _PAGE_BIT_PRESENT   0   /* is present */
#define _PAGE_BIT_RW        1   /* writeable */
#define _PAGE_BIT_USER      2   /* userspace addressable */
#define _PAGE_BIT_PWT       3   /* page write through */

arch/x86/include/uapi/asm/processor-flags.hกำหนดCR0และโดยเฉพาะPGตำแหน่งบิต:

#define X86_CR0_PG_BIT      31 /* Paging */

บรรณานุกรม

ฟรี:

  • rutgers-pxk-416บท "การจัดการหน่วยความจำ: บันทึกการบรรยาย"

    การทบทวนเทคนิคการจัดระเบียบหน่วยความจำในอดีตที่ดีซึ่งใช้โดย OS รุ่นเก่า

ไม่ฟรี:

  • bovet05บท "ที่อยู่หน่วยความจำ"

    การแนะนำที่อยู่หน่วยความจำ x86 ที่สมเหตุสมผล พลาดตัวอย่างที่ดีและเรียบง่าย


คำตอบที่ดี แต่ฉันยังไม่ชัดเจนว่า LRU ตัดสินใจอย่างไร การเรียกใช้ระบบปฏิบัติการทุกครั้งที่มีการเข้าถึงเพจอื่นที่ไม่ใช่ MRU ดูเหมือนจะมีราคาแพง อีกวิธีหนึ่งฉันสามารถเห็นฮาร์ดแวร์ที่จัดลำดับตารางเพจใหม่สำหรับ LRU ซึ่งอาจเป็นอันตรายสำหรับโปรแกรมที่ทำงานพร้อมกัน ข้อใดข้อหนึ่งถูกต้องหรือไม่? ระบบปฏิบัติการจะทราบได้อย่างไรว่าเพจใดคือ LRU เมื่อเกิดความผิดพลาดของเพจ
Keynan

@Keynan ฉันคิดว่ามันเป็นฮาร์ดแวร์ที่ทำดังนั้นเวลาที่ใช้จึงไม่ต้องกังวล สำหรับการทำงานพร้อมกันฉันไม่รู้ว่ามันจัดการอย่างไร ฉันคิดว่ามี CR3 และแคชหนึ่งตัวต่อโปรเซสเซอร์และระบบปฏิบัติการต้องตรวจสอบให้แน่ใจว่าหน้าหน่วยความจำไม่ทับซ้อนกัน
Ciro Santilli 郝海东冠状病六四事件法轮功

1
real TLBs are not usually fully associativeThe TLB is usually implemented as … CAMข้อความทั้งสองนี้ขัดแย้งกันไม่ใช่หรือ?
a3f

>>> x86_64 ใช้ 4 ระดับใน 9 | 9 | 9 | 12 รูปแบบควรเป็น 9 | 9 | 9 | 9 | 12?
monklof

@monklof ฉันคิดว่าสิ่งนี้ถูกต้อง: 9 9 9 12 อนุญาต RAM 512GB แล้ว โครงร่างระดับ 5 เป็นการพัฒนาล่าสุดที่มุ่งเป้าไปที่เซิร์ฟเวอร์เท่านั้นซึ่งมีการกล่าวถึงในคำตอบในเว็บไซต์ของฉันซึ่งเป็นข้อมูลล่าสุด
Ciro Santilli 郝海东冠状病六四事件法轮功

22

นี่คือคำตอบสั้น ๆ ระดับสูง:

โปรเซสเซอร์ x86 ทำงานในโหมดที่เป็นไปได้หลายโหมด (โดยประมาณ: จริงป้องกัน 64 บิต) แต่ละโหมดสามารถใช้หนึ่งในโมเดลการกำหนดแอดเดรสหน่วยความจำที่เป็นไปได้หลายแบบ (แต่ไม่ใช่ทุกโหมดที่สามารถใช้ได้ทุกโมเดล) ได้แก่ การกำหนดแอดเดรสโหมดจริงการกำหนดแอดเดรสแบบแบ่งส่วนและการกำหนดแอดเดรสเชิงเส้นแบบแบน

ในโลกสมัยใหม่เฉพาะการกำหนดแอดเดรสเชิงเส้นแบบแบนในโหมดป้องกันหรือโหมด 64 บิตเท่านั้นที่เกี่ยวข้องและทั้งสองโหมดมีความเหมือนกันโดยหลักความแตกต่างคือขนาดของคำเครื่องและจำนวนหน่วยความจำที่ระบุได้

ตอนนี้โหมดการกำหนดแอดเดรสหน่วยความจำให้ความหมายกับตัวถูกดำเนินการหน่วยความจำของคำสั่งเครื่อง (เช่นmov DWORD PTR [eax], 25ซึ่งเก็บdwordจำนวนเต็ม32 บิต (aka ) ของค่า 25 ไว้ในหน่วยความจำที่แอดเดรสถูกเก็บไว้ในeaxรีจิสเตอร์ 32 บิต) ในการกำหนดแอดเดรสเชิงเส้นตรงจำนวนนี้ในeaxได้รับอนุญาตให้ทำงานในช่วงเดียวที่ต่อเนื่องกันตั้งแต่ศูนย์ถึงค่าสูงสุด (ในกรณีของเราคือ 2 32  - 1)

อย่างไรก็ตามการกำหนดแอดเดรสเชิงเส้นแบบแบนสามารถเป็นเพจหรือไม่เพจก็ได้ หากไม่มีการเพจแอดเดรสจะอ้างถึงหน่วยความจำฟิสิคัลโดยตรง ด้วยการเพจหน่วยจัดการหน่วยความจำของโปรเซสเซอร์ (หรือ MMU) จะป้อนแอดเดรสที่ต้องการอย่างโปร่งใส (ปัจจุบันเรียกว่าแอดเดรสเสมือน ) ลงในกลไกการค้นหาตารางเพจที่เรียกว่าและรับค่าใหม่ซึ่งตีความว่าเป็นฟิสิคัลแอดเดรส ตอนนี้การดำเนินการดั้งเดิมทำงานกับที่อยู่ใหม่ที่แปลแล้วในหน่วยความจำกายภาพแม้ว่าผู้ใช้จะเห็นที่อยู่เสมือน

ประโยชน์หลักของการเพจคือตารางเพจได้รับการจัดการโดยระบบปฏิบัติการ ดังนั้นระบบปฏิบัติการจึงสามารถแก้ไขและแทนที่ตารางเพจได้ตามอำเภอใจเช่นเมื่อ "สลับภารกิจ" สามารถเก็บตารางเพจทั้งหมดไว้สำหรับ "กระบวนการ" แต่ละชุดและเมื่อใดก็ตามที่ตัดสินใจว่ากระบวนการใดจะทำงานบน CPU ที่กำหนดก็จะโหลดตารางหน้าของกระบวนการลงใน MMU ของ CPU นั้น (CPU แต่ละตัวมีของตัวเอง ชุดของตารางหน้า) ผลที่ได้คือแต่ละกระบวนการจะเห็นพื้นที่ที่อยู่เสมือนของตัวเองซึ่งมีลักษณะเหมือนกันไม่ว่าหน้าฟิสิคัลใดจะว่างเมื่อระบบปฏิบัติการต้องจัดสรรหน่วยความจำให้ มันไม่เคยรู้เกี่ยวกับหน่วยความจำของกระบวนการอื่นเนื่องจากไม่สามารถเข้าถึงหน่วยความจำกายภาพได้โดยตรง

ตารางเพจเป็นโครงสร้างข้อมูลแบบต้นไม้ที่ซ้อนกันซึ่งเก็บไว้ในหน่วยความจำปกติซึ่งเขียนโดยระบบปฏิบัติการ แต่อ่านโดยฮาร์ดแวร์โดยตรงดังนั้นรูปแบบจึงได้รับการแก้ไข พวกเขา "โหลด" ลงใน MMU โดยการตั้งค่าทะเบียนควบคุม CPU พิเศษให้ชี้ไปที่ตารางระดับบนสุด ซีพียูใช้แคชที่เรียกว่า TLB เพื่อจดจำการค้นหาดังนั้นการเข้าถึงซ้ำ ๆ ไปยังหน้าสองสามหน้านั้นจะเร็วกว่าการเข้าถึงแบบกระจัดกระจายมากด้วยเหตุผลที่พลาด TLB รวมถึงเหตุผลแคชข้อมูลตามปกติ เป็นเรื่องปกติที่จะเห็นคำว่า "รายการ TLB" ใช้เพื่ออ้างถึงรายการตารางหน้าแม้ว่าจะไม่ได้ถูกแคชไว้ใน TLB ก็ตาม

และในกรณีที่คุณกังวลว่ากระบวนการอาจปิดการใช้งานเพจหรือพยายามแก้ไขตารางเพจ: สิ่งนี้ไม่ได้รับอนุญาตเนื่องจาก x86 ใช้ระดับสิทธิ์ (เรียกว่า "แหวน") และรหัสผู้ใช้จะดำเนินการในระดับสิทธิ์ที่ต่ำเกินไปที่จะอนุญาต เพื่อแก้ไขตารางเพจของ CPU

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.