เจาะลึก Darwin OS และเคอร์เนล XNU ของ Apple
(tansanrao.com)- ระบบปฏิบัติการ Darwin ของ Apple คือแกนกลางตระกูล Unix ที่เป็นรากฐานของระบบปฏิบัติการสมัยใหม่ของ Apple อย่าง macOS และ iOS
- หัวใจสำคัญคือเคอร์เนล XNU ซึ่งเป็นเคอร์เนลแบบไฮบริดที่มีชื่อย่อมาจาก "X is Not Unix"
- มันผสานโครงสร้างของไมโครเคอร์เนล Mach เข้ากับองค์ประกอบของ BSD Unix เพื่อสร้างสมดุลระหว่างประสิทธิภาพและความเป็นโมดูลาร์
- บทความนี้อธิบายกระบวนการพัฒนาเชิงโครงสร้างของ Darwin และ XNU ตั้งแต่รากฐานของ Mach และ BSD ไปจนถึงวิวัฒนาการล่าสุดบน Apple Silicon
- วิเคราะห์องค์ประกอบหลักของเคอร์เนล เช่น IPC, การจัดตารางเวลา, การจัดการหน่วยความจำ, เวอร์ชวลไลเซชัน และการปรับตัวให้เข้ากับฮาร์ดแวร์สมัยใหม่
จุดกำเนิดของไมโครเคอร์เนล Mach (1985–1996)
- Mach เริ่มต้นขึ้นในปี 1985 ที่ Carnegie Mellon University โดย Richard Rashid และ Avie Tevanian
- มันถูกออกแบบเป็นไมโครเคอร์เนลที่ให้เฉพาะฟังก์ชันหลัก เพื่อลดความซับซ้อนของเคอร์เนล UNIX
- ให้เพียงฟังก์ชันระดับล่าง เช่น การจัดการหน่วยความจำ, การจัดตารางเวลาแบบเธรด, IPC แบบส่งข้อความ ขณะที่ระบบไฟล์และเครือข่ายถูกแยกออกไปเป็นเซิร์ฟเวอร์ใน user space
- Mach 2.5 รันร่วมกับโค้ดบางส่วนของเคอร์เนล BSD ใน kernel space เพื่อชดเชยด้านประสิทธิภาพ
- Mach 3.0 เปลี่ยนผ่านไปเป็นไมโครเคอร์เนลอย่างแท้จริง และยังส่งอิทธิพลต่อการจัดการหน่วยความจำของ BSD
- Mach นำแนวคิดของ Task และ Thread มาใช้ และสร้างโมเดลหน่วยความจำเสมือนที่มีประสิทธิภาพ
- NeXT (ก่อตั้งโดย Steve Jobs ในปี 1985) พัฒนา NeXTSTEP OS บนพื้นฐานของ Mach 2.5 + 4.3BSD
- เคอร์เนลของ NeXTSTEP ผสาน Mach และ BSD ภายใน kernel space เพื่อสร้างโครงสร้างแบบไฮบริด
- ไดรเวอร์ถูกพัฒนาด้วย DriverKit ที่อิง Objective-C โดยพยายามใช้แนวทางเชิงวัตถุ
- Apple เข้าซื้อ NeXT ในปี 1996 และนำ NeXTSTEP พร้อมเคอร์เนล XNU ที่อิง Mach/BSD มาด้วย
- Mac OS X รุ่นแรก ๆ (Rhapsody) ถูกพัฒนาบนพื้นฐานโครงสร้างเคอร์เนลของ NeXT
วิวัฒนาการช่วงแรกของ Mac OS X (1997–2005)
- Apple รวมโค้ด Mach 3.0 ที่อิง OSFMK 7.3 เข้ากับ XNU และอัปเดตชั้น BSD ด้วยโค้ดจาก FreeBSD และ 4.4BSD
- ยังคงรักษาโครงสร้างแบบไฮบริดที่ฝังความสามารถของ BSD และ Mach ไว้ภายใน เพื่อปรับปรุงประสิทธิภาพและรองรับฮาร์ดแวร์ได้กว้างขึ้น
- เปิดตัวเฟรมเวิร์กไดรเวอร์ใหม่ I/O Kit: เปลี่ยนจาก Objective-C ไปใช้ C++ เพื่อเพิ่มประสิทธิภาพและรองรับ hot-plugging
- สรุปคุณลักษณะสำคัญของแต่ละเวอร์ชัน:
- 10.1 Puma (2001): รองรับเธรดแบบเรียลไทม์, ปรับปรุงประสิทธิภาพ
- 10.2 Jaguar (2002): เพิ่ม IPv6, IPSec, Bonjour และ HFS+ journaling
- 10.3 Panther (2003): ปรับปรุงเคอร์เนลบนพื้นฐาน FreeBSD 5, เพิ่ม fine-grained locking เพื่อรองรับมัลติคอร์
- XNU รองรับ PowerPC เป็นหลัก แต่ยังคงมีโค้ดรองรับ x86 เพื่อเตรียมพร้อมสำหรับการเปลี่ยนผ่านในอนาคต
- 10.4 Tiger (2005): ได้รับการรับรอง UNIX 03, วางรากฐานสำหรับการเปลี่ยนไปใช้ Intel, และนำระบบเหตุการณ์ kqueue/kevent มาใช้
ยุค 64 บิต, มัลติคอร์ และ iPhone OS (2005–2010)
- 10.5 Leopard (2007):
- รองรับ x86_64 และไดรเวอร์ 64 บิต
- เพิ่มความสามารถด้านความปลอดภัยและดีบัก เช่น ASLR, sandbox และ DTrace
- เป็นเวอร์ชันสุดท้ายที่รองรับ PowerPC อย่างเป็นทางการ
- iPhone OS 1 (2007):
- อิง Darwin 9 และพอร์ต XNU ไปยัง ARM
- เพิ่มกลไก Jetsam เพื่อรับมือกับหน่วยความจำไม่เพียงพอ
- บังคับใช้ sandbox กับทุกแอปและกำหนดให้ต้องมี code signing
- 10.6 Snow Leopard (2009):
- ใช้ได้เฉพาะ Intel และรองรับเคอร์เนล 64 บิตอย่างสมบูรณ์
- นำ Grand Central Dispatch มาใช้: เฟรมเวิร์ก parallel task ใน user space ที่ทำงานร่วมกับเคอร์เนล
- ผสาน OpenCL และรองรับการประมวลผลด้วย GPU
- iOS 4 (2010):
- เพิ่มมัลติทาสก์และการจัดตารางเวลาตามลำดับความสำคัญ (แยก background/foreground)
การทำให้ macOS และ iOS ทันสมัย (2011–2020)
- 10.8~10.9 (2012–2013):
- เพิ่ม Compressed Memory เพื่อเพิ่มประสิทธิภาพการใช้ RAM
- ใช้ Timer Coalescing เพื่อประหยัดพลังงาน CPU
- พัฒนาการจัดตารางเวลาที่เน้นประสิทธิภาพพลังงาน เช่น App Nap และ QoS
- 10.10~10.11 (2014–2015):
- เพิ่ม SIP(System Integrity Protection): แม้มีสิทธิ์ root ก็ไม่สามารถแก้ไขไฟล์ระบบได้
- วางรากฐานให้ XNU ขยายไปยังอุปกรณ์หลากหลาย เช่น watchOS และ tvOS
- รองรับ ARM64 และเริ่มเตรียมยุติการรองรับ ARM 32 บิต
- 10.12~10.14 (2016–2018):
- เปลี่ยนระบบไฟล์ไปใช้ APFS(Apple File System)
- รองรับ snapshot, cloning และการเข้ารหัส
- เสริมความปลอดภัยของ kext: ต้องได้รับการอนุมัติจากผู้ใช้ และตรวจสอบ code signing เข้มงวดยิ่งขึ้น
- 10.15 Catalina (2019):
- เพิ่ม DriverKit: ให้ไดรเวอร์ทำงานใน user space (ย้อนกลับไปสู่แนวคิดไมโครเคอร์เนล)
- แยกระบบวอลุ่มแบบอ่านอย่างเดียวเพื่อเพิ่มความปลอดภัย
ยุค Apple Silicon (2020–ปัจจุบัน)
-
macOS 11 Big Sur (2020):
- รองรับ Apple Silicon (M1) บนพื้นฐาน ARM64
- รองรับการจัดตารางเวลาแบบ big.LITTLE CPU: กระจายงานไปยังคอร์ประสิทธิภาพ/คอร์แรงตาม QoS
- โครงสร้าง Mach VM เหมาะกับสถาปัตยกรรมหน่วยความจำรวม
-
การเสริมความปลอดภัยและเวอร์ชวลไลเซชัน:
- รองรับฟีเจอร์ความปลอดภัยฮาร์ดแวร์ ARM เช่น PAC(pointer authentication) และ MTE(memory tagging)
- เปิดตัวเฟรมเวิร์กเวอร์ชวลไลเซชันใหม่โดยอาศัยความสามารถไฮเปอร์ไวเซอร์ของ Apple Silicon
- บน macOS สามารถรัน VM แบบเบาสำหรับนักพัฒนาได้ (ควบคุมจาก user space)
-
โครงสร้างแพลตฟอร์มแบบรวมศูนย์:
- XNU ถูกใช้เป็นเคอร์เนลของทุกแพลตฟอร์ม Apple ไม่ว่าจะเป็น macOS, iOS, watchOS, tvOS, bridgeOS และ visionOS
- ด้วยการทำ abstraction ของ Mach จึงปรับตัวเข้ากับสถาปัตยกรรม CPU ที่หลากหลายได้ง่าย
สรุปไทม์ไลน์สำคัญของ XNU
- 1989 - NeXTSTEP 1.0 - นำโครงสร้างไฮบริด XNU จาก Mach 2.5 + BSD มาใช้
- 1996 - Apple เข้าซื้อ NeXT - เริ่มพัฒนา Rhapsody บนพื้นฐาน Mach 3.0 + FreeBSD
- 2001 - Mac OS X 10.0 - วางโครงสร้างเคอร์เนล XNU และปรับปรุงประสิทธิภาพช่วงแรก
- 2005 - 10.4 Tiger - ได้รับการรับรอง UNIX และเตรียมพร้อมสู่การเปลี่ยนผ่านไป Intel
- 2007 - 10.5 Leopard - รองรับ 64 บิต, เพิ่มความปลอดภัย, iPhone OS ปรากฏตัว
- 2009 - 10.6 Snow Leopard - เปลี่ยนผ่านสู่ Intel อย่างสมบูรณ์ และนำ GCD มาใช้
- 2011 - 10.7 Lion - บังคับใช้เคอร์เนล 64 บิต และขยาย sandboxing
- 2013 - 10.9 Mavericks - เพิ่ม memory compression และการจัดตารางเวลาแบบ QoS
- 2015 - 10.11 El Capitan - เพิ่ม SIP และขยายไปสู่อุปกรณ์อย่าง watchOS
- 2017 - 10.13 High Sierra - ใช้ APFS เป็นค่าเริ่มต้น และเพิ่มความปลอดภัยของ Kext
- 2019 - 10.15 Catalina - ให้ไดรเวอร์ทำงานใน user space ผ่าน DriverKit
- 2020 - 11 Big Sur - รองรับ Apple Silicon และนำโครงสร้างเวอร์ชวลไลเซชันใหม่มาใช้
- 2022 - 13 Ventura - ปรับปรุงการจัดตารางเวลาให้รองรับคอร์ประสิทธิภาพสูงอย่าง M1 Max
- 2024 - 14 Sonoma - ปรับแต่งสำหรับ M2/M3 และรองรับ Memory Tagging
โครงสร้างและการออกแบบของเคอร์เนล XNU
การออกแบบเคอร์เนลแบบไฮบริด: ผสาน Mach + BSD
- XNU มีโครงสร้างเคอร์เนลแบบไฮบริดที่รวมคุณลักษณะของทั้งไมโครเคอร์เนล (Mach) และโมโนลิธิกเคอร์เนล (BSD)
- Mach ทำหน้าที่ abstraction และ modularization ของฟังก์ชันระดับล่าง (เธรด, หน่วยความจำ, IPC ฯลฯ) ขณะที่ BSD รัน system call และ API แบบ UNIX ทั้งหมดโดยตรงใน kernel space
- BSD และ Mach ถูกลิงก์เป็นเคอร์เนลไบนารีเดียวและทำงานใน address space เดียวกัน
- ภายในเคอร์เนล ฟังก์ชันของ Mach และ BSD เรียกหากันได้โดยตรงโดยไม่ต้องส่งข้อความ และ system call แบบ UNIX จึงได้ประสิทธิภาพระดับเคอร์เนลยูนิกซ์ทั่วไป
- ตัวอย่าง: เมื่อเรียก system call
read()โค้ดระบบไฟล์ของ BSD จะทำงานในเคอร์เนลโดยตรง
บทบาทของ Mach
- ให้โครงสร้างพื้นฐานหลักของเคอร์เนล เช่น การจัดการเธรดและ task, context switching, scheduling queue และ timer
- ให้ IPC แบบส่งข้อความผ่าน Mach port (รองรับการแชร์หน่วยความจำระหว่างโปรเซสและการส่งบัฟเฟอร์ขนาดใหญ่)
- ดำเนินการฟังก์ชันการจัดการหน่วยความจำเสมือนขั้นสูง เช่น memory object, การเพิ่มประสิทธิภาพแบบ copy-on-write และ abstraction ของ address space
บทบาทของ BSD
- ให้ความสามารถแบบ UNIX เช่น process และ PID, signal, user ID, POSIX API, ระบบไฟล์, network stack และ UNIX IPC
- มีที่มาจากโค้ด BSD บนพื้นฐาน FreeBSD และยังรวมความสามารถจาก OpenBSD/NetBSD ด้วย
- ใช้นโยบายความปลอดภัย เช่น security framework (KAuth, MAC), sandbox, SIP และการตรวจสอบ code signing
- การทำ system call:
fork()จะทำการคัดลอก VM ใน Mach และคัดลอก file descriptor ใน BSD เป็นต้น - รับผิดชอบความสามารถแบบ UNIX ส่วนใหญ่ เช่น ระบบไฟล์ (VFS), เครือข่าย, การจัดการ signal และ POSIX thread
I/O Kit
- เฟรมเวิร์กไดรเวอร์เชิงวัตถุที่ทำงานใน kernel space (ใช้ Embedded Subset ของ C++)
- กำหนดลำดับชั้นของอุปกรณ์ และให้แต่ละไดรเวอร์สืบทอดไปใช้งาน
- ให้ user client interface ที่เข้าถึงได้จาก user space
- การซิงโครไนซ์และการควบคุมเธรดในเคอร์เนลอาศัยฟังก์ชันของ Mach ขณะที่ไดรเวอร์ระบบไฟล์และเครือข่ายเชื่อมกับ BSD
- ไดรเวอร์สามารถโหลดแบบไดนามิกเป็น Kext ได้ และถูกโหลดเข้า kernel memory ในรูปแบบ Mach-O
Mach IPC และการส่งข้อความ
- Mach port คือกลไก IPC หลักระหว่างเคอร์เนลกับ user space หรือระหว่างโปรเซสผู้ใช้ด้วยกัน
- แต่ละโปรเซสสามารถถูกควบคุมผ่าน Mach port ได้ และ system daemon อย่าง launchd ก็ใช้ port ในการควบคุมโปรเซส
- ฟีเจอร์ขั้นสูงของ macOS เช่น Grand Central Dispatch และ XPC ถูกสร้างขึ้นบนพื้นฐานของ Mach message
- Mach message มีระบบสิทธิ์ของ port จึงมีความปลอดภัยสูง และรองรับการส่งต่อ port กับการส่ง shared memory
- MIG(Mach Interface Generator) ใช้สร้างโค้ด RPC แบบส่งข้อความระหว่างเคอร์เนลกับผู้ใช้โดยอัตโนมัติ
- DriverKit ใช้ Mach IPC เป็นพื้นฐานในการสื่อสารระหว่างเคอร์เนลกับไดรเวอร์ใน user space
ตัวจัดตารางเวลาและการจัดการเธรด
- พัฒนามาจากตัวจัดตารางเวลาแบบ round-robin ตามลำดับความสำคัญบนพื้นฐาน Mach
- แต่ละ CPU มี Run Queue ของตัวเอง และเธรดจะถูกจัดตารางเวลาตามลำดับความสำคัญ
- หลังการมาของ iOS ได้มีนโยบายจัดตารางเวลาตามบทบาทของแอป (background/foreground)
- การจัดตารางเวลาแบบอิงคลาส QoS(Quality of Service): ปรับลำดับความสำคัญตามลักษณะงาน เช่น งานโต้ตอบกับผู้ใช้หรืองานเบื้องหลัง
- บน Apple Silicon จะจัดสรรเธรดไปยังคอร์ประหยัดพลังงานหรือคอร์สมรรถนะสูงตาม QoS
- เธรดเรียลไทม์ (เช่น งานเสียง) จะถูกรันก่อนผ่านคิวเรียลไทม์ และตั้งแต่ macOS 10.4 ก็รองรับ deadline scheduling
- ทำงานร่วมกับระบบจัดการพลังงาน: เช่น idle thread, timer coalescing และการเข้าสู่โหมดประหยัดพลังงาน เพื่อเพิ่มประสิทธิภาพบนอุปกรณ์พกพา
การจัดการหน่วยความจำและหน่วยความจำเสมือน
- Mach VM คือองค์ประกอบหลักของระบบหน่วยความจำใน XNU และมีการออกแบบที่ทรงพลังและยืดหยุ่น
- พื้นที่ address เสมือนใช้แนวคิด copy-on-write ทำให้สามารถคัดลอกหน่วยความจำได้อย่างมีประสิทธิภาพเมื่อเรียก fork()
- โครงสร้าง Memory Object และ Pager:
- เดมอน
dynamic_pagerใน user space ทำหน้าที่จัดการพื้นที่ swap - file mapping ถูกจัดการภายในเคอร์เนลผ่าน vnode pager
- เดมอน
- ตั้งแต่ Mavericks ได้เพิ่ม compressed memory: เมื่อหน่วยความจำไม่พอ จะบีบอัดเพจเก็บไว้แทนการ swap ลงดิสก์
- pmap: ชั้นที่ขึ้นกับเครื่องซึ่งดูแล physical memory และ page table ของแต่ละสถาปัตยกรรม
- เคอร์เนลมี address space แยกต่างหาก และบางพื้นที่ถูกกำหนดเป็นหน่วยความจำแบบ wired
- macOS เสริมความปลอดภัยหน่วยความจำด้วย guard page สำหรับดีบัก, การจัดสรรแบบ zero-fill และการป้องกันการแบ่งส่วน
- Mach VM จัดการสิ่งต่าง ๆ อย่างมีประสิทธิภาพ เช่น shared memory และการตั้งค่า inheritance สำหรับการแชร์เฟรมเวิร์ก
- บน Apple Silicon พื้นที่ GPU และหน่วยความจำถูกรวมเข้าด้วยกัน ทำให้ Mach VM ปรับการจัดสรรตามคุณลักษณะของหน่วยความจำได้อย่างเหมาะสม
การรองรับเวอร์ชวลไลเซชัน
- XNU เดิมไม่มีความสามารถด้านไฮเปอร์ไวเซอร์ แต่เริ่มรองรับเวอร์ชวลไลเซชันผ่าน Hypervisor.framework ตั้งแต่ OS X 10.10
- บนระบบ Intel สามารถใช้ VT-x เพื่อรัน VM ใน user space ได้
- บน Apple Silicon ที่ใช้ ARM จะใช้ความสามารถเวอร์ชวลไลเซชันระดับ EL2 ผ่าน Virtualization.framework
- ไฮเปอร์ไวเซอร์ภายในเคอร์เนลรับผิดชอบ virtual memory, การจัดการ trap ของ vCPU และการจัดตารางเวลา
- ใช้โครงสร้างเธรดของ XNU และ Mach task เพื่อจัดการ vCPU ในฐานะ host thread
- macOS ยังมีความสามารถจำลอง x86 อย่าง Rosetta 2 พร้อมการแปล syscall และความเข้ากันได้ระดับ ABI
- ตั้งแต่ iOS 15 เป็นต้นมา iOS ก็อนุญาตให้ใช้เวอร์ชวลไลเซชันได้ในรูปแบบจำกัด (ต้องเปิด developer mode)
โครงสร้างการประมวลผลด้านความปลอดภัย
- Secure Enclave:
- ซับซิสเต็มความปลอดภัยอิสระที่ถูกรวมอยู่ใน Apple SoC
- รันไมโครเคอร์เนลแยกต่างหากชื่อ sepOS เพื่อปกป้องข้อมูลชีวมิติ, กุญแจเข้ารหัส และข้อมูลสำคัญอื่น ๆ
- แม้เคอร์เนลหลักจะถูกโจมตี ก็ยังคงรักษากระบวนการความปลอดภัยแบบแยกส่วนไว้ได้
- Exclaves:
- พื้นที่แยกใหม่ที่เริ่มนำมาใช้ตั้งแต่ macOS 14.4 และ iOS 17
- แยกทรัพยากรอ่อนไหว เช่น การยืนยันตัวตน Apple ID, audio buffer และข้อมูลเซนเซอร์ ออกจากเคอร์เนลหลัก
- ควบคุมผ่าน Kext และเฟรมเวิร์กเฉพาะ เช่น
ExclaveKextClient.kext - แม้เคอร์เนลจะเสียหาย พื้นที่ exclave ก็ยังได้รับการปกป้องอย่างอิสระ
- enclave สะท้อนแนวคิดของพื้นที่ที่อยู่ภายในระบบ ส่วน exclave คือพื้นที่แยกที่เชื่อมต่ออยู่นอกระบบ
บทสรุป
- XNU คือเคอร์เนลที่มีโครงสร้างไฮบริดเชิงปฏิบัติ ซึ่งประนีประนอมข้อดีของทั้งไมโครเคอร์เนลและโมโนลิธิกเคอร์เนล
- ชั้น abstraction ของ Mach ทำให้การย้ายผ่านสถาปัตยกรรม CPU ที่หลากหลายและการขยายระบบเป็นไปได้ ขณะที่ BSD มอบความเข้ากันได้กับ POSIX และสภาพแวดล้อม Unix ที่เสถียร
- Apple ใช้ Mach IPC เพื่อแยกฟังก์ชันออกไปยัง user space เมื่อจำเป็น และเชื่อมส่วนภายในเคอร์เนลโดยตรงเพื่อประสิทธิภาพ
- ด้วยสถาปัตยกรรมหลายชั้น เช่น ไดรเวอร์แบบ user-space ผ่าน DriverKit, เวอร์ชวลไลเซชันผ่าน Hypervisor.framework, ตัวจัดตารางเวลาแบบ QoS และการจัดการหน่วยความจำแบบ Compressed Memory ทำให้มันตอบสนองความต้องการของระบบสมัยใหม่ได้อย่างยืดหยุ่น
- Darwin และ XNU เริ่มต้นจาก NeXTSTEP ก่อนจะพัฒนากลายเป็นแกนหลักของอุปกรณ์ Apple หลายร้อยล้านเครื่อง และยังคงวิวัฒน์ต่อไป
ยังไม่มีความคิดเห็น