- เฟิร์มแวร์สวิตช์เครือข่ายของ Oxide เปิดไม่ติดหลังการทดสอบเปลี่ยนแปลง ลำดับการจ่ายไฟ และสาเหตุมาจากบั๊กที่การตรวจสอบ การยืมหน่วยความจำของ IPC ในเคอร์เนล Hubris ชนกับวิธีจัดวางหน่วยความจำแบบใหม่
- Hubris เป็นระบบปฏิบัติการฝังตัวที่แยก task ด้วย MPU และเมื่อมีการยืมหน่วยความจำให้ task อื่นผ่าน IPC เคอร์เนลจะตรวจสอบว่าหน่วยความจำนั้นอยู่ในขอบเขตที่เข้าถึงได้จริงหรือไม่
- ฟีเจอร์ task packing ที่เพิ่งนำมาใช้ช่วยกู้ RAM คืนได้ 30% ในบางอิมเมจเฟิร์มแวร์ แต่การตรวจสอบแบบเดิมล้มเหลวเพราะสมมติว่าหน่วยความจำที่ให้ยืมต้องอยู่ใน MPU region เดียว
- task
sequencer ตายด้วย synthetic memory fault ระหว่างพยายามยืมหน่วยความจำที่มีแอดเดรส 0x801bffd ให้กับไดรเวอร์ I2C และใน humility tasks มีสถานะ mem fault... in syscall พร้อมการรีสตาร์ต 115 ครั้ง
- การแก้ไขคือเปลี่ยน อัลกอริทึมการตรวจสอบ ให้ยอมรับการยืมที่คร่อมหลาย MPU region ที่ติดกันได้ และใช้เวลาราว 3 ชั่วโมงตั้งแต่พบปัญหาจนแก้บั๊กในเคอร์เนลเสร็จ
สวิตช์เครือข่ายที่เปิดไม่ติด
- Arjen Roodselaar แห่ง Oxide กำลังทดสอบการเปลี่ยนแปลง ลำดับการจ่ายไฟ และการตั้งค่านาฬิกาในเฟิร์มแวร์สวิตช์เครือข่าย ก่อนจะพบว่าหลังการเปลี่ยนแปลงที่ดูเล็กน้อย สวิตช์กลับเปิดไม่ติด
- บางส่วนของเฟิร์มแวร์ยังตอบสนองต่อคำสั่งได้ แต่ส่วนสำคัญที่รับผิดชอบ power sequencer ดูเหมือนหยุดทำงาน
- ข้อผิดพลาดในลำดับการจ่ายไฟอาจทำให้ฮาร์ดแวร์เสียหายจริงได้ จึงต้องตรวจสอบก่อนว่าสวิตช์พังไปแล้วหรือแค่ไม่ตอบสนอง
Hubris และหน่วยความจำที่มีจำกัด
- Hubris เป็นระบบปฏิบัติการสำหรับ ระบบฝังตัวระดับลึก เช่น internal controller ของคีย์บอร์ด และถูกสร้างขึ้นเพื่อจัดการงานที่จำเป็นต่อการเริ่มต้นโปรเซสเซอร์ขนาดใหญ่ใน Oxide Rack
- เฟิร์มแวร์ที่ใช้ Hubris ประกอบด้วย task หลายตัวซึ่งเป็นโปรแกรมที่คอมไพล์แยกกัน
- แต่ละ task มีโค้ดมาตรฐานไลบรารีและส่วนที่จำเป็นของตัวเอง
- task ถูกแยกออกจากกันด้วยฮาร์ดแวร์ MPU เพื่อไม่ให้ทำให้กันเองล่มหรือทำหน่วยความจำเสียหาย
- บน ARM Cortex-M ตระกูล ARMv7-M ที่ใช้เป็นหลัก พื้นที่หน่วยความจำที่ป้องกันได้ต้องมีขนาดเป็น กำลังของ 2 และต้องจัดแนวตามขนาดนั้น
- ตัวอย่างเช่น หากพื้นที่ 1024 ไบต์ต้องการเพิ่มอีก 1 ไบต์ ก็จะไม่กลายเป็น 1025 ไบต์ แต่ต้องขยายเป็น 2048 ไบต์
task packing สร้างขอบเขตใหม่
- Hubris รุ่นแรกใช้วิธีง่าย ๆ คือให้ task ใช้หนึ่ง region สำหรับ RAM และอีกหนึ่ง region สำหรับ flash แต่ทำให้เกิดช่องว่างที่ใช้งานไม่ได้ระหว่าง task และสิ้นเปลืองหน่วยความจำ
- Matt Keeter ปรับปรุงระบบ build ให้สามารถจัดวาง task โดยผสมหลาย region แบบ power-of-two เข้าด้วยกันเมื่อเป็นไปได้
- ฮาร์ดแวร์อนุญาตได้สูงสุด 8 region ต่อ task
- ในบางอิมเมจเฟิร์มแวร์สามารถกู้ RAM คืนได้ 30%
- อุปกรณ์ที่เล็กที่สุดซึ่งเดิมตึงมือจนต้อง optimize ทุกครั้ง เริ่มมีพื้นที่เผื่อใช้งาน
- การเปลี่ยนแปลงนี้ทำให้เกิด ขอบเขต MPU region ที่คาดเดาได้ยากตรงกลางระหว่าง flash และ RAM ของ task
เบาะแสที่ humility tasks ทิ้งไว้
- Arjen ใช้ Humility ซึ่งเป็นดีบักเกอร์ของ Hubris ตรวจสอบสวิตช์ที่ล้มเหลว และพบว่า service processor ที่รับผิดชอบ power sequencing ยังมีชีวิตและทำงานอยู่ จึงดูไม่น่าใช่ปัญหาฮาร์ดแวร์
- ในผลลัพธ์ของ
humility tasks task sequencer แสดงสถานะดังนี้
mem fault (precise: 0x801bffd) in syscall (was: wait: reply from i2c_driver/gen0)
- task เดียวกันนี้ถูก รีสตาร์ต 115 ครั้ง และใน Hubris การรีสตาร์ต task มักแทบจะหมายถึงการตอบสนองต่อการ crash
- สตริงสถานะนี้มีความหมายดังนี้
mem fault: ละเมิดกฎการจัดการหน่วยความจำ
precise: 0x801bffd: ระบุแอดเดรสที่มีปัญหาได้อย่างชัดเจน
in syscall: task ไม่ได้กำลังรันโค้ดปกติ แต่กำลังอยู่ใน system call
was: wait: reply from i2c_driver/gen0: กำลังรอคำตอบจากข้อความที่ส่งไปยังไดรเวอร์ I2C
gen0 หมายความว่า i2c_driver ยังไม่เคย crash เลย ขณะที่ sequencer อยู่ที่ generation 115
Hubris IPC และการยืมหน่วยความจำ
- task ใน Hubris สื่อสารกันผ่านข้อความ IPC ซึ่งทำงานคล้ายการเรียกฟังก์ชัน
- task ที่ส่งข้อความจะหยุดรอ
- task ที่รับข้อความจะได้สิทธิ์ควบคุม CPU
- เมื่อผลลัพธ์กลับมา task ที่ส่งจึงจะถูกปลุกอีกครั้ง
- IPC ถูกออกแบบให้เข้ากับ ownership model ของ Rust ได้ดี โดย task สามารถยืมบางส่วนของหน่วยความจำตัวเองให้ task อื่นพร้อมกับข้อความ IPC ได้
- task ที่โต้ตอบกับอุปกรณ์ I2C จะยืมช่วงหน่วยความจำของตัวเองให้ไดรเวอร์ I2C bus และไดรเวอร์จะอ่านหรือเขียนช่วงนั้นโดยตรง
- ช่วยลดความจำเป็นที่ bus driver ต้องมี buffer pool แยก
- ลดจำนวนครั้งของการคัดลอกข้อมูล
- หากทำผิดอาจกลายเป็นช่องโหว่ด้านความปลอดภัยได้ ดังนั้นเคอร์เนล Hubris จึงห้าม task ยืมหน่วยความจำที่ตัวเองไม่ได้เป็นเจ้าของจริงหรือเข้าถึงไม่ได้
- server จะได้รับรหัสข้อผิดพลาด
- client จะได้รับ fault และถูกยุติเสมอ
- สิ่งนี้ถูกมองเป็น access violation ที่บ่งชี้ถึงบั๊ก ความเสียหาย หรือความเป็นไปได้ของการโจมตี
synthetic fault และสาเหตุที่แท้จริง
- Hubris แยก fault ออกเป็น real fault และ synthetic fault
- real fault คือการละเมิดกฎของฮาร์ดแวร์ เช่น dereference null pointer หรือเขียนลงใน code region
- synthetic fault คือการละเมิดกฎซอฟต์แวร์ที่ Hubris เพิ่มเข้ามา เช่น IPC หรือการยืมหน่วยความจำ
- fault ของ
sequencer เป็น synthetic fault ที่เกิดระหว่างการยืมหน่วยความจำให้ไดรเวอร์ I2C ผ่าน IPC
- แอดเดรส
0x801bffd ที่เป็นปัญหาเป็นแอดเดรส flash ที่ถูกต้อง แต่เพราะมันอยู่ต่ำกว่าขอบเขตกำลังของ 2 อยู่ 3 ไบต์ จึงดูมีแพตเทิร์นแปลกตา
- ผลลัพธ์จาก
humility mem แสดงให้เห็นว่า task sequencer มี flash สอง region ที่ชนติดกันพอดีที่ 0x801c000
LOW HIGH SIZE ATTR ID TASK
0x08018000 - 0x0801bfff 16kiB r-x--- 17 sequencer
0x0801c000 - 0x0801dfff 8kiB r-x--- 17 sequencer
- แม้ทั้งสอง region จะเป็นของ task เดียวกันและในการรันโปรแกรมปกติฮาร์ดแวร์ MPU ก็อนุญาตให้เข้าถึงได้ไม่มีปัญหา แต่การตรวจสอบการยืมหน่วยความจำใน IPC ของเคอร์เนลกลับตั้งอยู่บนสมมติฐานอีกแบบหนึ่ง
จุดที่การทำให้ง่ายในอดีตกลายเป็นบั๊ก
- การตรวจสอบแบบเดิมของเคอร์เนลเพียงเช็กว่า memory slice ที่จะให้ยืมนั้นอยู่ครบถ้วนภายใน region เดียว ของ task หรือไม่
self.region_table().iter().any(|region| {
region.covers(slice)
&& region.attributes.contains(desired)
&& !region.attributes.intersects(forbidden)
})
- โค้ดนี้สอดคล้องกับสมมติฐานในการออกแบบตอนนั้น คือ task หนึ่งมี RAM region เดียวและ flash region เดียว
- เมื่อมี task packing หน่วยความจำของ task เดียวกันจึงสามารถถูกแบ่งออกเป็นหลาย MPU region ที่ติดกันได้ และสมมติฐานเดิมก็ใช้ไม่ได้อีกต่อไป
- การเข้าถึงหน่วยความจำทั่วไปไม่โดนผลกระทบ เพราะฮาร์ดแวร์ MPU เป็นผู้ตรวจเองโดยตรง และปัญหาจะปรากฏเฉพาะตอนพยายาม ยืมหน่วยความจำนั้นผ่าน IPC เท่านั้น
ความขัดข้องที่เกิดจากสองฟีเจอร์ทำงานร่วมกัน
- task packing ทำงานแบบฉวยโอกาส
- มีข้อจำกัดสูงสุด 8 region ต่อ task
- task ไดรเวอร์ฮาร์ดแวร์ใช้บาง region ไปแล้วกับ memory-mapped register
- ระบบจะพยายามจัดวางแบบฉลาดขึ้นก็ต่อเมื่อยังมีช่อง region เหลือ
- ผลคือจุดแบ่ง region เกิดขึ้นในตำแหน่งที่ผู้เขียน task คาดเดาได้ยาก
- การเปลี่ยนขนาดเล็กน้อยของ task A อาจไปเปลี่ยนตำแหน่งขอบเขต MPU region ของ task B ที่ไม่เกี่ยวข้องกัน
- แค่เพิ่มโค้ดดีบักก็อาจทำให้การตัดสินใจเรื่อง layout และขอบเขต region เปลี่ยน จน crash หายไปได้
- Matt ปิด task packing ในระบบ build ทันทีเพื่อให้ Arjen สร้างอิมเมจเฟิร์มแวร์ที่ใช้งานได้ก่อน พร้อมกับเดินหน้าวิเคราะห์และแก้บั๊กในเคอร์เนลไปพร้อมกัน
วิธีแก้ในเคอร์เนล
- หัวใจของการแก้คือเปลี่ยน อัลกอริทึมตรวจสอบการเข้าถึงหน่วยความจำ ให้ยอมรับกรณีที่หน่วยความจำที่จะยืมคร่อมหลาย MPU region ที่ติดกันอย่างพอดี
- อัลกอริทึมใหม่ถูกออกแบบให้ไล่ดู region table เพียงครั้งเดียว
- Hubris พยายามหลีกเลี่ยงการเปิดเผยการดำเนินการที่มี time complexity ซึ่ง task สามารถควบคุมได้
- ประสิทธิภาพจึงต้องขึ้นกับ region table ขนาดคงที่ ไม่ใช่กับขนาดของหน่วยความจำที่ยืม
- region table มีขนาดคงที่ที่ 8 รายการ
- เพื่อให้ทำได้ ระบบ build จึงถูกเปลี่ยนให้จัดเรียง task region ตามลำดับแอดเดรสจากน้อยไปมาก
regions.sort_by_key(|i| region_table.get_index(*i).unwrap().1.base);
- คอมมิตแก้ไข ทำให้เคอร์เนลใช้คุณสมบัติการเรียงลำดับนี้เพื่อตรวจสอบการเข้าถึงได้ในต้นทุนที่ต่ำกว่า
- โค้ดที่ซับซ้อนขึ้นถูกแยกออกจากแกนหลักของเคอร์เนล Hubris ไปไว้ใน crate ที่พกพาได้มากกว่า และมีการเพิ่ม unit test สำหรับ corner case สำคัญ
- ด้วยโค้ดใหม่นี้จึงสามารถเปิด task packing ได้อีกครั้ง โดยไม่ทิ้ง crash ที่คาดเดายากไว้ให้ผู้พัฒนา task
ทำไมปัญหาจึงไม่ลุกลามหนัก
- เรื่องทั้งหมดเริ่มจากสวิตช์เครือข่ายเปิดไม่ติด และจบลงด้วยการแก้บั๊กในเคอร์เนลภายในเวลาประมาณ 3 ชั่วโมง
- ด้วย fault isolation ในเฟิร์มแวร์สวิตช์ที่ประกอบด้วย 23 task แบบแยกกัน
sequencer จึงเป็นเพียง task เดียวที่ตายซ้ำ ๆ ขณะที่องค์ประกอบอื่นจำนวนมากยังทำงานต่อได้
- ระบบอัปเดตเฟิร์มแวร์
- IP network stack สำหรับอินเทอร์เฟซการจัดการและควบคุม
- บริการเครือข่ายหลายตัว ตั้งแต่ implementation ของโปรโตคอล
echo ไปจนถึงอินเทอร์เฟซ control plane ของแร็ก
- I2C, SMBus, PMBus สำหรับตรวจสอบเซนเซอร์ พัดลม และสถานะระบบอื่น ๆ
- ไดรเวอร์ทรานซีฟเวอร์ QSFP 100G จำนวน 32 พอร์ตด้านหน้าเครื่อง
- Hubris IPC ถูกออกแบบบนสมมติฐานว่า task อื่นอาจล้มเหลวได้ และงานที่ระบุว่า idempotent สามารถ retry ซ้ำได้อย่างโปร่งใส
- บั๊กเดิมในการตรวจสอบการเข้าถึงหน่วยความจำเป็นการปฏิเสธการเข้าถึงของโปรแกรมที่ถูกต้อง ไม่ใช่การเปิดทางให้การเข้าถึงที่ผิดหรือมุ่งร้าย จึงไม่มีผลกระทบด้านความปลอดภัย
- ในช่วงที่
sequencer และไดรเวอร์ I2C กำลังจะแชร์หน่วยความจำกันนั้น sequencer ตายไปก่อน แต่ไดรเวอร์ I2C ยังทำงานต่อได้โดยไม่มีความเสี่ยงจากความเสียหาย
โครงสร้างพื้นฐานการดีบักและการทำงานของทีม
- Humility เป็นดีบักเกอร์ที่พัฒนาควบคู่กับเคอร์เนล Hubris และ Arjen สามารถระบุตำแหน่งโค้ดที่ crash ได้ถึงระดับเลขบรรทัดภายในไม่กี่นาที พร้อมแชร์ snapshot ที่เป็นอิสระของ service processor ได้
- Hubris จะบันทึก core dump แบบบีบอัดของ task ที่ crash ลงใน RAM และสามารถดึงกลับมาทางเครือข่ายได้
- จึงได้ crash dump แม้ไม่มี persistent storage ที่เขียนได้
- ฟีเจอร์ crash dump ไม่ได้อยู่ในเคอร์เนล แต่เป็น task แยกต่างหาก
- โปรเซสเซอร์เหล่านี้ไม่ได้จัดการข้อมูลเวิร์กโหลดของลูกค้า แต่รับผิดชอบเฉพาะทราฟฟิกสำหรับการจัดการระบบ และรายงานการ crash ก็ไม่ได้อัปโหลดอัตโนมัติ
- ส่วนที่ไม่ขึ้นกับสถาปัตยกรรมของเคอร์เนล Hubris มีขนาดโค้ด 1,789 บรรทัด และคอมเมนต์ 1,192 บรรทัด ส่วนการรองรับ ARMv6-M, ARMv7-M และ ARMv8-M เพิ่มอีก 1,075 บรรทัดของโค้ดและคอมเมนต์ 534 บรรทัด
- แนวคิดของเคอร์เนลและ IPC ใน Hubris ค่อนข้างเรียบง่าย ดังนั้นเมื่อ fault ชี้ไปที่ IPC จึงมีจุดที่ต้องตรวจสอบไม่มากนัก
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
Hubris ดีจริง ๆ ผมลองอ่านโค้ดเคอร์เนลประมาณ 30 นาที มันห่างไกลจากโค้ด C ที่เคยเห็นซึ่งเต็มไปด้วยมาโคร
ifdefชอบตั้งชื่อตัวแปรสองตัวอักษร และขาดคอมเมนต์มาก ๆ แต่เขียนได้ชัดเจนและดีมากเหมาะเป็นของอ่านก่อนนอนด้วย แนะนำให้ลองไล่ดูสักรอบ: https://github.com/oxidecomputer/hubris/blob/b44e677fb39cde8...
พื้นที่ดิสก์ สำหรับซอร์สโค้ดไม่ใช่ปัญหาใหญ่มาตั้งแต่ 40 ปีก่อนแล้ว แต่ก็ยังตระหนี่กับชื่อตัวแปรกันอยู่
เพราะ AI เรียนรู้รสนิยมและนิสัยของโค้ดเดอร์คนนั้นได้อย่างแม่นยำ
เป็นบทความที่ดี แต่ตำแหน่งคอมเมนต์ด้านล่างน่าเสียดาย
คอมเมนต์เหนือ
regions.sort_by_key(|i| region_table.get_index(*i).unwrap().1.base);ที่ว่า “ต้องจัดเรียงตามที่อยู่จากน้อยไปมาก และเคอร์เนลใช้คุณสมบัตินี้เพื่อตรวจสอบการเข้าถึงได้ถูกลง” นั้นไม่ค่อยใช่รายละเอียดของฟังก์ชันนี้เท่าไร แต่เป็น invariant ของฟิลด์ ที่ผู้เขียนทุกคนต้องรักษา และผู้อ่านทุกฝั่งสามารถนำไปใช้ได้ดังนั้นดูเหมาะกว่าที่จะใส่ไว้ในสตริงเอกสารของ
TaskDesc::regions: https://github.com/oxidecomputer/hubris/commit/b44e677fb39cd...วิธีที่ดีที่สุดน่าจะเป็นการสร้าง เมธอด constructor ให้
TaskDescเพื่อจัดเรียง region และบังคับใช้ invariant นั้น เห็นได้ว่าโค้ดเริ่มซับซ้อนขึ้นเรื่อย ๆ ตอนนี้จึงน่าจะคุ้มที่จะใช้เวลาสักหน่อยห่อความซับซ้อนไว้ในเมธอดเป็นหนึ่งใน ประกาศรับสมัครงาน ที่ดีที่สุดเท่าที่เคยเห็นมา ชอบโฟลว์ที่ค่อย ๆ เปลี่ยนไปคุยเรื่องวัฒนธรรมอย่างเป็นธรรมชาติ แล้วปิดท้ายด้วย “ว่าแต่เรากำลังรับคนอยู่นะ”
เป็นบทวิเคราะห์หลังเหตุการณ์ที่ยอดเยี่ยมจริง ๆ และแม้ผมจะเป็นนักพัฒนาระดับแอปพลิเคชันก็ยังตามทัน พอดีตอนนี้กำลังอ่าน Rust in Action อยู่ เลยยิ่งพร้อมกับเนื้อหาแบบนี้มากขึ้น
การได้เห็นคนที่ใส่คอมเมนต์ในโค้ดเยอะ ๆ ก็เป็นเรื่องน่ายินดีเสมอ literate programming ใช้ได้ผลจริง
ดูเหมือนภาคก่อนหน้าจะดูได้ที่นี่
ส่วนที่ว่า “การผสานรวมของทีมอย่างแน่นแฟ้นและไม่เป็นลำดับชั้น” สะดุดตา แม้จะไม่ใช่ฟีเจอร์ของ Hubris โดยตรง แต่คำอธิบายที่ว่าแยก Hubris ออกจากทีมที่สร้างมันได้ยาก และทีมวิศวกรรมของ Oxide แทบไม่มีไซโลภายในนั้นน่าประทับใจ
อยากฟังเพิ่มเติมว่าทำไมถึงสร้างวัฒนธรรมที่ส่งเสริม ความเปิดกว้าง ความใฝ่รู้ และการสื่อสาร พร้อมกับกดพฤติกรรมเชิงป้องกันตัว การสร้างจักรวรรดิ และการกั้นประตู และนำไปใช้จริงอย่างไรบ้าง นอกจากนี้ยังสงสัยว่าการบ่มเพาะวัฒนธรรมแบบนี้ในองค์กรมีข้อเสียหรือไม่
บางที่ก็เลือกใช้ระบบลำดับชั้นที่เข้มงวดกว่า และผังองค์กรอาจต้องกำหนดเชิงกลยุทธ์ จึงยังไม่ค่อยเข้าใจ trade-off นัก
ถ้าโครงสร้างนั้นไม่ถูกระบุไว้อย่างชัดเจน มันก็จะเปิดเผยน้อยกว่า ไม่ได้ถูกเลือกอย่างตั้งใจ และโดยเฉพาะสำหรับคนที่ไม่ถนัดปฏิสัมพันธ์ทางสังคม ก็จะยิ่งเข้าใจได้ยากขึ้น ด้วยลักษณะที่เหมือนเงานี้ มันจึงอาจปล่อยให้เกิดพฤติกรรมที่เป็นปัญหามากขึ้น และต่อให้ไม่ได้แย่มาก ก็ทำให้การประสานงานยากขึ้นมาก
เคยเจอเรื่องแบบนี้ในหลายบริษัท บริษัทที่ปรึกษาขนาดใหญ่แห่งหนึ่งมีโครงสร้างอำนาจทางการอยู่ก็จริง แต่ในทางปฏิบัติไม่ค่อยยึดตามนั้น และวิธีเข้าไปอยู่ในโปรเจกต์ก็ใกล้เคียงกับการสนิทกับคนฝ่ายขายหรือฝ่ายบริหารมากกว่าผ่านช่องทางทางการ ถ้าสร้างเครือข่ายทางสังคมที่จำเป็นได้ดีก็ดีไป แต่ถ้าไม่ได้ มันก็ทำงานได้ไม่ดี
ตัวอย่างคล้ายกันคือ “The Tyranny of Structurelessness” ซึ่งเป็นปาฐกถาของนักสตรีนิยมที่เห็นสิ่งเดียวกันเกิดขึ้นในองค์กรที่มองลำดับชั้นว่าเป็นปิตาธิปไตยและปฏิเสธมัน และก็มีการถกเถียงคล้ายกันใน Valve ที่โครงสร้างภายในไม่ชัดเจน โปรเจกต์โอเพนซอร์สก็เจอปัญหาเดียวกันได้ และผมมองว่าความขัดแย้งบางส่วนในฝั่ง Rust ก็เกิดจากปัญหาลักษณะคล้ายกัน
แต่โครงสร้างอำนาจที่ชัดเจนไม่จำเป็นต้องเป็นลำดับชั้นเสมอไป องค์กรธุรกิจแบบดั้งเดิมเป็นแบบลำดับชั้น แต่โครงสร้างของ Oxide อาจชัดเจนและไม่เป็นลำดับชั้นได้ วิธีแบบนี้มักทำงานได้ดีกว่าเมื่อขนาดเล็ก และบริษัทที่ปรึกษาที่กล่าวถึงก่อนหน้านี้เป็นตัวอย่างที่ใหญ่ที่สุดเท่าที่ผมรู้จักของบริษัทที่ดำเนินงานใกล้เคียงกับรูปแบบอิสระ แต่ก็ยังมีฐานรองรับอยู่บ้าง
เรื่องนี้ไม่ใช่ทวิภาค แต่เป็นสเปกตรัม ต่อให้โครงสร้างอำนาจบนกระดาษแข็งตัวที่สุด ข้างใต้ก็ยังมีโครงสร้างโดยนัยที่ซับซ้อนกว่า และนั่นคือธรรมชาติของกลุ่มมนุษย์
ผมไม่ได้เชื่อว่าโครงสร้างที่ชัดเจนดีกว่าโครงสร้างโดยนัยเสมอไป แค่พูดถึงข้อเสียที่สังเกตได้ในองค์กรที่ระบุโครงสร้างน้อยกว่าเท่านั้น และโครงสร้างอำนาจที่ชัดเจนกว่าก็มีปัญหาของตัวเองเช่นกัน เรื่องนี้ยังเกี่ยวข้องกับ “seeing like a state” หรือปัญหาเรื่อง legibility ด้วย
เป็นบทความที่ยอดเยี่ยมซึ่งแสดงให้เห็นกระบวนการดีบักปัญหาซับซ้อนอย่างลึกซึ้ง ข้อเท็จจริงที่ว่าระบบส่วนที่เหลือยังคงเสถียรได้ดี แสดงถึง คุณภาพทางวิศวกรรม ของทีม Oxide อย่างชัดเจน
โดยส่วนตัวแล้วก็ได้แรงบันดาลใจมาก และตั้งใจจะลองนำเทคนิคคล้าย ๆ กันไปใช้ในงานประจำวัน
ถ้าปฏิบัติกับฮาร์ดแวร์นั้นเหมือน TLB ที่เติมด้วยซอฟต์แวร์ ก็จะรองรับ region ได้มากกว่า 8 รายการ
คงไม่ทำเด็ดขาดเว้นแต่จะเป็นทางเลือกสุดท้าย virtual paging นั้นยุ่งเหยิง และไม่อยากให้เหลือข้อสงสัย
สิ่งที่ Oxide ทำอยู่นั้นน่าทึ่งจริง ๆ
ไม่ว่าเหล่าคนของ Oxide จะทำอะไร ผมก็ชอบทั้งนั้น และนี่ก็เป็นหนึ่งในนั้น
ตั้งชื่อระบบปฏิบัติการว่า Hubris เหรอ? อา นั่นมัน… พูดไม่ออกเลย
ใครที่สติยังดีอยู่จะเขียนระบบปฏิบัติการใหม่ในยุคนี้กัน? คำตอบคือคนที่พยายามแก้ปัญหาที่ระบบปฏิบัติการทุกตัวเมิน นั่นคือปัญหาคอนโทรลเลอร์บนเมนบอร์ดและการ์ดขยาย ซึ่งระบบปฏิบัติการไม่ได้ควบคุมและไม่สามารถควบคุมได้