หน่วยความจำสูงและหน่วยความจำเหลือน้อยบน Linux คืออะไร


92

ฉันสนใจความแตกต่างระหว่าง Highmem และ Lowmem:

  1. ทำไมถึงมีความแตกต่างเช่นนี้?
  2. เราได้อะไรจากการทำเช่นนั้น?
  3. แต่ละคุณสมบัติมีอะไรบ้าง

@hiro คุณหมายถึง "HIGHMEM" คือ "เคอร์เนลที่อยู่เสมือน" ตามที่อธิบายโดย ldd3 ฉันเห็นด้วยกับคุณ. มันทำให้เกิดความสับสน ldd3 กำหนด "LOWMEM" "HIGHMEM" ยังกำหนด "ที่อยู่เสมือนเคอร์เนล" "เคอร์เนลที่อยู่ตรรกะ" มันเป็นสิ่งเดียวกัน แต่มีชื่อแตกต่างกัน นั่นคือ "ความงาม" ของซอฟต์แวร์มันเป็นคำอธิบายที่ขึ้นอยู่กับภาษา
สตีฟ

คำตอบ:


69

บนสถาปัตยกรรม 32 บิตช่วงพื้นที่ที่อยู่สำหรับการกำหนดแอดเดรส RAM คือ:

0x00000000 - 0xffffffff

หรือ4'294'967'295(4 GB)

เคอร์เนล linux จะแยกออกเป็น 3/1 (อาจเป็น 2/2 หรือ 1/3 1 ) ในพื้นที่ผู้ใช้ (หน่วยความจำสูง) และพื้นที่เคอร์เนล (หน่วยความจำต่ำ) ตามลำดับ

ช่วงพื้นที่ของผู้ใช้:

0x00000000 - 0xbfffffff

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

ช่วงพื้นที่เคอร์เนล:

0xc0000000 - 0xffffffff

กระบวนการเคอร์เนลได้รับที่อยู่ (ช่วง) ที่นี่ เคอร์เนลสามารถเข้าถึงที่อยู่ 1 GB นี้ได้โดยตรง (ไม่ใช่เต็ม 1 GB มี 128 MB สงวนไว้สำหรับการเข้าถึงหน่วยความจำสูง)

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

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


1ไม่ว่าการแบ่งจะเป็น 3/1, 2/2 หรือ 1/3 ถูกควบคุมโดยCONFIG_VMSPLIT_...ตัวเลือก คุณสามารถตรวจสอบภายใต้/boot/config*เพื่อดูตัวเลือกที่เลือกสำหรับเคอร์เนลของคุณ


นี่คือรุ่นเก่าและฉันไม่แน่ใจว่าคุณอยู่ที่นี่ แต่ฉันต้องการถามสิ่งหนึ่ง: 128MB ที่สงวนไว้ในพื้นที่เคอร์เนล (สำหรับการเข้าถึงหน่วยความจำสูง) มันคือทั้งหมดอ้างอิงของพื้นที่หน่วยความจำพื้นที่ผู้ใช้? ดังนั้นกระบวนการเคอร์เนลสามารถเข้าถึงพื้นที่ผู้ใช้ใด ๆ โดยอ้างถึงพื้นที่นี้ใช่ไหม
Amumu

1
ทำไมมันเป็น 1/4 เสมอ คือทำไมมันไม่แบ่ง 5/1 หรือบางสิ่งบางอย่าง?
mgalgs

"เข้าถึงโดยตรง" หมายความว่าอะไรที่นี่? ฉันหมายความว่าเคอร์เนลไม่สามารถเข้าถึงได้ผ่านกลไกหน่วยความจำเสมือนใช่หรือไม่
telenn

1
ฉันเชื่อว่าสิ่งที่คุณพูดเกี่ยวกับหน่วยความจำสูง / ต่ำผิด: ฉันเชื่อว่าในระบบ 32 บิตที่บริสุทธิ์เคอร์เนลสามารถเข้าถึงพื้นที่ผู้ใช้เต็มรูปแบบ 3GB โดยตรง (เคอร์เนลสามารถเข้าถึงพื้นที่เคอร์เนลและพื้นที่ผู้ใช้) อย่างไรก็ตามเมื่อคุณมีเคอร์เนล PAE มีความซับซ้อนมากขึ้นตอนนี้คุณมี RAM มากกว่า 3GB แต่ละกระบวนการสามารถเป็น 3GB และคุณไม่สามารถเข้าถึงพื้นที่ผู้ใช้ทั้งหมดได้โดยตรง นี่คือที่ mem สูงและหน่วยความจำ 128MB ในพื้นที่เคอร์เนลเข้ามาด้วยเคอร์เนล 64 บิตจะง่ายขึ้นอีกครั้งไม่มีชายสูงเนื่องจากพื้นที่ผู้ใช้ทั้งหมดสามารถเข้าถึงได้จากเคอร์เนล
ctrl-alt-delor

