2 คะแนน โดย GN⁺ 17 일 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • macOS บน Apple Silicon จำกัด macOS VM ที่รันได้ผ่าน Virtualization.framework ไว้สูงสุด 2 เครื่อง โดยอิงตามข้อกำหนดในสัญญาอนุญาตใช้งาน macOS
  • จากการวิเคราะห์พบว่าข้อจำกัดนี้ถูกจัดการด้วย ตัวแปรไม่เปิดเผย hv_apple_isa_vm_quota ภายในเคอร์เนล XNU และสามารถเขียนทับได้ผ่านบูตอาร์กิวเมนต์
  • มีการใช้ขั้นตอน สร้างและบูต Development Kernel เพื่อข้ามการตรวจสอบ AppleInternal ของ System Integrity Protection
  • หลังตั้งค่าแล้ว สามารถรัน macOS VM ได้พร้อมกันสูงสุด 9 เครื่อง บน UTM, Viable, Parallels และอื่น ๆ ได้สำเร็จ
  • ประเด็นที่น่าสนใจคือ Apple ยังคงทิ้งฟังก์ชันสำหรับเขียนทับข้อจำกัด VM ไว้ในเคอร์เนล และมีการเสนอความเป็นไปได้ในการปรับปรุงต่อผ่านเครื่องมืออัตโนมัติหรือ kernel extension

ขั้นตอนปลดข้อจำกัด macOS VM 2 เครื่องบน Apple Silicon

  • เมื่อรัน macOS virtual machine บน Mac ที่ใช้ Apple Silicon ด้วย Virtualization.framework จะมี ข้อจำกัดให้รันได้สูงสุดเพียง 2 เครื่อง
    • ข้อจำกัดนี้ถูกตั้งไว้ตามข้อ 2.B.iii ของสัญญาอนุญาตใช้งานซอฟต์แวร์ macOS (SLA)
    • ข้อกำหนดดังกล่าวอนุญาตให้รัน macOS instance ได้สูงสุด 2 ชุดสำหรับการพัฒนา การทดสอบ การใช้งาน macOS Server และการใช้งานส่วนบุคคลแบบไม่เชิงพาณิชย์
  • จากการวิเคราะห์พบว่าข้อจำกัดนี้ไม่ได้ถูกติดตั้งไว้ใน user space แต่ถูกติดตั้งไว้ใน ส่วนภายในที่ไม่เปิดเผยของเคอร์เนล XNU
    • ในเคอร์เนลฝั่ง Intel ไม่มีโค้ดชุดเดียวกันนี้ และชุดฟังก์ชัน hv_vm_* ของเคอร์เนล Apple Silicon เป็นผู้ดูแล virtualization stack
    • ตัวแปร hv_apple_isa_vm_quota ภายในโค้ดเริ่มต้น hv_init() เป็นตัวจัดการจำนวน VM และจะเพิ่มหรือลดค่าเมื่อมีการสร้างหรือลบ VM
    • ในเคอร์เนลมีบูตอาร์กิวเมนต์ hypervisor= และ hv_apple_isa_vm_quota= อยู่ โดยตัวหลังสามารถใช้เขียนทับข้อจำกัดจำนวน VM ได้
  • ใน release kernel การใช้อาร์กิวเมนต์ hypervisor ถูกจำกัดด้วยการตรวจสอบ AppleInternal ของ System Integrity Protection (SIP)
    • อาร์กิวเมนต์ hv_apple_isa_vm_quota จะมีผลก็ต่อเมื่อเปิดใช้งานแฟลก CSR_ALLOW_APPLE_INTERNAL
    • เพื่อข้ามจุดนี้ จึงใช้วิธีบูต Development Kernel ของ Apple

การสร้าง Development Kernel Collection

  • ต้องดาวน์โหลดและติดตั้ง Kernel Debug Kit (KDK) จากเว็บไซต์ Apple Developer
    • KDK ต้องตรงกับ build ของ macOS บนเครื่องโฮสต์อย่างแม่นยำ ไม่เช่นนั้นอาจเกิดข้อผิดพลาดในการลิงก์เคอร์เนล·kext และการบูต
  • หลังตรวจสอบสถาปัตยกรรมเคอร์เนลด้วยคำสั่ง uname แล้ว ให้ใช้คำสั่ง kmutil create เพื่อสร้าง Development Kernel Collection (VirtualMachine.kc)
    • ตัวอย่างนี้ใช้ macOS 14.0 (build 23A5301h) และเคอร์เนล T6020
    • ใช้ตัวเลือก --variant-suffix development เพื่อระบุ development kernel และรวมที่เก็บ system extension หลายชุดเข้าไว้ด้วย

