เผยบน HN: Banan-OS ระบบปฏิบัติการคล้าย Unix ที่เขียนขึ้นใหม่ตั้งแต่ต้น
(github.com/Bananymous)- Banan-OS เป็น ระบบปฏิบัติการงานอดิเรก ที่เขียนด้วย C++ และปัจจุบันรองรับสถาปัตยกรรม x86_64 และ i686
- ขอบเขตฟีเจอร์ครอบคลุมถึง user space ระดับ Ring3, SMP, network stack, การโหลด ELF และ dynamic linking, หน่วยความจำแบบ copy-on-write และ สภาพแวดล้อมกราฟิก พื้นฐาน
- ไดรเวอร์และฟีเจอร์ระบบรองรับดิสก์ NVMe/ATA, NIC ตระกูล E1000/E1000E และ RTL, อินพุต PS2/USB, ระบบไฟล์ Ext2/FAT, GRUB และ BIOS bootloader ของตัวเอง
- TCP ถูกระบุว่าเป็น การใช้งานบางส่วนและมีบั๊ก ส่วน SSL, อุปกรณ์ virtio, USB controller บางตัว, ระบบไฟล์ Sys/9P และ UEFI bootloader ของตัวเองยังไม่ถูกนำไปใช้
- การ build เน้นใช้สคริปต์
./bosโดยหลังสร้าง toolchain แล้วสามารถรัน QEMU/Bochs, build kernel/image และเลือกตัวเลือกสถาปัตยกรรม/bootloader/UEFI/initrd ได้
ภาพรวม Banan-OS
- Banan-OS เป็น ระบบปฏิบัติการงานอดิเรก ที่เขียนด้วย C++
- สถาปัตยกรรมที่รองรับในปัจจุบันคือ x86_64 และ i686
- มี live demo ให้ใช้ที่ bananymous.com/banan-os
- หากต้องการรัน DOOM ต้องเข้า GUI environment ด้วยคำสั่ง
start-guiแล้วรันdoomใน GUI terminal
ฟีเจอร์หลักที่นำไปใช้แล้ว
- ฟีเจอร์ทั่วไป
-
Ring3 user space
- SMP หรือ multiprocessing
- linear framebuffer บน VESA และ GOP
- network stack
- การโหลดไฟล์ปฏิบัติการ ELF
- AML interpreter แบบบางส่วน
- สภาพแวดล้อมกราฟิกพื้นฐาน
- terminal emulator
- status bar
- program launcher
- “แอปที่ใช้ได้ดี” ยังไม่ถูกนำไปใช้
- ELF dynamic linking
- หน่วยความจำแบบ copy-on-write
- file mapping ถูกนำไปใช้แล้ว
- anonymous mapping ยังไม่ถูกนำไปใช้
-
การรองรับไดรเวอร์ เครือข่าย และระบบไฟล์
- ไดรเวอร์
- รองรับ ดิสก์ NVMe และดิสก์ ATA IDE/SATA
- รองรับ NIC E1000, E1000E, RTL8111/8168/8211/8411
- คีย์บอร์ด PS2 รองรับ scancode set ทั้งหมด และรองรับเมาส์ PS2 ด้วย
- USB รองรับ xHCI, คีย์บอร์ด, เมาส์, mass storage และ hub
- EHCI, OHCI, UHCI และอุปกรณ์เครือข่าย/สตอเรจ virtio ยังไม่ถูกนำไปใช้
- เครือข่าย
- รองรับ ARP, ICMP, IPv4, UDP
-
TCP เป็นการใช้งานบางส่วนและมีบั๊ก
- รองรับ Unix domain socket
- SSL ยังไม่ถูกนำไปใช้
- ระบบไฟล์
- รองรับ virtual file system, Ext2, FAT12/16/32, Dev, Ram, Proc
- Sys และ 9P ยังไม่ถูกนำไปใช้
- bootloader
- รองรับ GRUB และ BIOS bootloader ของตัวเอง
- UEFI bootloader ของตัวเองยังไม่ถูกนำไปใช้
โครงสร้างโค้ด
- คอมโพเนนต์หลักและไลบรารีแต่ละส่วนมี ไดเรกทอรีย่อยแยกต่างหาก เช่น
kernel,userspace,libc - ในแต่ละไดเรกทอรีมีไดเรกทอรี
includeที่เก็บไฟล์ header ทั้งหมดของคอมโพเนนต์นั้น - header ทั้งหมดถูก include ด้วย absolute path
การ build และการรัน
- สำหรับ Ubuntu 22.04 ต้องใช้แพ็กเกจ
aptได้แก่build-essential,git,ninja-build,texinfo,bison,flex,libgmp-dev,libmpfr-dev,libmpc-dev,parted,qemu-system-x86,cpu-checker - ในสภาพแวดล้อม
pacmanต้องใช้base-devel,git,wget,cmake,ninja,parted,qemu-system-x86 - build toolchain สำหรับระบบปฏิบัติการเพียงครั้งเดียวด้วย
./bos toolchain- เนื่องจากต้องคอมไพล์ binutils และ gcc จึงอาจใช้เวลานาน
- การ build และรัน OS เองทำด้วยคำสั่ง
./bos./bos qemu./bos qemu-nographic./bos qemu-debug./bos bochs
- สามารถ build เฉพาะ kernel หรือ disk image ได้เช่นกัน
./bos kernel./bos image
- การสร้างและแก้ไข disk image ต้องใช้ สิทธิ์ root
ตัวเลือกการ build และการจัดการ image
- หากต้องการ build สำหรับสถาปัตยกรรมอื่น ให้ตั้งค่า environment variable
BANAN_ARCH- ตัวอย่าง:
BANAN_ARCH=i686
- ตัวอย่าง:
- หากต้องการเปลี่ยน bootloader ให้ตั้งค่า environment variable
BANAN_BOOTLOADER- ค่าที่รองรับคือ
BANANและGRUB
- ค่าที่รองรับคือ
- หากต้องการรันด้วย UEFI ต้องตั้งค่า
BANAN_UEFI_BOOT=1- ต้องตั้งค่า
OVMF_PATHให้เป็นพาธ OVMF ที่ถูกต้องด้วย โดยค่าเริ่มต้นคือ/usr/share/ovmf/x64/OVMF.fd
- ต้องตั้งค่า
- หากต้องการสร้าง initrd image โดยไม่มี physical root filesystem ให้ตั้งค่า
BANAN_INITRD=1- ใช้ได้เมื่อต้องการทดสอบบนฮาร์ดแวร์ที่มี USB controller ที่ไม่รองรับ
- หาก disk image เสียหายหรืออยากสร้าง image ใหม่ ให้ลบ
build/banan-os.imgหรือรัน./bos image-full - มี shell completion script สำหรับ zsh ให้ด้วย
- คัดลอกไฟล์
_script/shell-completion/zsh/_bosไปยัง/usr/share/zsh/site-functions/หรือเพิ่ม_script/shell-completion/zshเข้าไปในfpathของ.zshrc
- คัดลอกไฟล์
วิธีมีส่วนร่วม
- upstream ไม่ได้โฮสต์บน GitHub แต่โฮสต์ที่
https://git.bananymous.com/Bananymous/banan-os - สามารถส่ง GitHub PR ได้เช่นกัน แต่ maintainer ต้องดาวน์โหลด diff แล้วนำไปใช้ด้วยตนเอง
- อาจขอบัญชี git server แยกได้ โดยต้องติดต่อทางอีเมลหรือ Discord
- สำหรับการเพิ่มฟีเจอร์ใหม่ แนะนำให้ติดต่อ maintainer ก่อน
- เนื่องจากเป็นโปรเจกต์เพื่อการเรียนรู้ หากส่ง PR โดยไม่ถามล่วงหน้าในฟีเจอร์ที่ maintainer ตั้งใจจะทำเอง PR อาจถูกปิด
- ยินดีรับการแก้บั๊กเสมอ
- ข้อความ commit ต้องเขียนบรรทัดแรกในรูปแบบ
Subject: DescriptionSubjectระบุพื้นที่ที่เปลี่ยนแปลง เช่นKernel,Shell,BuildSystem- บรรทัดแรกต้องไม่เกิน 72 ตัวอักษร
- เนื้อหาควรอธิบายเพิ่มเติมว่าเปลี่ยนอะไรและเพราะเหตุใด
- commit ทั้งหมดต้องผ่าน pre-commit hook ที่กำหนดไว้ใน
.pre-commit-config.yaml
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
เจ๋งมาก และชอบชื่อด้วย อยากรู้ว่าส่วนที่ ยากที่สุด ในบรรดาสิ่งที่ทำมาจนถึงตอนนี้คืออะไร และระหว่างทางมีอุปสรรคร้ายแรงบ้างไหม
AML interpreter ยากเพราะสเปก ACPI เขียนไว้เละเทะมาก ส่วน USB ก็ลำบากเพราะสเปกมีปริมาณมากและมีการอ้างอิงข้ามกันเยอะ
ไม่มีอุปสรรคใหญ่ ๆ แต่บางฟีเจอร์ก็เคยยอมแพ้ไปก่อน แล้วค่อยกลับมาทำต่อหลังจากนั้นหนึ่งหรือสองเดือน
เจ๋งจริง ๆ โดยเฉพาะการ ทำ USB driver ตั้งแต่ศูนย์ นี่สุดยอดมาก อนึ่ง ลองพิมพ์
cat doom1.wadเพื่อทำให้มันพังดูแล้วในการประกาศเคอร์เนลระบบปฏิบัติการใหม่ มักจะมีประโยคหนึ่งที่ต้องใส่ตามธรรมเนียม แต่ประกาศนี้ไม่มีประโยคนั้น
เจ๋งดี อยากรู้ว่าใช้เวลากับโปรเจกต์นี้ประมาณกี่ชั่วโมงต่อสัปดาห์ งานที่ลงไปดูเยอะมาก
ในโปรไฟล์บอกว่าเป็นนักศึกษา หมายถึงนักศึกษามหาวิทยาลัยหรือเปล่า และถ้าใช่ ได้ทำ OS นี้โดยตรงเป็นส่วนหนึ่งของการเรียนด้วยไหม
นอกนั้นโปรเจกต์นี้ไม่ได้เป็นส่วนหนึ่งของการเรียนโดยตรง แต่ก็ต้องขอบคุณโปรเจกต์นี้ที่ทำให้ผมได้งานพาร์ตไทม์ด้าน embedded ที่มหาวิทยาลัย
เวลาที่ทุ่มให้นั้นเปลี่ยนไปมากจริง ๆ ตามแต่ว่าช่วงนั้นชีวิตมีอะไรเกิดขึ้นบ้าง บางเดือนใส่ไปแค่รวม 5 ชั่วโมง แต่บางสัปดาห์ก็ทำเกือบ 40 ชั่วโมง
เป็นโปรเจกต์ที่เจ๋งดี ถ้าจะตั้งชื่อ fork ว่า PlatanOS ก็น่าจะเหมาะ
ดีมาก และดูเป็นงานจำนวนมาก อยากรู้ว่ามี ความท้าทาย อะไรที่น่าจดจำเป็นพิเศษไหม
ยอดเยี่ยมมาก อยากรู้ว่าพัฒนาแบบไหน รันใน VM หรือรันบนฮาร์ดแวร์จริง เวลานั่งลงเริ่มทำงาน กระบวนการเป็นอย่างไรบ้าง
น่าจะได้เรียนรู้อะไรเยอะจากการทำสิ่งนี้ เลยอยากรู้ว่าจดโน้ตหรือติดตามการพัฒนาอย่างไร หรือว่า OS เองเป็นเหมือนบันทึกการพัฒนาที่มีชีวิตอยู่แล้ว
การได้เห็นมันรันบน bare metal จริง ๆ นั้นเจ๋งเสมอ และ bare metal ก็ไม่ใจดีเท่า VM
ปกติจะเลือกฟีเจอร์ที่อยากเพิ่มก่อน จากนั้นอ่านสเปกที่เกี่ยวข้องแบบคร่าว ๆ และบางครั้งก็ดูว่าระบบปฏิบัติการเดิม ๆ จัดการอย่างไร สร้างโมเดลในหัวว่าระบบต้องการอะไร แล้วก็เขียนโค้ดตามที่นึกออกตรงนั้น
ผมมีนิสัยแย่มากคือไม่เขียนเอกสารหรือโน้ต โดยพื้นฐานคือเก็บทุกอย่างไว้ในหัว แล้วพอต้องใช้ข้อมูลนั้นทีหลังก็ลืมไป สำหรับเรื่องที่ซับซ้อนกว่านั้นก็อาจวาดไดอะแกรมและจดโน้ตบ้าง แต่แทบทั้งหมดเก็บไว้แค่ในเครื่อง local
อยากรู้จริง ๆ ว่า driver อย่าง NVMe, ATA, Realtek NIC นี่เริ่มเขียนจากตรงไหนกันแน่ เมาส์กับคีย์บอร์ดรู้ว่าใช้ HID ซึ่งเป็นมาตรฐาน แต่อุปกรณ์อื่น ๆ ก็มี โปรโตคอลมาตรฐาน คล้ายกันไหม
สงสัยด้วยว่านี่คือเหตุผลที่ Linux ส่วนใหญ่เลี่ยง “การติดตั้ง driver” ได้หรือเปล่า และถ้ามี API อุปกรณ์มาตรฐาน แล้วทำไม Windows ถึงต้องผ่านขั้นตอนติดตั้ง driver ทุกครั้งที่เสียบอะไรสักอย่าง
อุปกรณ์ทั้งหมดที่ผมเขียน driver ให้มีสเปกเผยแพร่ให้ใช้ฟรี ตัวอย่างเช่น NVMe อยู่ที่ https://nvmexpress.org/specifications
ผมไม่ค่อยรู้ว่า Linux หรือ Windows จัดการ driver อย่างไร ตอนคอมไพล์ Linux kernel จะระบุว่า driver ไหนจะรวมไว้ใน kernel และ driver ไหนจะปล่อยไว้เป็น module ปกติ driver ที่พบบ่อยจะถูก build มาพร้อมกับ kernel ดังนั้นแทบไม่จำเป็นต้องติดตั้งภายหลัง แค่โหลด driver module ก็พอ
นอกจากนี้ยังมีอุปกรณ์ที่ทำงานได้ด้วย driver ทั่วไป แต่ถ้ามี driver เฉพาะก็จะใช้ฟังก์ชันได้มากขึ้น เช่น การตั้งค่า LED ของเมาส์เกมมิง เป็นต้น Windows อาจจะติดตั้ง driver แบบเลือกได้ เหล่านี้
เป็น side project ที่เจ๋งมาก อยากรู้ว่ามีทิปสำหรับคนที่อยากลองทำอะไรคล้าย ๆ กันไหม เช่นควรเริ่มตรงไหน หรือเอกสารอ้างอิงอะไรดี
ยอดเยี่ยม ไม่คิดว่าจะมีชุดฟีเจอร์แบบนี้ อยากรู้ว่ามีแผนจะพอร์ตซอฟต์แวร์เพิ่มอีกไหม
ในเครื่อง local ยังมี port อีกสองสามตัวที่ยังทำงานไม่ได้
git,binutils,gcc,makeคอมไพล์ได้ทั้งหมด แต่กำลังเจอ error แปลก ๆ น่าจะมีโอกาสสูงว่าเป็น bug ในlibcหรือ system call ของผม