2
@mgalgs ¼, 2/4 และ¾เป็นเพียงตัวเลือกเริ่มต้นที่เปิดเผย ตั้งแต่ปี 2007 หนึ่งสามารถเลือก 5/16 และ 15/32 หากคุณรู้ว่าจะแก้ไข #define บรรทัดใดคุณสามารถเลือกแยกส่วนของคุณเองได้ตามอำเภอใจ
jørgensen

28

การอ้างอิงแรกหันไปเป็นไดรเวอร์อุปกรณ์ Linux (ใช้ได้ทั้งแบบออนไลน์และในรูปแบบหนังสือ) โดยเฉพาะอย่างยิ่งบทที่ 15ซึ่งมีส่วนในหัวข้อ

ในโลกอุดมคติอุดมคติทุกองค์ประกอบของระบบจะสามารถแมปหน่วยความจำทั้งหมดที่จำเป็นต้องเข้าถึงได้ และนี่เป็นกรณีสำหรับกระบวนการบน Linux และระบบปฏิบัติการส่วนใหญ่: กระบวนการแบบ 32 บิตสามารถเข้าถึงหน่วยความจำเสมือนน้อยกว่า 2 ^ 32 ไบต์ได้เพียงเล็กน้อย (อันที่จริงแล้วประมาณ 3GB บนสถาปัตยกรรม Linux 32 บิตโดยทั่วไป) มันยากสำหรับเคอร์เนลซึ่งจะต้องสามารถแมปหน่วยความจำเต็มของกระบวนการที่ระบบเรียกว่ากำลังดำเนินการรวมทั้งหน่วยความจำกายภาพทั้งหมดรวมถึงอุปกรณ์ฮาร์ดแวร์ที่แมปหน่วยความจำอื่น ๆ

ดังนั้นเมื่อเคอร์เนลแบบ 32 บิตต้องการแมปหน่วยความจำมากกว่า 4GB ก็จะต้องมีการคอมไพล์ด้วยการรองรับหน่วยความจำสูง หน่วยความจำสูงคือหน่วยความจำที่ไม่ได้ถูกแมปอย่างถาวรในพื้นที่ที่อยู่ของเคอร์เนล (หน่วยความจำต่ำเป็นสิ่งที่ตรงกันข้าม: มันถูกแมปอยู่เสมอดังนั้นคุณจึงสามารถเข้าถึงได้ในเคอร์เนลเพียงแค่ยกเลิกการลงทะเบียนตัวชี้)

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


2
ขอบคุณ Gilles สำหรับคำตอบ .. แต่ฉันยังคงไม่สามารถรับแนวคิดทั้งหมดได้ คุณช่วยได้ง่ายขึ้นอีกเล็กน้อยโดยไม่ลดข้อมูลลงไปไหม?
Sen

17

สิ่งนี้เกี่ยวข้องกับเคอร์เนล Linux ฉันไม่แน่ใจว่า Unix kernel จัดการกับมันอย่างไร

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

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

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

แหล่งข้อมูลเพิ่มเติม:


4

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

แผนที่หน่วยความจำเสมือนแบบ 32 บิต Linux โดยทั่วไปมีลักษณะดังนี้:

  • 0x00000000-0xbfffffff: กระบวนการผู้ใช้ (3GB)

  • 0xc0000000-0xffffffff: พื้นที่เคอร์เนล (1GB)

(เวกเตอร์เฉพาะซีพียูและสิ่งใดก็ตามจะถูกละเว้นที่นี่)

Linux แบ่งพื้นที่เคอร์เนล 1GB เป็น 2 ชิ้นคือ LOWMEM และ HIGHMEM การแยกแตกต่างกันไปตั้งแต่การติดตั้งจนถึงการติดตั้ง

หากการติดตั้งเลือกพูด 512MB-512MB สำหรับ LOW และสูง mems 512MB LOWMEM (0xc0000000-0xdfffffff) จะถูกแมปแบบคงที่ในเวลาบูตเคอร์เนล โดยปกติแล้วไบต์แรก ๆ ของหน่วยความจำฟิสิคัลจำนวนมากจะถูกใช้เพื่อการนี้เพื่อให้ที่อยู่เสมือนและฟิสิคัลในช่วงนี้มีออฟเซ็ตคงที่เช่น 0xc0000000

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


3

เท่าที่ฉันจำได้ "High Memory" ใช้สำหรับพื้นที่แอพพลิเคชันและ "Low Memory" สำหรับเคอร์เนล

ข้อดีคือแอปพลิเคชัน (พื้นที่ผู้ใช้) ไม่สามารถเข้าถึงหน่วยความจำเคอร์เนลพื้นที่


0

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

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

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