การตั้งค่าบูต Development Kernel

  • ปิดเครื่อง Mac แล้วบูตเข้า recoveryOS เพื่อทำการตั้งค่าต่อไปนี้ในเทอร์มินัล
    1. ปิด System Integrity Protection (csrutil disable)
    2. ปลดข้อจำกัดบูตอาร์กิวเมนต์ (bputil --disable-boot-args-restriction)
    3. ระบุ custom kernel collection (kmutil configure-boot)
    4. ตั้งค่าบูตอาร์กิวเมนต์ (ส่งผ่านด้วยคำสั่ง nvram)
      • kcsuffix=development : บูต development kernel
      • hypervisor=0x1 : เปิดใช้ความสามารถพิเศษของ virtualization stack
      • hv_apple_isa_vm_quota=0xFF : ตั้งจำนวน VM สูงสุดเป็น 255
  • หลังรีบูต สามารถตรวจสอบการนำค่าไปใช้ได้ด้วย sysctl kern.osbuildconfig และ nvram boot-args

ผลลัพธ์การรันหลาย VM พร้อมกัน

  • หลังตั้งค่าเสร็จ ได้ทำการทดสอบด้วยโซลูชันที่อิงกับ Virtualization.framework เช่น UTM, Viable, Parallels
    • บน M2 Pro MacBook Pro สามารถรัน macOS VM พร้อมกัน 9 เครื่อง ได้สำเร็จ
    • ระบบยังคงทำงานได้ในระดับที่สามารถทดสอบต่อได้

ช่วงเวลาที่เพิ่มฟังก์ชันนี้และโครงสร้างภายใน

  • บูตอาร์กิวเมนต์ hv_apple_isa_vm_quota ถูกเพิ่มเข้ามาพร้อมกับ virtualization stack ตั้งแต่ macOS 12 Monterey
    • ในเวอร์ชันถัดมา (รวมถึง macOS Sonoma) การตรวจสอบ AppleInternal ก็ยังคงมีอยู่
    • ยืนยันได้ว่า Apple ยังคงเก็บฟังก์ชันที่ไม่เปิดเผยหลายอย่างไว้ภายใน XNU

ข้อควรระวังเมื่ออัปเดต OS

  • เมื่อใช้ custom kernel collection ฟังก์ชัน อัปเดต OS อัตโนมัติจะถูกปิดใช้งาน
    • หากอัปเดตในสภาพนี้จะเกิดข้อผิดพลาด ดังนั้นจึงต้อง กู้กลับไปใช้ kernel collection เริ่มต้น ก่อน
    • ในโหมดกู้คืนสามารถสร้าง boot policy ใหม่ด้วย bputil เพื่อกลับไปใช้เคอร์เนลเริ่มต้นได้
    • ตัวอย่าง: ใช้ตัวเลือก bputil --full-security หรือ --disable-boot-args-restriction

บทสรุปและแนวคิดสำหรับการปรับปรุงในอนาคต

  • มีการตรวจสอบวิธีที่ Apple ใช้บังคับข้อจำกัด VM และทดลองยืนยัน วิธีปลดข้อจำกัดแบบไม่เป็นทางการ ได้สำเร็จ
    • แม้ทีม Virtualization จะไม่ได้จัดทำเอกสารอย่างเป็นทางการ แต่การที่ ฟังก์ชันเขียนทับข้อจำกัด VM ยังคงอยู่ในเคอร์เนล เป็นจุดที่น่าสนใจ
  • แนวคิดการปรับปรุงในอนาคต
    • พัฒนา เครื่องมืออัตโนมัติสำหรับการสร้างและบูต KC
      • รองรับการสร้าง development kernel collection อัตโนมัติตามโฮสต์แต่ละเครื่อง และช่วยตั้งค่าในโหมดกู้คืน
    • พัฒนาฟังก์ชันเขียนทับตัวแปร hv_apple_isa_vm_quota ผ่าน kernel extension (kext)
      • สำรวจความเป็นไปได้ในการปลดข้อจำกัดโดยไม่ต้องบูต development kernel
  • งานวิจัยถัดไปจะสำรวจ ความเป็นไปได้ในการ override การลงทะเบียน DEP และ serial number ของ Apple Silicon VM

