- เป็นระบบปฏิบัติการทดลองแบบกราฟิกที่พัฒนาด้วย Rust ทั้งหมด โดยใช้การออกแบบแบบ unikernel และ โมเดลความปลอดภัยแบบ WASM-based sandboxing
- เคอร์เนล, WASM engine และแอปทั้งหมดถูกฝังอยู่ใน EFI ไบนารี ทำให้มี โครงสร้างที่ย่อเล็กลงและอินเทอร์เฟซ system call ที่ไม่เหมือนใคร
- ทำงานบน QEMU ผ่าน ไดรเวอร์ที่อิงกับ VirtIO โดยการจัดการอินพุต เครือข่าย และ GPU ถูกออกแบบแบบ polling โดยไม่ใช้อินเทอร์รัพท์
- รองรับโครงสร้างการทำงานที่เรียบง่ายและการมอนิเตอร์ทรัพยากรแยกตามแอปผ่าน global event loop และ cooperative scheduling
- มาพร้อม UI toolkit ชื่อ Uitk และแอปในตัว (เว็บเบราว์เซอร์, โปรแกรมแก้ไขข้อความ, Python terminal) พร้อมรองรับการพัฒนาแอป WASM ได้จากหลายภาษา
Munal OS คืออะไร
- Munal OS เป็น ระบบปฏิบัติการเชิงทดลอง ที่พัฒนาด้วย Rust ทั้งหมด เป็นโปรเจ็กต์ที่สร้างขึ้นเพื่อสำรวจการออกแบบ OS แบบใหม่ โดยผสานสถาปัตยกรรมที่อิงกับ unikernel เข้ากับ WASM sandboxing
- มีเป้าหมายเพื่อลดความซับซ้อนและคงไว้เฉพาะองค์ประกอบที่จำเป็น เพื่อให้ได้โครงสร้างระบบที่กระชับด้วยเครื่องมือสมัยใหม่
คุณสมบัติหลัก
- รองรับ สภาพแวดล้อมแบบกราฟิกเต็มรูปแบบ และ ความละเอียดระดับ HD พร้อมอินเทอร์เฟซเมาส์และคีย์บอร์ด
- รันแอปแบบ sandbox เพื่อป้องกันไม่ให้แอปผู้ใช้เข้าถึงหน่วยความจำของเคอร์เนล
- มี network driver และ TCP stack ของตัวเอง ในตัว
- มี UI toolkit (Uitk) ที่ปรับแต่งได้ รองรับวิดเจ็ตหลากหลาย เลย์เอาต์ยืดหยุ่น และการเรนเดอร์ข้อความ
- แอปที่มีมาให้: เว็บเบราว์เซอร์ (รองรับ DNS, HTTPS, HTML ขั้นพื้นฐาน), โปรแกรมแก้ไขข้อความ, Python terminal
สถาปัตยกรรม
-
โครงสร้างแบบ EFI ไบนารี
- ทำงานในรูปแบบ EFI ไบนารี โดยไม่ใช้ bootloader และฝังเคอร์เนล/WASM engine/แอปทั้งหมดไว้ในไฟล์เดียว
- UEFI boot services จะถูกปิดใช้งานให้เร็วที่สุด และไม่มีการใช้งานเพิ่มเติมนอกจากนาฬิการะบบ
-
การจัดการ address space
- ไม่ใช้ virtual address space แต่ใช้ identity-mapped address ที่ UEFI ทิ้งไว้ตามเดิม
- ไม่มีการเปลี่ยน page table โดยอาศัย WASM sandboxing มาช่วยชดเชยด้านการปกป้องหน่วยความจำเคอร์เนลโดยตรง
-
ไดรเวอร์และการรองรับฮาร์ดแวร์
- แทนที่จะใช้ PS/2 หรือ VGA มีการพัฒนา PCI driver ขึ้นเองโดยตรงโดยใช้อิงตามสเปก VirtIO 1.1
- มีไดรเวอร์สำหรับ คีย์บอร์ด, เมาส์, เครือข่าย และ GPU
- ไม่ใช้อินเทอร์รัพท์ ไดรเวอร์ทั้งหมดถูกออกแบบให้ทำงานแบบ polling
- ยังไม่รองรับการทำงานบนฮาร์ดแวร์จริงนอกเหนือจาก QEMU และต้องมีการพัฒนาเพิ่มเติมในอนาคต
-
event loop และ scheduling
- ไม่รองรับ multi-core/interrupts โดยการทำงานทั้งหมดรันแบบเชิงเส้นอยู่ใน global event loop เดียว
- ในแต่ละลูปจะทำการ polling ไดรเวอร์เครือข่าย/อินพุต, รันเดสก์ท็อป UI และแอป, แล้วอัปเดต GPU framebuffer
- วิเคราะห์ประสิทธิภาพได้ง่าย เพราะสามารถวัดเวลาได้ในแต่ละรอบของลูป
- แอปต้องคืนการครอบครอง CPU ด้วยตนเอง งานที่ใช้เวลานานต้องยอมปล่อยการทำงานอย่างชัดเจน
- แม้จะอิงกับ cooperative scheduling แต่ก็อาจรองรับการบังคับหยุดแอปที่ทำงานผิดพลาดผ่าน ฟีเจอร์ fuel limit ของ Wasmi engine ได้ในอนาคต (ยังไม่พัฒนา)
โครงสร้างการรันแอปพลิเคชัน
- มี [Wasmi WASM engine] ฝังอยู่ภายใน เพื่อให้การรันแอปเป็น sandbox แบบสมบูรณ์และแยกจากเคอร์เนล
- มี system call API ให้ในระดับเคอร์เนล ทำให้แอปสามารถอ่าน mouse/key events, ใช้ TCP socket, แสดงผลผ่าน framebuffer เป็นต้น
- ผลลัพธ์การเรนเดอร์ของแอปจะถูก OS นำไปคอมโพสิตแล้วแสดงบนเดสก์ท็อป
- สร้างแอปได้ด้วยภาษาอื่นนอกเหนือจาก Rust ตราบใดที่รองรับการ build เป็น WASM ก็ไม่มีข้อจำกัดในการใช้งาน
- รองรับ WASI เพียงบางส่วน ไม่ได้สอดคล้องครบถ้วนทั้งหมด และมีเพียงการพัฒนาขั้นต่ำเพื่อใช้งาน external dependency หลัก ๆ
- มี log stream แยกตามแอป (คล้าย stdout) ซึ่งสามารถดูพร้อมการใช้ทรัพยากรได้ในมุมมอง ‘audit’ บนเดสก์ท็อป
UI toolkit (uitk)
- เป็น immediate-mode UI kit ที่พัฒนาขึ้นเองและใช้ทั้งใน Munal OS และแอป WASM
- มี วิดเจ็ตพื้นฐาน (ปุ่ม, progress bar, ตัวแก้ไขข้อความ, scroll canvas) และ triangle rasterizer
- ใช้การจัดสไตล์แบบรวมศูนย์บนพื้นฐานของ global stylesheet และรองรับการ override รายองค์ประกอบ
- มี ระบบแคชที่มีประสิทธิภาพ เพื่อป้องกันการ re-render ที่ไม่จำเป็น
- แบ่งแต่ละพื้นที่เป็น “tile” และใช้อัลกอริทึมตรวจจับการเปลี่ยนแปลงที่อิงกับกฎ mutability ของ Rust
สภาพแวดล้อมสำหรับการ build และรัน
- สามารถ build และรันได้บน Rust Nightly 2025-06-01 และ QEMU 10.0.0 ขึ้นไป
แหล่งอ้างอิงหลักและเครดิต
- Rust OS tutorial ของ Philipp Oppermann และเอกสารจาก OSDev Wiki
- ใช้งานโอเพนซอร์สสำคัญอย่าง Wasmi, smoltcp, Rustls, RustPython เป็นต้น
- ใช้ฟอนต์ ไอคอน และวอลเปเปอร์จากโอเพนซอร์สหลายชุด
ความหมายและจุดเด่นของ Munal OS
- การผสานโครงสร้างแบบ EFI ไบนารีเดี่ยวเข้ากับ sandboxing ที่ล้ำสมัย ช่วยชวนให้กลับมาทบทวนกระบวนทัศน์การออกแบบ OS แบบเดิม
- ปรับให้เหมาะกับสภาพแวดล้อม QEMU และมี โครงสร้างไดรเวอร์แบบ polling ที่เป็นเอกลักษณ์ เพื่อลดการพึ่งพาฮาร์ดแวร์ของระบบจริง
- มี ความโปร่งใสในการจัดการทรัพยากรระบบ และมีคุณค่าอย่างมากในเชิงการเรียนรู้และการทดลองจากโครงสร้างที่เรียบง่าย
- มีศักยภาพสูงในการ ขยายระบบนิเวศแอป WASM โดยไม่จำกัดภาษาและสภาพแวดล้อม
1 ความคิดเห็น
ความเห็นจาก Hacker News
รู้สึกว่าน่าสนใจกับโครงสร้างที่ในแต่ละรอบจะคอย polling เครือข่ายและไดรเวอร์อินพุต วาดเดสก์ท็อปอินเทอร์เฟซ รัน WASM แอปที่เปิดใช้งานอยู่ทีละหนึ่งสเต็ป แล้วค่อย flush GPU framebuffer เลยไปค้นโค้ดดูว่าเขาทำสิ่งนี้ด้วย Wasmi อย่างไร ลิงก์โค้ด GitHub อยากบอกว่าบน Wasmi รุ่นใหม่ (v0.45+) ได้ขยายความสามารถของการเรียกฟังก์ชันแบบ resume ได้ เพื่อให้ yield ตอน fuel หมดได้ ลิงก์เอกสาร Wasmi ในเมื่อใช้ fuel metering อยู่แล้ว มันอาจเป็นวิธีที่มีประสิทธิภาพกว่าในขั้นรันก็ได้ ดูตัวอย่างการใช้งานได้จาก ตัวอย่าง Wasmi Wast runner
mallocใหม่แบบชัดเจนในสถานะที่ล้มเหลว ผมก็ยังสับสนว่าได้ประโยชน์ต่างกันตรงไหนมีการพูดถึงว่าเพราะพึ่งพา VirtIO อยู่ Munal OS จึงยังไม่ทำงานบนฮาร์ดแวร์จริง แต่ถ้าจะให้ไปรันบนฮาร์ดแวร์จริง แทนที่จะเพิ่มไดรเวอร์เอง ก็อาจใช้ Linux เป็น bootloader แล้วรันระบบปฏิบัติการบน minimal hypervisor ซึ่งเป็นแนวทางที่น่าสนุก วิธีนี้ทำให้คงคอนเซปต์ว่า “VirtIO คือแพลตฟอร์ม” เอาไว้ได้ โครงสร้างที่ใช้ WASM สำหรับรันแอป และใช้ VirtIO เป็นแพลตฟอร์ม ดูรักษาอัตลักษณ์ได้ดีมาก แต่ในมุมความปลอดภัยก็คงต้องใช้ MMU ถึงในเชิงดีไซน์อาจไม่จำเป็นต้องมี virtual memory เต็มรูปแบบ แต่แค่จะใช้ protection bits ก็ต้องมี page tables และการจัดการ TLB เพิ่มความซับซ้อนเข้ามา ทำให้ความเรียบง่ายลดลงบ้าง
คิดว่าข้อเสียที่ใหญ่กว่าการที่ลูปซ้ำต้องไม่ยึด CPU นานเกินไป และงานที่กินเวลานานต้อง
yieldอย่างชัดเจน ก็คือยิ่งเปิดแอปมาก ความเร็วในการประมวลผลของแต่ละแอปก็ยิ่งช้าลง ผมแทบไม่เคยเปิดเกิน 10 แอปพร้อมกัน แต่เคยเปิดแท็บได้ถึง 30 แท็บ ถ้าแต่ละอันเป็นโปรเซสจริง ประสิทธิภาพน่าจะตกลงชัดเจน ถ้าฮาร์ดแวร์เร็วพอก็คงไม่เป็นไร แต่กับงานหนักอย่างการเรนเดอร์วิดีโอ อาจช้าจาก 1 วินาทีเป็น 30 วินาทีจนรู้สึกได้มาก ถึงอย่างนั้น การทำทั้ง OS ด้วยแนวทางนี้ก็ยังเป็นอะไรที่ฉลาดมาก น่าทึ่ง และน่าตื่นเต้นจริง ๆyieldเองอย่างชัดเจนเมื่อเตรียมเฟรมเสร็จแล้ว ดังนั้นแอปที่ไม่มีอะไรต้องทำก็แทบไม่ใช้เวลาเลยนอกจาก cooperative scheduling แล้ว ก็ดูเหมือนการป้องกันการโจมตีแบบ Spectre จะทำได้ยาก และก็สงสัยว่าจะมีประสิทธิภาพได้จริงไหมถ้าไม่มี virtual memory เช่นตอนจัดการ
memory.growใน WASM ถ้าไปชนกับหน่วยความจำของแอปอื่น ก็อาจต้องmemmoveทั้งก้อน แบบนั้นจะทำได้จริงหรือเปล่า ถึงอย่างนั้นก็ยังเป็นโปรเจกต์ที่น่าประทับใจมากพอ wasm component ใช้งานได้จริงแล้ว ความพยายามแบบนี้จะเปลี่ยนไปอย่างไรบ้างก็น่าสนใจ ผมชื่นชมการออกแบบแบบ unikernel และก็ประทับใจกับความสามารถที่หลากหลายของ Munal OS ด้วย หวังว่าจะได้เห็น wasm ถูกใช้ไม่ใช่แค่กับแอปใหญ่เพียงตัวเดียว แต่ใช้โฮสต์โปรเซสเล็ก ๆ จำนวนมากและสภาพแวดล้อมย่อยต่าง ๆ ได้ด้วย ใน wasi preview3 ความเป็นไปได้ที่ sync/async จะอยู่ร่วมกันก็กำลังจะเปิดขึ้น และถ้าเป็นแบบนั้น wasm ก็จะมีองค์ประกอบของ runtime อเนกประสงค์ครบถ้วนอยู่แล้ว ยังเสียดายที่โลกของ host object bridging ยังหนักไปทาง JS แต่ก็หวังว่าคำสัญญาของ wasm component—มาตรฐาน, เบา, sandbox, และการประกอบข้ามภาษา—จะถูกทำให้เห็นในโลกจริงในฐานะความสามารถของ runtime ไม่ใช่แค่ฟอร์แมตสำหรับแจกจ่ายเพียงอย่างเดียว ลองดูทอล์กนี้ด้วย What is a Component (and Why)
ในทอล์ก “The Birth and Death of Javascript” ที่ Pycon 2014 ผมเห็นช่วงที่พูดถึงอนาคตของการทำ OS sandbox ด้วย asm.js (ต้นแบบของ wasm ในปัจจุบัน) ซึ่งดูคล้ายกับแก่นของการออกแบบโปรเจกต์นี้ เลยสงสัยว่าได้รับอิทธิพลมาจากตรงนั้นหรือเปล่า ลิงก์ทอล์ก
ตกใจที่ OS นี้มีเว็บเบราว์เซอร์ของตัวเองฝังมาให้ด้วย ซอร์สเว็บเบราว์เซอร์ ในวิดีโอเดโมก็เห็นว่ามันเรนเดอร์ Hacker News ได้
น่าทึ่งมาก และก็อดสงสัยไม่ได้ว่าโครงสร้างแบบนี้จะเป็นอนาคตของ OS หรือไม่ ตัว readme เองก็น่าสนใจมาก อยากรู้ว่าทำไมถึงเลือก wasmi แทน wasmtime ผมเองก็อยากลองใช้ OS นี้บน VM และอยากพอร์ต GUI library ของตัวเองไปลง Munal ด้วย
ตั้งแต่ยุค Xerox PARC ก็มีความพยายาม “ทำให้ userspace เป็น bytecode” เกิดขึ้นซ้ำ ๆ มาโดยตลอด และกรณีที่ประสบความสำเร็จจริงในตลาดก็คงมีแค่ IBM i, ChromeOS และ Android เท่านั้น ถึงอย่างนั้นโปรเจกต์นี้ก็เจ๋ง และหวังว่าจะไปได้ดี
การออกแบบ client OS เองก็น่าทึ่งมาก และโครงสร้างแบบนี้ก็ดูมีประโยชน์ใช้สอยบนฝั่งเซิร์ฟเวอร์ได้ทันทีด้วย ถ้าทำเคอร์เนลให้เล็กมากและเหลือแอปที่ทำงานอยู่เพียงตัวเดียว ก็น่าจะลดขอบเขตความปลอดภัยที่ไม่จำเป็นลงได้ เช่น key/value store ก็ดูเหมาะกับโครงสร้างแบบนี้มาก สิ่งที่ผมสงสัยคือด้วยโมเดล IO แบบนี้ ประสิทธิภาพเครือข่ายจะออกมาดีหรือไม่ และเวลาโฮสต์ WASM จะมีเทคนิคพิเศษอะไรที่ช่วยลดการคัดลอกหน่วยความจำที่ไม่จำเป็นได้บ้างหรือเปล่า