2 คะแนน โดย GN⁺ 2024-12-06 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • 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: Description
    • Subject ระบุพื้นที่ที่เปลี่ยนแปลง เช่น Kernel, Shell, BuildSystem
    • บรรทัดแรกต้องไม่เกิน 72 ตัวอักษร
    • เนื้อหาควรอธิบายเพิ่มเติมว่าเปลี่ยนอะไรและเพราะเหตุใด
  • commit ทั้งหมดต้องผ่าน pre-commit hook ที่กำหนดไว้ใน .pre-commit-config.yaml

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

 
GN⁺ 2024-12-06
ความคิดเห็นบน Hacker News
  • เจ๋งมาก และชอบชื่อด้วย อยากรู้ว่าส่วนที่ ยากที่สุด ในบรรดาสิ่งที่ทำมาจนถึงตอนนี้คืออะไร และระหว่างทางมีอุปสรรคร้ายแรงบ้างไหม

    • ไม่มีส่วนไหนที่ยากเกินไปนัก แต่ถ้าต้องเลือกก็น่าจะเป็น AML interpreter หรือ USB stack
      AML interpreter ยากเพราะสเปก ACPI เขียนไว้เละเทะมาก ส่วน USB ก็ลำบากเพราะสเปกมีปริมาณมากและมีการอ้างอิงข้ามกันเยอะ
      ไม่มีอุปสรรคใหญ่ ๆ แต่บางฟีเจอร์ก็เคยยอมแพ้ไปก่อน แล้วค่อยกลับมาทำต่อหลังจากนั้นหนึ่งหรือสองเดือน
    • ตอนแรกอ่านเป็น “banyan tree” จนกระทั่งเห็น ASCII art ถึงเพิ่งรู้ว่าเป็น การอ้างอิงถึงกล้วย
  • เจ๋งจริง ๆ โดยเฉพาะการ ทำ USB driver ตั้งแต่ศูนย์ นี่สุดยอดมาก อนึ่ง ลองพิมพ์ cat doom1.wad เพื่อทำให้มันพังดูแล้ว

    • ขอบคุณ ข้อมูลที่เขียนไปยัง TTY แทบไม่มี การทำ serialization เลย ดังนั้นถ้าป้อนข้อมูลไบนารีอะไรก็ได้เข้าไป ก็อาจพังได้ :D
  • ในการประกาศเคอร์เนลระบบปฏิบัติการใหม่ มักจะมีประโยคหนึ่งที่ต้องใส่ตามธรรมเนียม แต่ประกาศนี้ไม่มีประโยคนั้น

    • คงหมายถึงประโยคที่ว่า “นี่เป็นโปรเจกต์งานอดิเรก และคงจะไม่ใหญ่โตหรือเป็นมืออาชีพเท่า GNU” แน่ ๆ ใช่ไหม?
  • เจ๋งดี อยากรู้ว่าใช้เวลากับโปรเจกต์นี้ประมาณกี่ชั่วโมงต่อสัปดาห์ งานที่ลงไปดูเยอะมาก
    ในโปรไฟล์บอกว่าเป็นนักศึกษา หมายถึงนักศึกษามหาวิทยาลัยหรือเปล่า และถ้าใช่ ได้ทำ OS นี้โดยตรงเป็นส่วนหนึ่งของการเรียนด้วยไหม

    • ใช่ เป็นนักศึกษามหาวิทยาลัย ผมเอาโปรเจกต์นี้ไปให้ศาสตราจารย์ดู เลยสามารถ “ข้าม” บางวิชาอย่าง ระบบปฏิบัติการ หรือ concurrency ได้
      นอกนั้นโปรเจกต์นี้ไม่ได้เป็นส่วนหนึ่งของการเรียนโดยตรง แต่ก็ต้องขอบคุณโปรเจกต์นี้ที่ทำให้ผมได้งานพาร์ตไทม์ด้าน embedded ที่มหาวิทยาลัย
      เวลาที่ทุ่มให้นั้นเปลี่ยนไปมากจริง ๆ ตามแต่ว่าช่วงนั้นชีวิตมีอะไรเกิดขึ้นบ้าง บางเดือนใส่ไปแค่รวม 5 ชั่วโมง แต่บางสัปดาห์ก็ทำเกือบ 40 ชั่วโมง
  • เป็นโปรเจกต์ที่เจ๋งดี ถ้าจะตั้งชื่อ fork ว่า PlatanOS ก็น่าจะเหมาะ

    • ผมชอบ PlátanOS ที่เน้นเสียงพยางค์แรก
  • ดีมาก และดูเป็นงานจำนวนมาก อยากรู้ว่ามี ความท้าทาย อะไรที่น่าจดจำเป็นพิเศษไหม

    • ผมคิดว่าความท้าทายที่ใหญ่ที่สุดคือ การอ่านเอกสารสเปกขนาดใหญ่ ก่อนหน้านี้ไม่เคยทำแบบนั้นจริงจัง เลยต้องใช้เวลาปรับตัวให้คุ้น
  • ยอดเยี่ยมมาก อยากรู้ว่าพัฒนาแบบไหน รันใน VM หรือรันบนฮาร์ดแวร์จริง เวลานั่งลงเริ่มทำงาน กระบวนการเป็นอย่างไรบ้าง
    น่าจะได้เรียนรู้อะไรเยอะจากการทำสิ่งนี้ เลยอยากรู้ว่าจดโน้ตหรือติดตามการพัฒนาอย่างไร หรือว่า OS เองเป็นเหมือนบันทึกการพัฒนาที่มีชีวิตอยู่แล้ว

    • ประมาณ 95% ของการทดสอบทำใน VM เร็วกว่ามากและสะดวกกว่ามาก แต่ก็ยังทดสอบบนฮาร์ดแวร์จริงเป็นประจำ
      การได้เห็นมันรันบน bare metal จริง ๆ นั้นเจ๋งเสมอ และ bare metal ก็ไม่ใจดีเท่า VM
      ปกติจะเลือกฟีเจอร์ที่อยากเพิ่มก่อน จากนั้นอ่านสเปกที่เกี่ยวข้องแบบคร่าว ๆ และบางครั้งก็ดูว่าระบบปฏิบัติการเดิม ๆ จัดการอย่างไร สร้างโมเดลในหัวว่าระบบต้องการอะไร แล้วก็เขียนโค้ดตามที่นึกออกตรงนั้น
      ผมมีนิสัยแย่มากคือไม่เขียนเอกสารหรือโน้ต โดยพื้นฐานคือเก็บทุกอย่างไว้ในหัว แล้วพอต้องใช้ข้อมูลนั้นทีหลังก็ลืมไป สำหรับเรื่องที่ซับซ้อนกว่านั้นก็อาจวาดไดอะแกรมและจดโน้ตบ้าง แต่แทบทั้งหมดเก็บไว้แค่ในเครื่อง local
  • อยากรู้จริง ๆ ว่า driver อย่าง NVMe, ATA, Realtek NIC นี่เริ่มเขียนจากตรงไหนกันแน่ เมาส์กับคีย์บอร์ดรู้ว่าใช้ HID ซึ่งเป็นมาตรฐาน แต่อุปกรณ์อื่น ๆ ก็มี โปรโตคอลมาตรฐาน คล้ายกันไหม
    สงสัยด้วยว่านี่คือเหตุผลที่ Linux ส่วนใหญ่เลี่ยง “การติดตั้ง driver” ได้หรือเปล่า และถ้ามี API อุปกรณ์มาตรฐาน แล้วทำไม Windows ถึงต้องผ่านขั้นตอนติดตั้ง driver ทุกครั้งที่เสียบอะไรสักอย่าง

    • โดยพื้นฐานแล้ว อุปกรณ์ที่ใช้กันทั่วไปแทบทั้งหมดมีโปรโตคอลที่ถูกทำให้เป็นมาตรฐานอยู่แล้ว แต่ก็มีอุปกรณ์บางชนิดที่ผู้ผลิตต้องจัดหา 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 ที่เจ๋งมาก อยากรู้ว่ามีทิปสำหรับคนที่อยากลองทำอะไรคล้าย ๆ กันไหม เช่นควรเริ่มตรงไหน หรือเอกสารอ้างอิงอะไรดี

    • ก็แทบเหมือนที่คนอื่นพูดไว้ ลองอ่าน https://wiki.osdev.org/Getting_Started และถ้าตัดสินใจพัฒนาระบบปฏิบัติการ ต้องจำไว้ว่า ใช้เวลามาก
    • ความรู้เชิงปฏิบัติดูได้จาก OSDev Wiki ส่วนทฤษฎีก็ดูหนังสือออกแบบระบบปฏิบัติการและสถาปัตยกรรมคอมพิวเตอร์
    • ถ้าใช้ Rust มี https://os.phil-opp.com/ และสำหรับการพัฒนาระบบปฏิบัติการทั่วไปมี https://github.com/tuhdo/os01 และ Operating Systems: Three Easy Pieces เป็นหนังสือที่ควรอ่านอย่างยิ่ง
  • ยอดเยี่ยม ไม่คิดว่าจะมีชุดฟีเจอร์แบบนี้ อยากรู้ว่ามีแผนจะพอร์ตซอฟต์แวร์เพิ่มอีกไหม

    • มีแผนจะพอร์ตเพิ่มอยู่ ผมไม่อยากใส่ โค้ด third-party ลงใน OS พื้นฐาน แต่ port เป็นวิธีที่ดีมากในการทำให้รันสิ่งที่ผมยังไม่ได้เขียนเองได้
      ในเครื่อง local ยังมี port อีกสองสามตัวที่ยังทำงานไม่ได้ git, binutils, gcc, make คอมไพล์ได้ทั้งหมด แต่กำลังเจอ error แปลก ๆ น่าจะมีโอกาสสูงว่าเป็น bug ใน libc หรือ system call ของผม