1 ความคิดเห็น

 
GN⁺ 17 일 전
ความคิดเห็นจาก Hacker News
  • ข้อจำกัดแบบนี้ที่ใช้เหมือนกันกับ Mac ทุกเครื่องนั้น ไร้เหตุผล มาก
    ถ้าซื้อ Mac ที่แรงกว่า ก็ควรจะทำ virtualization ของ macOS ได้หลายอินสแตนซ์มากขึ้น
    เช่น อาจจำกัด M5 ไว้ที่ 2 เครื่อง, M5 Pro ที่ 4 เครื่อง, M5 Max ที่ 8 เครื่อง แบบนี้ยังฟังดูสมเหตุสมผลกว่า

    • ไม่เข้าใจเลยว่าทำไมต้องมีข้อจำกัดตั้งแต่แรก
      ประสิทธิภาพของฮาร์ดแวร์ก็คือขีดจำกัดตามธรรมชาติอยู่แล้ว ผู้ใช้จะหยุดกันเอง
    • นี่ดูไม่ใช่ปัญหาเรื่องทรัพยากร แต่เป็น การตัดสินใจทางธุรกิจ มากกว่า
      มีแนวโน้มว่าน่าจะทำมาเพื่อกันไม่ให้มีบริการ Mac VPS ราคาถูก
    • สิ่งที่กำลังสู้ด้วยไม่ใช่ข้อจำกัดของฮาร์ดแวร์ แต่คือ ความกังวลเรื่องยอดขายของ Tim Cook
    • ซื้อไลเซนส์ Windows 11 Pro 100 ดอลลาร์ แล้วข้อจำกัด VM คือ 1024 เครื่อง
      Hyper‑V สามารถรัน VM พร้อมกันได้สูงสุด 1024 เครื่อง ถ้าฮาร์ดแวร์รับไหว
      แม้แต่บนโน้ตบุ๊ก Windows ARM เครื่องเล็กของฉันก็ยังรัน 4 เครื่องได้สบาย
    • เหลือเชื่อจริง ๆ
      ฉันรัน VM เพื่อทดสอบ openclaw แต่กลับต้องงงเพราะ การเข้าถึง iCloud และ App Store ถูกจำกัด
  • น่าสนใจที่ 2 ปีหลังจาก Mykola Grymalyuk เขียนบล็อกโพสต์นี้ เขาก็เข้าทำงานที่ Apple
    ทำให้นึกถึงมีม “ตายในฐานะฮีโร่ หรือไม่ก็…”

  • ตั้งแต่ M3 ขึ้นไป สามารถรัน nested VM ได้ด้วย Hypervisor.framework / Virtualization.framework
    ถ้ามันใช้ข้ามข้อจำกัดนี้ได้ก็คงน่าสนุกทีเดียว

    • ถ้าจำไม่ผิด การ nested ทำได้เฉพาะ Linux guest
      ส่วน macOS ทำได้แค่หนึ่งชั้น จึงไม่สามารถเปิด macOS guest อีกตัวภายใน macOS guest ได้
    • ถ้าแต่ละ VM รัน VM ได้อีก 2 ตัว ก็อาจสร้าง โซ่ VM แบบไม่สิ้นสุด ได้เลย
      ฉันขี้เกียจลองเอง แต่อยากให้มีใครสักคนทดลองให้ดู
  • อยากรู้จริง ๆ ว่าทำไม Apple ถึงใส่ข้อจำกัดแบบนี้

    • โมเดลธุรกิจ ของ Apple คือการขายฮาร์ดแวร์ควบคู่กับซอฟต์แวร์
      รายได้จากฮาร์ดแวร์ช่วยสนับสนุนการพัฒนาซอฟต์แวร์ ดังนั้นบริษัทจึงไม่อยากให้คนที่ไม่ได้ซื้อฮาร์ดแวร์มาใช้ macOS
    • macOS มี ข้อจำกัดต่อผู้ใช้ แบบนี้อยู่มาก
      การที่ Apple รักษาอำนาจควบคุมไว้สำคัญกว่าความอิสระของผู้ใช้
    • อาจเป็นมาตรการเพื่อกันไม่ให้ใช้ Mac เครื่องเดียวรัน ฟาร์มบัญชีออนไลน์ (identity farm) ก็ได้
  • น่าทึ่งที่สามารถคอมไพล์ custom kernel, บูตมันขึ้นมา แล้วเปิด GUI ได้ด้วย

  • ตัวบทความเองน่าสนใจมาก แต่การใช้แพลตฟอร์มที่มี ข้อจำกัดตามอำเภอใจ แบบนี้เพื่อการพัฒนาก็ดูแปลก

    • ตลอด 20 ปีที่ผ่านมา Apple เคยเป็นแพลตฟอร์มสำหรับนักพัฒนาอย่างจริงจังหรือเปล่าก็ยังน่าสงสัย
      นักพัฒนาจำนวนมากใช้มันเพราะฮาร์ดแวร์ระดับสูง แต่ macOS ก็เป็น “เกือบจะ Linux แต่เป็น OS ที่ถูกควบคุมโดยบริษัทที่มี iTunes เป็นศูนย์กลาง” มาโดยตลอด
  • บน Apple Silicon ถ้าใช้ custom kernel collection จะทำให้ อัปเดต OS อัตโนมัติ ไม่ได้
    แต่บางทีมันอาจเป็น พรแฝง ก็ได้

  • สงสัยว่านี่จะใช้ได้กับ lume ด้วยไหม
    ตอนนี้มันก็มีข้อจำกัดคล้ายกันอยู่

    • น่าจะได้
      ถ้าจำไม่ผิด lume เป็น ตัวห่อแบบบาง ๆ ของ Apple Virtualization.framework
  • เคยได้ยินว่าถ้าปิด SIP แล้วตั้ง boot args ก็ทำได้โดยไม่ต้องใช้ custom kernel

    • ถ้าเรื่องนี้จริง นี่คือ ทิปที่ถูกประเมินค่าต่ำเกินไป
  • Apple จำกัด VM ไว้ที่ 2 เครื่องเหรอ?

    • ใช่, ตามไลเซนส์ macOS VM ได้แค่ 2 เครื่อง
      แต่ guest OS อื่นสามารถรันได้แบบไม่จำกัด