ซับซิสเต็ม Windows 9x สำหรับ Linux
(social.hails.org)- โปรเจ็กต์เชิงทดลองที่ทำให้สามารถรัน เคอร์เนล Linux รุ่นใหม่ล่าสุด (6.19) แบบร่วมมือกันภายในเคอร์เนล Windows 9x เพื่อใช้ความสามารถทั้งหมดของทั้งสองระบบปฏิบัติการได้พร้อมกัน
- ต่างจาก WSL ตรงที่ไม่ใช้ฮาร์ดแวร์เวอร์ชวลไลเซชัน จึงสามารถรันได้แม้บน 486
- สามารถใช้ความสามารถของระบบปฏิบัติการสมัยใหม่ เช่น paging, memory protection, preemptive scheduling ในสภาพแวดล้อม Windows 9x และรองรับการรันแอปเคียงข้างกันโดยไม่ต้องรีบูต
- ประกอบด้วย 3 ส่วนคือ เคอร์เนล Linux ที่แพตช์แล้ว, ไดรเวอร์ VxD, ไคลเอนต์
wsl.comโดยดัดแปลง User-Mode Linux ให้เรียก Win9x kernel API - system call ถูก dispatch ผ่าน ตัวจัดการ General Protection Fault (GPF) แทน
int 0x80เนื่องจากข้อจำกัดของ interrupt descriptor table แบบสั้นของ Win9x - "เขียนอย่างภาคภูมิใจโดยไม่ใช้ AI (Proudly written without AI)", ไลเซนส์ GPL-3
WSL9x - codeberg.org/hails/wsl9x
ภาพรวม
- WSL9x คือ ซับซิสเต็ม Linux สำหรับ Windows 9x ที่ทำให้เคอร์เนล Linux รุ่นใหม่ล่าสุด (ณ เวลาที่เขียนคือ 6.19) ทำงานแบบร่วมมือกันอยู่ภายในเคอร์เนล Windows 9x
- สามารถใช้ความสามารถทั้งหมดของทั้งสองระบบปฏิบัติการพร้อมกัน เช่น paging, memory protection, preemptive scheduling
- สามารถรันแอปของทั้งสองระบบปฏิบัติการเคียงข้างกันได้ โดยไม่ต้องรีบูต
- เขียนขึ้นด้วยตัวเองโดยไม่ใช้ AI
โครงสร้างทางเทคนิค
- WSL9x ประกอบด้วย 3 องค์ประกอบ
- เคอร์เนล Linux ที่แพตช์แล้ว (
win9x-um-6.19branch) - ไดรเวอร์ VxD
- โปรแกรมไคลเอนต์
wsl.com
- เคอร์เนล Linux ที่แพตช์แล้ว (
ไดรเวอร์ VxD
- รับผิดชอบการเริ่มต้นระบบของ WSL9x โดยมีจุดเข้าใช้งานอยู่ที่
vxd/wsl9x.asm - ตั้งค่า initial mapping ของโค้ดเคอร์เนล และโหลด
vmlinux.elfจากดิสก์ผ่าน DOS interrupt (vxd/loader.c,vxd/fs.asm) - เคอร์เนลถูกคอมไพล์ด้วย base address คงที่ที่
0xd0000000 - สร้างเธรดใหม่ภายใน System VM และจัดสรร สแตก 16 KiB เพื่อใช้สำหรับการเข้า Linux
- จากนั้นเข้าสู่ event loop ที่จัดการการเข้าเคอร์เนล, การ dispatch IRQ, การกลับสู่ userspace และสถานะ idle (
vxd/entry.c)
การจัดการ system call และ page fault
- ไดรเวอร์จัดการ page fault และ system call ซึ่งเป็นเหตุการณ์จาก userspace ที่ต้อง dispatch ไปยังเคอร์เนล
- system call ถูกจัดการผ่าน ตัวจัดการ General Protection Fault (GPF)
- Win9x มี interrupt descriptor table ที่ยาวไม่พอ สำหรับติดตั้งตัวจัดการที่เหมาะสมให้กับ
int 0x80ซึ่งเป็น Linux i386 system call interrupt - ตัวจัดการ GPF จะตรวจสอบคำสั่งที่ทำให้เกิด fault และถ้าเป็น
int 0x80ก็จะขยับ instruction pointer ราวกับว่า interrupt สำเร็จ แล้ว dispatch ไปยัง Linux system call (vxd/fault.c)
- Win9x มี interrupt descriptor table ที่ยาวไม่พอ สำหรับติดตั้งตัวจัดการที่เหมาะสมให้กับ
การดัดแปลงเคอร์เนล Linux
- มีพื้นฐานมาจาก User-mode Linux แต่ถูกแก้ให้เรียก Windows 9x kernel API แทน POSIX API
- รันใน ring 0 (supervisor/kernel mode) ไม่ใช่ user mode (ring 3)
- การผสานรวมกับเคอร์เนล Win9x ส่วนใหญ่ รวมถึง context switching อยู่ฝั่งเคอร์เนล Linux
- ตำแหน่งโค้ดหลัก:
linux/arch/um/os-Win95 - จุดเข้า:
_startในmain.c, และไฟล์สำคัญคือprocess.c,mmu.c
- ตำแหน่งโค้ดหลัก:
ไคลเอนต์ wsl.com
- เป็น โปรแกรม DOS 16 บิต ที่พัฒนาอยู่ใน
wsl/wsl.asm - ทำให้สามารถใช้ MS-DOS prompt เป็นหน้าต่าง TTY ได้โดยไม่ต้องมีการทำ TTY แยกต่างหาก
- เมื่อรันจะเรียก WSL9x V86 API (
vxd/v86_api.asm) เพื่อขอคอนโซลที่ไม่ได้ใช้งาน และแจ้งให้ output ของคอนโซลนั้นถูก dispatch มาที่ตัวเอง - หลังจากนั้นจะเข้าสู่ event loop ที่รอ IRQ และพยายามอ่านคีย์บอร์ดเมื่อเกิด interrupt
- ยังทำหน้าที่เป็น จุดซิงโครไนซ์ ของไดรเวอร์คอนโซล (
vxd/console.c)- เมื่อ Linux พร้อมส่ง output จะมีการ schedule event และรัน
int 0x29ในคอนเท็กซ์ของ MS-DOS VM เพื่อพิมพ์อักขระไปยังหน้าต่าง DOS - interrupt นี้ยังเป็นจุดที่ไดรเวอร์ ANSI สำหรับ DOS อย่าง NNANSI ใช้ดักจับ terminal output เพื่อรองรับ ANSI escape code
- เมื่อ Linux พร้อมส่ง output จะมีการ schedule event และรัน
ข้อกำหนดสำหรับการบิลด์และรัน
- ต้องมี cross toolchain สำหรับเป้าหมาย
i386-linux-musl(แนะนำให้ใช้ musl-cross-make) - ต้องมี Open Watcom v2 toolchain สำหรับบิลด์ส่วนประกอบฝั่ง Windows
- ต้องบิลด์ เคอร์เนล Linux ที่แพตช์แล้ว จาก branch
win9x-um-6.19 - ต้องตั้งค่า environment variable
WATCOMและLINUXให้เหมาะสม (ดูตัวอย่างใน.envrc.example) - ต้องมีอิมเมจฮาร์ดดิสก์
hdd.base.imgที่ ติดตั้ง Windows 9x ไว้ล่วงหน้า - เมื่อรัน
makeจะสร้างhdd.imgที่เตรียม WSL9x ไว้พร้อมใช้งาน - ให้รัน
wslจาก MS-DOS prompt เพื่อเปิด pty และหากต้องการใช้ ANSI color แนะนำให้โหลดไดรเวอร์อย่างnnansi.comไว้ล่วงหน้า
ไลเซนส์
- GPL-3
2 ความคิดเห็น
ความคิดเห็นใน Hacker News
http://www.colinux.org/
https://github.com/wishstudio/flinux
ที่จริง flinux มีโครงสร้างใกล้กับ WSL1 มาก ส่วน CoLinux ก็ให้อารมณ์ไปทาง WSL2 เพราะยกเคอร์เนล Linux ขึ้นมารันข้าง ๆ
ในเชิงเทคนิค รู้สึกว่า Cygwin เป็นแนวทางที่ตรงตามหลักมากกว่า เพราะเป็นการรันไบนารี POSIX แบบเนทีฟบน Windows แทนที่จะฝืนยัด plumbing ของ Linux จากภายนอกเข้ามา และจบได้ด้วยการลิงก์ DLL เบา ๆ โดยไม่ต้องไปแตะ ring 0 ซึ่งเป็นจุดที่ชอบ
แต่ตอนนั้นความสะดวกของ CLI package manager ยังไม่ดีพอ และเวลาทำงานบน Windows จริง ๆ ก็หมกมุ่นกับ CoLinux อยู่พอสมควร
ปัญหาหลักที่จำได้คือ DLL hell เช่น ถ้า OpenSSH ที่พอร์ตมาสำหรับ Windows ขน cygwin1.dll ของตัวเองมาด้วย ก็มักจะชนกันเรื่องเวอร์ชันบ่อย ๆ
ถึงอย่างนั้น ในยุคที่ RAM น้อยและการสว็อปหนักมาก ข้อดีเรื่องโอเวอร์เฮดต่ำก็ยังมีความหมาย
ยุคนั้นยังเป็นโลกที่แอปเนทีฟมาก่อน Web 2.0 หรือ NodeJS และ Java ก็ชื่อเสียงไม่ค่อยดี
สุดท้ายมันก็ให้ความรู้สึกเหมือนเดินหน้าสองก้าวถอยหลังหนึ่งก้าวตามปกติ
แม้จะพูดกันเหมือนไม่ช้า แต่ของจริงมันช้า ทั้งยังเข้ากันได้น้อยกว่าวิธีอื่น ต้องคอมไพล์ใหม่ และตลอดช่วงชีวิตส่วนใหญ่ก็ไม่ใช่เครื่องมือที่คนรักกันแพร่หลาย
ข้างใน cygwin1.dll มี เวทมนตร์ด้านความเข้ากันได้ มหาศาลเกิดขึ้น และสุดท้ายก็เหมือนลาก plumbing ของ Linux จากภายนอกเข้ามาไว้ในโปรเซสอยู่ดี โดยเฉพาะถ้านึกถึงวิธีที่มันทำ
fork()โดยไม่มีการสนับสนุนจากระบบCygwin ใช้งานใน Windows AppContainer isolation ไม่ได้เลย ส่วน MSYS2 ก็ยังใช้ฐานนี้อยู่จนถึงตอนนี้ ทำให้ไบนารีของ MSYS2 รันใน AppContainer ไม่ได้
เพราะงั้นตอนทำ sandboxing ให้ Claude Code จึงต้องใช้เส้นทางที่ต่างออกไปทั้งหมด เนื่องจาก Claude Code ต้องการ Git for Windows และ Git for Windows ก็แจก
bash.exeที่บิลด์ด้วย MSYS2 เป็นต้นตรงกันข้าม บิลด์ Windows แบบเนทีฟจริง ๆ ไม่มีการแฮ็กประหลาดแบบที่ cygwin1.dll ต้องการ ทำให้บิลด์ non-MSYS2 ที่ผมหาเจอรันใน AppContainer ได้ดี
ใช้ pacman ของ Arch Linux ได้ จึงทำให้การจัดการไบนารี POSIX แบบเนทีฟบน Windows โดยไม่ต้องมี Linux VM เป็นมิตรกว่ามาก
ถ้า C library ที่อยากใช้ไม่มี Cygwin เวอร์ชัน ที่บิลด์ไว้ล่วงหน้า ก็ต้องไล่รัน dependency tree ทั้งก้อนด้วย
configure,makeเองแถมถ้าจำไม่ผิด ก็มีประมาณสองในสามที่ต้องลงมือแก้อะไรเอง เพราะ POSIX ไม่ได้ตรงเป๊ะขนาดนั้น
แต่เพื่อให้ได้ semantics ที่ถูกต้อง ก็ต้องใช้ทางอ้อมและการแฮ็กสารพัด เช่น
forkไม่ใช่ copy-on-writeผมใช้ Cygwin มาตั้งแต่ราวปี 1999 จนถึง 2022 ลองใช้ WSL2 มาบ้าง และตอนนี้ก็ยังใช้มันบนโน้ตบุ๊ก
แต่เดสก์ท็อปย้ายไป Linux เต็มตัวตั้งแต่ปีที่แล้ว
เมื่อก่อนสมัยใช้ Windows ช่วง XP เคยรัน Colinux มันเป็นเครื่องมือที่น่าทึ่งจริง ๆ
การยก LAMP stack ไปไว้ฝั่ง Linux ง่ายกว่ามาก และยังใช้เอดิเตอร์บน Windows แก้ไฟล์ต่อได้ ทำให้จัด local development environment ได้ค่อนข้างดี
ยังลองต่อ X11 server บน Windows แล้วเปิดเดสก์ท็อป Linux ไว้ด้านบนได้ด้วย
พอมองตัวเองค่อย ๆ กองสภาพแวดล้อมแบบ Unix ลงบน Windows มากขึ้นเรื่อย ๆ สุดท้ายก็ย้ายไป macOS
นอกจากคุณค่าด้านการแฮ็กเพียว ๆ แล้ว ถ้านึกถึงการใช้งานจริง ก็รู้สึกว่าบนเครื่องระดับ 486 น่าจะชน ข้อจำกัดด้านหน่วยความจำ อย่างรวดเร็ว
http://colinux.org/
แค่มีคนที่มองเห็นสิ่งนั้นไม่มากนักเท่านั้นเอง
สำหรับผมมันแทบเป็นงานที่ดูเป็นไปไม่ได้
แต่ก็สงสัยว่าถ้าคนที่เข้าใจสถาปัตยกรรมมาดู จะมองมันอย่างไร
เลยนึกถึงมุกที่นักคณิตศาสตร์สองคนบอกว่าทฤษฎีบทหนึ่งเป็นเรื่องเล็กน้อย แล้วพออธิบายไปสองชั่วโมงถึงค่อยยอมรับว่ามันเล็กน้อยจริง
จากนั้นอาจารย์ก็บอกว่าใช่แล้ว แล้วข้ามไปข้อต่อไปเลย
สิ่งที่น่าทึ่งคือผู้เขียนค่อย ๆ ไขรายละเอียดจำนวนมากแบบ รายการรายละเอียดระดับคัมภีร์ ที่ทำให้มันเกิดขึ้นได้ทีละข้อ
เพราะงั้นแต่ละโปรแกรมจึงอ่านได้แค่บางส่วนของหน่วยความจำตัวเอง และ CPU ก็จะให้เวลาอย่างจำกัดก่อนส่งต่อให้โปรแกรมถัดไป
Windows ใช้ความสามารถเหล่านี้อย่างจริงจังตั้งแต่ Windows NT และ XP ก็อยู่ในสายเดียวกัน
แต่จนถึง Windows 98 โปรแกรมแทบจะทำอะไรก็ได้ และความสามารถป้องกันระดับฮาร์ดแวร์เหล่านั้นแทบไม่ได้ถูกใช้
Windows ยุคนั้นจึงให้ความรู้สึกว่าใกล้เคียงกับ ชุดไลบรารีฟังก์ชัน ที่คอยแสดง UI และคุยกับอุปกรณ์ต่อพ่วง มากกว่าจะเป็นระบบปฏิบัติการ
CPU มีฮาร์ดแวร์พิเศษที่จำกัดการเข้าถึงหน่วยความจำและเวลาประมวลผล แต่ Windows 9x ใช้มันไม่เต็มที่
เพราะอย่างนั้นจึงมีช่องให้ Linux subsystem บน Windows 9x แสร้งทำตัวเป็นระบบปฏิบัติการเอง แล้วหยิบฮาร์ดแวร์นั้นมาใช้เพื่อรันระบบปฏิบัติการสมัยใหม่ได้
สำหรับผม ส่วนที่ยากที่สุดของงานแบบนี้คือการทำความเข้าใจ Microsoft driver API
เอกสารยุค 9x ทั้งไม่ละเอียดพอ เข้าถึงก็ยาก และแม้ตอนนี้ก็ยังไม่ใช่พื้นที่ที่น่ารื่นรมย์นัก
เลยดูเหมือนว่าจะมีพื้นที่ให้ย้ายฟังก์ชันระดับล่างของ Linux บางส่วนเข้าไปได้พอสมควร
ด้านหนึ่งมีบทสนทนาเรื่อง Show HN เพิ่มขึ้นสามเท่าและแอปแนว vibe coding คล้าย ๆ กันเต็มไปหมด แต่อีกด้านหนึ่งมีคนหนึ่งใช้เวลา 6 ปี เจาะลึกเข้าไปใน Win9x เพื่อรันเคอร์เนล Linux สมัยใหม่อยู่ข้างใน
พอเทียบกับเธรดที่เต็มไปด้วยแอปที่ทำจากพรอมป์ต 20 นาที โพสต์แบบนี้ทำให้รู้สึกมีความสุขจริง ๆ
รู้สึกดีทีเดียวที่ได้เห็นข้อความแบบนี้
เดี๋ยวนี้แทนที่จะบอกว่า create me an owl app หลายคนจะขอให้ช่วยสร้าง พรอมป์ตแบบครบชุด สำหรับทำ owl app แล้วค่อยเอาไปแปะในเซสชัน AI ถัดไป
เพราะมีผลิตภัณฑ์ชื่อ Zero AI อยู่จริง เลยอาจตีความแบบนั้นได้
ถ้อยคำก็ชัดขึ้น และตัวโปรเจ็กต์เองก็น่าทึ่งจริง ๆ
https://codeberg.org/hails/wsl9x
Mastodon นี่ยังบังคับให้ รัน JavaScript แม้จะอ่านแค่โพสต์เดียว เลยปกติผมจะข้ามไปเลย
https://github.com/mastodon/mastodon/issues/23153
https://github.com/mastodon/mastodon/issues/19953
ผมรู้แค่ว่ามี VM Monitor กับข้อมูลกระจัดกระจายว่ามีการรองรับลักษณะนี้อยู่ แต่คำอธิบายละเอียด ๆ ดูจะกระจายอยู่ทั่ว
หลายคนสรุปง่าย ๆ ว่า Windows แค่รันอยู่บน DOS แต่ผมว่ามันไม่ถูกต้องนัก
แน่นอนว่ามันไม่ใช่ virtual machine ในความหมายแบบปัจจุบัน แต่ข้างในมีโครงสร้างทางเทคนิคที่น่าสนใจมาก และเอกสารส่วนใหญ่ก็แตะเรื่องนี้แค่ผิวเผิน
อีกอย่างก็สงสัยว่าโปรเจ็กต์นี้คล้ายกับ BSD on Windows มากแค่ไหน
และผมก็รู้จัก Architecture of Windows 9x อยู่แล้ว แต่สำหรับรสนิยมผมมัน ลึกไม่พอ
https://winworldpc.com/product/windows-sdk-ddk/windows-95-ddk
เอกสารละเอียดมากและมี sample code เยอะ เหมาะกับการขุดลึกเอง
เพราะ WSL หมายถึง Linux on Windows ดังนั้นอันนี้ก็น่าจะอ่านเป็น W9xSL ในความหมายว่า Linux บน Windows 9x
ตอนนี้ยกหลักฐานทันทีไม่ได้ แต่จำได้ว่าเคยอ่านว่ามันเกี่ยวกับ ปัญหาเครื่องหมายการค้า
เหมือนเดิมทีอยากเรียกว่า Linux Subsystem for Windows แต่ฝั่ง Linux foundation ไม่อนุญาตให้โปรเจ็กต์ที่ไม่ได้รับอนุญาตใช้ชื่อที่ขึ้นต้นด้วย Linux
ปรัชญาหลักคือมีหลาย personality แล้วแปล system call ของแต่ละสภาพแวดล้อมไปเป็นการเรียกของเคอร์เนล NT
เพราะงั้น WSL1 ในปี 2016 ก็เหมือนกับนำกลเม็ดเดิมกลับมาใช้ใหม่กับ Linux อีกครั้ง
ส่วน Windows 9x นั้นอยู่บนสาย DOS ดังนั้นถ้าจะรัน Linux ข้างในก็น่าจะต้องใช้การแฮ็กที่เลอะเทอะและต่างออกไปโดยพื้นฐานมาก
คาดว่านั่นก็น่าจะเป็นเหตุผลว่าทำไมสมัยนั้นไม่มีใครทำ
เพราะงั้นแค่ความจริงที่ว่ามันรันได้จริง ก็ทำให้รู้สึกว่านี่แสดงให้เห็นว่า NT architecture ล้ำยุคแค่ไหน
ถ้ามองการใช้งานจริง ก็นึกถึงสภาพแวดล้อมที่ยังผูกติดกับ Windows 98 เช่นซอฟต์แวร์เก่าด้านการแพทย์หรืออุตสาหกรรม
แต่ถ้าในปี 2026 ยังถือเครื่อง 486 อยู่ ผมว่าการรัน Linux แบบเนทีฟน่าจะมีประโยชน์กว่ามาก แทนที่จะยัด Linux เข้าไปในอนุพันธ์ของ DOS อายุ 30 ปี
แค่ที่ Windows 9x รัน DOS ได้ก็มี เวทมนตร์พอตัว อยู่แล้ว
ฝากบทความที่น่าอ่านไว้ด้วย
ฮ่า coLinux 555 -_- ชื่อนี้น่าคิดถึงจริงๆ 555 แต่ตอนนี้ถึงจะมี wsl ผมก็ยังไม่ใช้ ทว่า win95+linux นี่น่าสนใจแฮะ