1 คะแนน โดย GN⁺ 2024-01-01 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • SteamOS 3 “Holo” เป็นดิสโทรที่อิง Arch สำหรับ Steam Deck แต่เพื่อแก้ปัญหา การกลับมาทำงานหลัง suspend บนพีซีในห้องนั่งเล่น จึงต้องย้อน kernel commit และฟอร์กไปถึงอิมเมจ rootfs เอง
  • โครงสร้างการอัปเดตเป็นแบบ A/B โดยติดตั้ง rootfs แบบอ่านอย่างเดียว ตัวใหม่ลงในพาร์ทิชันที่ยังไม่ใช้งานแล้วรีบูต จากนั้น /etc จะใช้ overlayfs เพื่อเก็บการเปลี่ยนแปลงไว้
  • แพตช์เคอร์เนลของ Valve ใช้โฟลว์ที่โคลน bare Git repository จาก source tarball เช่น linux-neptune-61-6.1.52.valve9-1.src.tar.gz ใน pacman source mirror แล้วค่อย build แพ็กเกจด้วยแท็กของตนเองและ PKGBUILD
  • การรีแพ็ก rootfs คือการดึง rootfs.img.caibx ออกจาก SteamOS RAUC bundle ทำเป็นอิมเมจ แล้วเปลี่ยน Btrfs UUID, สลับแพ็กเกจ, เปลี่ยน buildid, เปลี่ยน URL อัปเดตและใบรับรอง RAUC ก่อนจะรวมกลับเป็น RAUC bundle อีกครั้ง
  • หากมีเว็บเซิร์ฟเวอร์ของตนเองที่ให้บริการ live.json และเปลี่ยน QueryUrl, ImagesUrl, MetaUrl ของ steamos-atomupd ก็สามารถทำให้การติดตั้ง SteamOS เดิมอัปเดตไปใช้อิมเมจของตนเองได้

เหตุผลที่ฟอร์ก SteamOS ให้เหมาะกับพีซีในห้องนั่งเล่น

  • SteamOS 3 “Holo” คือ ดิสโทร Linux ที่อิง Arch สำหรับเครื่องเล่นเกมพีซีพกพา Steam Deck ของ Valve Software
  • วิธีอัปเดตเป็นโครงสร้าง A/B atomic update โดยดาวน์โหลด rootfs แบบอ่านอย่างเดียวตัวใหม่ลงในพาร์ทิชันที่ไม่ได้ใช้งาน แล้วรีบูตเข้าไปใช้พาร์ทิชันนั้น
  • ผู้ใช้สามารถรัน steamos-devmode เพื่อปลดล็อก rootfs และทำให้ฐานข้อมูล pacman กลับมาปกติ จากนั้นก็ใช้งานได้คล้ายดิสโทร Linux ทั่วไป
  • เป้าหมายคือการสร้าง ฟอร์กที่แท้จริง ซึ่งแก้ไขอิมเมจ rootfs ได้โดยตรง แทนการเลี่ยงข้อจำกัดแบบง่าย ๆ ด้วย steamos-devmode
  • บนพีซีในห้องนั่งเล่น SteamOS แทบจะทำงานได้หมด ยกเว้นแค่ การกลับมาทำงานหลัง suspend ที่ล้มเหลว
    • บนเครื่องเดียวกันนี้ ดิสโทรอื่นที่ใช้เคอร์เนล mainline หรือ stable สามารถกลับมาหลัง suspend ได้ตามปกติ
    • หลังหา source ของเคอร์เนล Valve แล้วทำ git bisect ก็พบว่ามี commit ที่ดูเหมือนจะไว้แก้การกลับมาหลัง suspend บนฮาร์ดแวร์ Steam Deck แต่กลับก่อปัญหากับพีซีเครื่องนี้
    • การต้องย้อน commit นั้นและ build เคอร์เนลเอง จึงเป็นเหตุผลตรง ๆ ของงานทั้งหมดนี้
  • แม้จะมีทางเลือกอย่างการใช้ Arch โดยตรง แต่หากต้องปรับแต่งดิสโทร Linux สำหรับรันเกม ก็ยังชอบพึ่งชุดแพ็กเกจที่ Valve ทดสอบไว้มากกว่า

โครงสร้างพาร์ทิชันและการอัปเดตของ SteamOS

  • ระบบ SteamOS ใช้ 8 พาร์ทิชัน
    • EFI system partition มี stage 1 bootloader และเมทาดาทาสำหรับเลือกชุดพาร์ทิชัน A/B
    • แต่ละชุด A/B มี GRUB ซึ่งเป็น stage 2 bootloader, root filesystem และพาร์ทิชัน /var
    • พื้นที่ดิสก์ที่เหลือจะเป็นพาร์ทิชัน home เดียว
  • ตอนบูตจะมีการ mount pseudo-filesystem เพิ่มเติมอีกหลายจุด
    • ไดเรกทอรีเกือบ 12 ตัว เช่น /var/log, /root, /nix จะถูก bind mount จาก /home/.steamos/offload เพื่อให้ข้อมูลคงอยู่ถาวร
  • /etc ถูกจัดการด้วย overlayfs
    • ส่วนที่เปลี่ยนแปลงจะถูกเก็บไว้ใน /var/lib/overlays/etc/upper
    • รายการอย่าง machine-id หรือการเชื่อมต่อของ NetworkManager ซึ่งปกติควรอยู่ใน /etc จะยังคงอยู่
    • ไฟล์คอนฟิกที่ไม่ได้แก้ไขสามารถถูกอัปเดตได้
    • วิธีนี้ทำให้จัดการทั้งการคงคอนฟิกและการอัปเดตในโครงสร้างพาร์ทิชัน A/B ได้ โดยไม่ต้องมีตรรกะของ package manager
  • การอัปเดตระบบเริ่มต้นเมื่อ Steam client หรือผู้ใช้ในเทอร์มินัลรัน steamos-update
    • คำสั่งนี้จะเรียกโปรแกรม Python steamos-atomupd-client
    • ไคลเอนต์จะส่งข้อมูล OS ปัจจุบันและการตั้งค่าช่องทางอัปเดตของผู้ใช้ไปยัง URL ใน /etc/steamos-atomupd/client.conf เพื่อตรวจสอบว่ามีอัปเดตใหม่หรือไม่
  • หากมีอัปเดตใหม่ เซิร์ฟเวอร์จะตอบกลับเป็นพาธของ RAUC bundle
    • ไคลเอนต์จะดาวน์โหลด bundle แล้วรัน rauc install
    • RAUC จะตรวจสอบลายเซ็นของ bundle และค้นหา rootfs.img.caibx
    • จากนั้น casync extract จะดาวน์โหลดชิ้นส่วนของอิมเมจใหม่แล้วเขียนลงพาร์ทิชัน rootfs ที่ไม่ได้ใช้งาน
    • สคริปต์หลังติดตั้งจะซิงก์ข้อมูลบางส่วนจาก /var ที่ใช้งานอยู่ไปยัง /var ที่ไม่ได้ใช้งาน และเปลี่ยนค่าตั้งค่า stage 1 bootloader ใน EFI system partition เพื่อให้บูตเข้าชุดพาร์ทิชันใหม่

การสร้างแพ็กเกจจาก source เคอร์เนลของ Valve

  • Valve ใช้ Linux kernel ที่แก้ไขเพิ่มเติมอย่างมากใน SteamOS และเปิดให้ดาวน์โหลด source ได้
  • source ของอิมเมจ SteamOS ปัจจุบันหาได้จาก sources/holo-3.5 และ sources/jupiter-3.5 ใน pacman mirror ของ Valve
  • ณ เวลาที่เขียน เคอร์เนลของอิมเมจ stable คือ 6.1.52-valve9-1-neptune-61 และ source tarball มีขนาด 2.9GiB
  • เหตุผลที่ tarball ใหญ่ เพราะมันบรรจุ Linux Git tree ทั้งชุดไว้
    • ภายใน tarball มี PKGBUILD, config, config-neptune, archlinux-linux-neptune/ เป็นต้น
    • archlinux-linux-neptune/ ไม่ใช่ working tree ปกติที่เปิดมาทำงานได้ทันที แต่เป็น bare repository
  • PKGBUILD ชี้ source ไปยัง GitLab repository แบบปิดในรูป git+ssh://git@gitlab.steamos.cloud/jupiter/linux-integration.git#tag=$_tag
    • จึงไม่สามารถ clone ตรง ๆ หรืออ้างลิงก์ commit ได้
    • แต่จาก source ของ makepkg สามารถได้ snapshot ที่มีประวัติ commit ทั้งหมดของแต่ละแท็ก
    • โครงสร้างนี้เองที่ทำให้สามารถ bisect หา commit ที่ทำให้การกลับมาหลัง suspend บนพีซีในห้องนั่งเล่นพังได้
  • วิธีทำงานคือ clone bare repository ออกมาเป็น working tree ปกติ แล้วดูแล branch กับ tag ของตนเอง
    • ตัวอย่างคือสร้าง my-branch จากแท็ก 6.1.52-valve9
    • การเปลี่ยนแปลงของตนเองจะถูก push ไปยัง Git host แยกต่างหาก แล้วเปลี่ยน source ใน PKGBUILD ให้ชี้ไปยัง repository และแท็กของตนเอง
    • มี repository ตัวอย่างคือ linux
  • สามารถสร้างแพ็กเกจเคอร์เนลด้วย makepkg
    • makepkg MAKEFLAGS=-j$(nproc) หรือการปรับ /etc/makepkg.conf จะมีประโยชน์ถ้าไม่ได้ build บน VM ขนาดเล็ก
    • เท่าที่ตรวจดู แพ็กเกจเฉพาะของ SteamOS อื่น ๆ ก็ใช้โครงสร้างคล้ายกัน โดยใช้ Git repository เป็น source แรก
  • เพื่อให้ขั้นตอนถัดไปง่ายขึ้น จึงตั้งค่า pacman repo ของตัวเอง
    • วางแพ็กเกจไว้ในไดเรกทอรี แล้วรัน repo-add $REPO_NAME.db.tar.zst [PACKAGES...] ก่อนอัปโหลดขึ้นเว็บโฮสต์
    • repo นี้ยังช่วยให้เครื่องมือทำงานได้ถูกต้องในภายหลัง แม้จะรัน steamos-devmode ก็ตาม

การดึงและ mount root filesystem

  • เนื่องจากหา release engineering script ไม่พบ จึงเลือกวิธี รีแพ็ก root filesystem เดิมให้ตรงความต้องการ
  • สคริปต์ที่ไม่มีคำอธิบายและคอมเมนต์อยู่ที่ fauxlo
  • วิธีทั่วไปในการได้อิมเมจ rootfs ของ SteamOS คือซื้อ Steam Deck หรือดาวน์โหลดอิมเมจกู้คืนของ Steam Deck แต่ทั้งสองวิธีต้องยอมรับ Steam End User License Agreement
  • สามารถดูเวอร์ชันรีลีสปัจจุบันได้จาก snapshot JSON ซึ่งดูเหมือนเป็น fallback URL ของระบบอัปเดต
    • ตอนที่เขียน เวอร์ชัน stable คือ 20231122.1
    • และมี snapshot JSON แยกสำหรับช่อง preview ด้วย
  • การดาวน์โหลด rootfs ทำตามลำดับเดียวกับ steamos-atomupd-client
    • ดาวน์โหลดไฟล์ .raucb ซึ่งเป็น RAUC bundle
    • แตก rootfs.img.caibx ออกจาก bundle ซึ่งเป็นไฟล์ระบบแบบ SquashFS
    • ใช้ casync extract ดึงชิ้นส่วนจาก .castr store เพื่อสร้าง rootfs.img
    • URL ของ .castr store คือการแทน .raucb ใน URL ของ RAUC bundle ด้วย .castr
    • พฤติกรรมนี้ถูก hardcode ไว้ใน steamos-atomupd
    • มีสคริปต์อัตโนมัติอยู่ที่ fetch-current.sh
  • ไฟล์ .img.zip และ .img.zst ที่อยู่ข้างกันไม่ใช่ rootfs แต่เป็น อิมเมจกู้คืน ที่บูตได้ต่างหาก
    • สามารถดึงพาร์ทิชัน rootfs จากอิมเมจกู้คืนนี้ไปใช้ในขั้นตอนถัดไปได้เช่นกัน
    • แต่ไฟล์นั้นไม่เหมือนกับอิมเมจที่ได้จาก RAUC และ casync แบบ bit-for-bit และยังไงก็ต้องใช้เครื่องมือชุดนี้อยู่ดีเมื่อต้องสร้าง update bundle ใหม่
  • ก่อนแก้ไข rootfs ต้องเปลี่ยน filesystem UUID ก่อน
    • ถ้าอัปเดตจากอิมเมจ SteamOS เดิมไปเป็นอิมเมจที่ปรับแต่งเองโดยไม่เปลี่ยน UUID จะทำให้มี filesystem สองตัวที่ใช้ UUID เดียวกัน
    • สถานะนี้อาจทำให้เกิดปัญหาได้
    • ตัวอย่างคือ btrfstune -fu rootfs.img
  • Valve ใช้ อิมเมจ Btrfs ที่บีบอัดด้วย zstd
    • หากต้องการคงการบีบอัดไว้ระหว่างแก้ไข ให้ mount ด้วย mount -o compress=zstd rootfs.img rootfs
    • SteamOS ใช้คุณสมบัติ readonly ของ Btrfs subvolume จึงต้องปลดด้วย btrfs property set -ts rootfs ro false
  • การแก้แพ็กเกจอย่าง Linux kernel อาจกระตุ้นสคริปต์ที่ต้องใช้ /dev และ /proc
    • จึงต้อง mount devtmpfs และ proc ไว้ใต้ rootfs
    • เพื่อไม่ให้เกิดการเขียนลงไดเรกทอรีที่ระบบจริงจะ mount ตอนบูต จึง mount tmpfs ให้กับ /tmp, /run, /var, /home
    • และ bind mount /etc/resolv.conf ของโฮสต์เพื่อให้ chroot แก้ชื่อได้

การสลับแพ็กเกจและแก้เมทาดาทาของอิมเมจ

  • เพิ่ม repository ของตนเองเป็น repo รายการแรกใน /etc/pacman.conf
    • วิธีนี้ทำให้แพ็กเกจของตนเองถูกเลือกก่อน แม้ใน Valve repo จะมีแพ็กเกจเวอร์ชันใหม่กว่า
    • และยังทำให้ติดตั้งแพ็กเกจของตนเองกลับเข้าไปใหม่ได้ภายหลัง แม้จะรัน steamos-devmode
  • ตัวอย่าง stanza ของ repo ใช้ [fauxlo], Server = https://fauxlo.ili.fyi/pacman/$arch, SigLevel = Never
    • SigLevel = Never หมายถึงอนุญาตให้ใช้แพ็กเกจที่ไม่มีลายเซ็น
    • หากต้องการติดตั้งแพ็กเกจที่เซ็นด้วย GPG ก็ต้องเติม pacman keyring ให้พร้อม
    • แทนที่จะไปแตะ keyring ว่างใน /etc/pacman.d/gnupg วิธีที่ใช้คือสร้าง keyring ใหม่บน tmpfs แล้วเติมข้อมูลลงไป
  • การติดตั้งแพ็กเกจทำได้ในรูป pacman --sysroot rootfs --noconfirm -Sy linux-neptune-61
    • แต่ในสคริปต์จริงจะหลีกเลี่ยง -y และซิงก์เฉพาะฐานข้อมูล repo ของตัวเองจากฝั่ง pacman แทน
    • วิธีนี้ช่วยตรึงสถานะของ repository อื่น ๆ ไว้ตามช่วงเวลาที่อิมเมจต้นฉบับถูก build
    • เป็นการตัดสินใจเพื่อลดความต่างที่ปรากฏใน image diff
  • steamos-atomupd จะอ่านเวอร์ชันอิมเมจปัจจุบันและ build ID จาก /lib/steamos-atomupd/manifest.json หรือถ้าไม่มีจึงค่อยใช้ /etc/os-release
    • หาก build ID ของอัปเดตที่เซิร์ฟเวอร์ส่งมาเท่ากับอิมเมจปัจจุบัน ระบบจะปฏิเสธการอัปเดต
    • ข้อมูลนี้ยังมีประโยชน์ในการระบุว่าเครื่องกำลังรันอิมเมจใดอยู่
  • build ID ต้องอยู่ในรูปแบบ YYYYMMDD.N เท่านั้น
    • ถ้ารูปแบบไม่ตรง steamos-atomupd จะจบการทำงานพร้อม Python traceback
    • เพื่อไม่ต้องเพิ่ม N เองทีละขั้น สามารถใส่ HHMMSS หรือ Unix timestamp ลงใน N ได้
    • ต้องเปลี่ยนทั้ง buildid ใน manifest.json และ BUILD_ID ใน os-release
    • มีชิ้นส่วนสคริปต์ Bash สำหรับงานนี้อยู่ใน repack.sh
  • RAUC ใช้ ใบรับรอง X.509 สำหรับการตั้งค่าความเชื่อถือ
    • ใบรับรองที่เชื่อถืออยู่ใน /etc/rauc/keyring.pem
    • ใช้เพียง self-signed certificate ธรรมดาก็เพียงพอ
    • แล้วติดตั้งใบรับรองใหม่ลงใน rootfs/etc/rauc/keyring.pem
  • เปลี่ยน URL ใน rootfs/etc/steamos-atomupd/client.conf ให้ชี้ไปยังเซิร์ฟเวอร์ของตนเองด้วย
    • QueryUrl
    • ImagesUrl
    • MetaUrl
  • หากยังไม่เกินพื้นที่ของอิมเมจ Btrfs ขนาด 5GiB ก็สามารถแก้ไขอย่างอื่นได้อีก
    • เช่น ถ้าอยากหาอุปกรณ์ SteamOS บนเครือข่ายด้วย hostname.local ก็สามารถลบ rootfs/usr/lib/systemd/resolved.conf.d/00-disable-mdns.conf ได้
    • จะใช้การ override ผ่าน /etc overlay ก็ได้ แต่เห็นว่ายุ่งยากกว่า
  • โดยหลักแล้ว ถ้ามีการเปลี่ยนแปลงที่ทำได้ง่ายโดยไม่ต้องใส่ลงอิมเมจ ก็ควรหลีกเลี่ยงการใส่ไว้ใน rootfs
    • ตัวอย่างเช่นสามารถติดตั้ง Firefox ลงใน rootfs ได้
    • แต่ทุกครั้งที่ Firefox มีอัปเดตความปลอดภัย ก็จะต้องรีแพ็กอิมเมจใหม่อีก

การ unmount rootfs และสร้าง RAUC bundle

  • เมื่อแก้ไขเสร็จแล้ว ให้ตั้ง filesystem กลับเป็น read-only อีกครั้ง
    • btrfs property set -ts rootfs ro true
  • บล็อกที่ไม่ได้ใช้งานให้ discard ด้วย fstrim -v rootfs
  • การ unmount ใช้ umount --recursive rootfs ได้สะดวก
    • เพราะจัดการ pseudo-filesystem ที่ mount ไว้ก่อนหน้านี้ได้พร้อมกัน
  • ก่อนสร้าง RAUC bundle ต้องสร้าง casync store และ blob index ก่อน
    • ตัวอย่างคือ casync make --store=rootfs.img.castr bundle/rootfs.img.caibx rootfs.img
  • RAUC bundle ต้องมี 3 ไฟล์
    • manifest.raucm
    • rootfs.img.caibx
    • UUID ที่เก็บ filesystem UUID
  • ใน manifest.raucm จะมีข้อมูลอัปเดตและข้อมูลของอิมเมจ rootfs
    • compatible=steamos-amd64
    • version=$version
    • sha256
    • size
    • filename=rootfs.img.caibx
  • ไฟล์ UUID สร้างได้ด้วย blkid -s UUID -o value rootfs.img >bundle/UUID
  • เมื่อเตรียมทั้งสามไฟล์แล้ว ให้รัน rauc bundle
    • ระบุใบรับรองและกุญแจผ่าน --signing-keyring, --cert, --key
    • ผลลัพธ์จะเป็น rootfs.img.raucb
  • จากนั้นอัปโหลด rootfs.img.raucb และ rootfs.img.caibx ไปยังเว็บเซิร์ฟเวอร์ที่ ImagesUrl ใน client.conf ชี้อยู่
    • ทั้งสองไฟล์ต้องอยู่ในไดเรกทอรีเดียวกัน

เซิร์ฟเวอร์อัปเดตของตัวเองและการนำไปใช้

  • เว็บเซิร์ฟเวอร์ที่ใช้กับ QueryUrl และ MetaUrl ต้องให้บริการไฟล์ JSON
  • หากตั้งค่าแบบง่าย ไฟล์ live.json ไฟล์เดียวก็เพียงพอ
    • อ็อบเจ็กต์ .minor.candidates[0].image ต้องตรงกับ /lib/steamos-atomupd/manifest.json ที่อยู่ในอิมเมจ
    • update_path คือพาธที่ไคลเอนต์อัปเดตจะนำไปต่อท้าย ImagesUrl เพื่อดาวน์โหลด bundle
  • ตัวอย่างการตั้งค่า Caddy จะ rewrite คำขอที่ steamos-atomupd ส่งไปยัง QueryUrl และ MetaUrl ให้ไปหา live.json
    • rewrite /updates ไปเป็น /live.json
    • rewrite /meta/*/*/*/*.json และ /meta/*/*/*/*/*.json ไปเป็น /live.json
    • ใช้ file_server browse
  • แม้ QueryUrl และ MetaUrl ของ SteamOS จริงจะดูเหมือนมีตรรกะมากกว่านี้ แต่การตั้งค่าแบบนี้ก็เพียงพอให้ steamos-atomupd หาอัปเดตใหม่เจอ
  • ยังมีตรรกะที่หลีกเลี่ยงการอัปเดต หากอิมเมจที่ประกาศไว้เป็นตัวเดียวกับที่กำลังรันอยู่
  • หากต้องการให้อินสแตนซ์ SteamOS เดิมอัปเดตมาใช้อิมเมจของตนเอง ให้แก้ /etc/rauc/keyring.pem และ /etc/steamos-atomupd/client.conf
    • ไม่จำเป็นต้องใช้ steamos-readonly disable
    • การเปลี่ยนแปลงจะถูกเก็บใน /etc overlay
    • หลังรัน steamos-update แล้ว อาจพิจารณาล้างการเปลี่ยนแปลงเหล่านั้นออกจาก /var/lib/overlays/etc/upper
  • น่าจะสามารถติดตั้ง SteamOS ที่ดัดแปลงแล้วได้ด้วยการแก้หนึ่งในอิมเมจกู้คืนของ Valve แล้วแทนที่ rootfs ด้วยอิมเมจของตนเอง แต่ยังไม่ได้ทดสอบวิธีนี้

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

 
GN⁺ 2024-01-01
ความคิดเห็นจาก Hacker News
  • ชอบบทความแบบนี้ที่ลงลึกเรื่องการปรับแต่งซอฟต์แวร์/OS ของอุปกรณ์ที่ตัวเองมีอย่างจริงจัง อีกอย่างที่ดีใจคือบน Steam Deck ไม่ต้องกังวลเรื่อง Tivoization
    ส่วนที่น่าสนใจที่สุดในบทความสำหรับผมคือพาร์ทิชัน /nix ผมไม่รู้ว่า Steam Deck รองรับ nixpkgs พอไปหาข้อมูลเพิ่มก็พบว่า แม้จะไม่ใช่การติดตั้งเริ่มต้น แต่ก็เอาไปลงบนเครื่องได้โดยไม่ต้องฟอร์ก OS ทั้งระบบ

    • เดิมที Nix ก็สามารถติดตั้งบน OS ตระกูล *nix ใด ๆ ได้โดยไม่ต้อง “ฟอร์ก OS ทั้งระบบ” อยู่แล้ว
      ที่เก็บของ Nix จะวางไว้ตรงไหนก็ได้ที่เขียนได้ แล้วแค่เปลี่ยนให้ $PATH ชี้ไปยังไดเรกทอรีของ symbolic link ก็พอ
    • มีใครรู้ไหมว่าใน Steam Deck ใช้อะไรจาก nixpkgs บ้าง? ผมเองก็ใช้ nixpkgs เยอะ เลยสงสัย แต่น่าเสียดายที่ไม่มี Steam Deck
  • เป็นบทความที่ละเอียดและน่าสนใจมาก ส่วนตัวคงไม่ทำถึงขั้นนี้แน่นอน
    ประสบการณ์กับ Linux ของผมมีแค่สมัยใช้ Raspberry Pi และถึงอย่างนั้นก็คงแค่ราว ๆ 1% เลยรู้สึกว่าผู้เขียนสุดยอดมาก

    • ผมเองก็เคยอยู่ในสถานการณ์คล้ายกับผู้เขียน ต้องบิลด์ เคอร์เนล Red Hat เองอยู่นานพอสมควรด้วยเหตุผลที่ค่อนข้างเฉพาะทางมาก คือเพื่อข้ามการตรวจ RMRR แล้ว passthrough GPU ไปยัง Windows VM
      คล้ายกับ https://github.com/kiler129/relax-intel-rmrr แต่ไม่ใช่ repo ของผม
      สาเหตุรากเหง้าแก้ได้แค่ด้วย ROM update จากผู้ผลิต แต่ DL360 รุ่นเก่าที่ผมใช้อยู่ HPE เลิกซัพพอร์ตแล้ว
      ตัวแพตช์เองเปลี่ยนแค่บรรทัดเดียว แต่การอัปเดตเคอร์เนลยุ่งยาก ต้องไปเอา SRPM มา และเพราะไม่มี Git repository ก็ต้องแตก SRPM ออกมา ใส่แพตช์ แล้วบิลด์และติดตั้งใหม่
    • ถ้าอยากได้ทีวี ไม่นานนี้อาจไม่มีตัวเลือกจริง ๆ เหลือแล้วก็ได้
  • มีดิสโทรที่สร้างจากองค์ประกอบของ SteamOS อยู่แล้ว และปรับให้เหมาะกับการใช้บน PC กับคอนโทรลเลอร์ ChimeraOS ทำงานในสภาพแวดล้อมของผมได้ค่อนข้างไม่มีปัญหา แถมรวม EmuDeck ซึ่งเป็นเครื่องมือเสริมสำหรับ Steam Deck มาด้วย

  • ผมสั่ง GPU มาเพื่อจะรัน Steam Headless บนเซิร์ฟเวอร์ NAS unRaid เป็น Docker image เจ๋ง ๆ แล้วเข้าใช้งานจากแล็ปท็อป Windows ด้วยไคลเอนต์อย่าง Moonlight
    ถ้าใช้งานได้ดี ก็ดีกว่าการซื้อฮาร์ดแวร์เดสก์ท็อปสำหรับเล่นเกมเพิ่มอีกชุด ทั้งที่มี NAS ที่ส่วนใหญ่ว่างอยู่มาก เพียงแต่ต้องตั้งค่าพลังงานของการ์ด Nvidia ให้คงอยู่ในโหมด idle ตอนที่ไม่ได้ใช้ หวังว่าน่าจะทำได้ด้วยการเรียก nvidia-persistenced
    1: https://github.com/Steam-Headless/docker-steam-headless

    • ผมก็ใช้เวลาค่อนข้างมากพยายามทำเกือบแบบเดียวกันด้วย GOW ยากกว่าที่คิดไว้เยอะ และต้องใช้ปลั๊ก HDMI dummy ด้วยเพื่อให้ตั้งค่า X server ได้ถูกต้อง
      1: https://github.com/games-on-whales/gow
    • อีกทางเลือกหนึ่งคือรัน KVM ที่มี GPU passthrough แล้วใช้ cloud-init เพื่อเปิด Sunshine กับเกม หรือไม่ก็ใช้จอภาพโดยตรงไปเลย
      https://kubevirt.io/user-guide/virtual_machines/host-devices...
      นี่มันการรันเกมแบบ declarative cloud-native เลยนะ!
      kubectl apply -f crysis.yaml
    • ดูดีเลย ตอนนี้ผมใช้ Sunshine + Moonlight อยู่ แต่เร็ว ๆ นี้ตั้งใจจะทดสอบ ประสิทธิภาพของ Steam Headless
    • น่าสนใจทีเดียว เวลาสตรีมบนเครือข่ายภายในแบบนี้ รู้สึกถึงข้อจำกัดด้าน input latency หรือคุณภาพวิดีโอบ้างไหม?
    • ดีเลย ผมจินตนาการถึงการตั้งค่าแบบนี้มาตลอด: เอา เกมผลัดกันเล่นแบบ hotseat อย่าง Civilization ไปรันบนเซิร์ฟเวอร์ แล้วให้รีโมตเข้าไปผ่านเบราว์เซอร์ เพื่อเล่นเกมแบบเทิร์นยาว ๆ กับเพื่อนได้ทุกที่ทุกเวลา
  • วันนี้เพิ่งรู้จัก RAUC(https://rauc.io/) เคยสงสัยอยู่ว่า Valve ใช้วิธีอัปเดตแบบ A/B อย่างไร

  • คิดถึง favicon รูปฝนดาวตก ของ Netscape กันบ้างไหม?

  • เป็นบทความที่น่าสนใจ การอัปเกรดแบบ A/B ดูจะเกินจำเป็นไปหน่อย ถ้ามีปัญหาก็บูต live distro หรือไม่ก็ติดตั้งระบบกู้คืนเวอร์ชันเก่าไว้ในพาร์ทิชันแยกก็ได้
    ช่วงไม่กี่ปีมานี้ผมใช้ NixOS แล้วกลับมาใช้ Arch ก่อนหน้านั้นก็ใช้ Arch มานาน และคิดว่าความกังวลของผู้เขียนน่าจะไม่ตรงนัก
    Arch เป็นดิสโทรที่จริงจังและเติบโตเต็มที่มากอย่างแน่นอน และไว้ใจได้มากกว่า Valve
    เหตุผลที่ย้ายมา Arch คือเรื่อง คุณภาพแพ็กเกจ repository หลักอัปเดตเร็วมากจริง ๆ และ AUR ก็มีแพ็กเกจมีประโยชน์จำนวนมาก

    • คุณกับผมบูต live distro ได้ แต่ผู้ใช้คอมพิวเตอร์ส่วนใหญ่ทำไม่ได้ Valve ชัดเจนว่ามุ่งทำเพื่อผู้ใช้ทั่วไป และไม่ว่าผมจะชอบ Linux distro แค่ไหน พวกมันก็ยังทำเรื่องนั้นได้ไม่ดีนัก
      การที่ระบบกู้คืนตัวเองอัตโนมัติหลังอัปเกรดล้มเหลว แทบจะเป็นสิ่งจำเป็นสำหรับ OS ที่ดูแลน้อย ในยุคนี้
    • ไม่ควรคาดหวังให้ผู้ใช้ Steam Deck ต้อง บูต live distro เพื่อซ่อมอัปเกรดที่พัง ทุกอย่างควรราบรื่นและจัดการเองอยู่เบื้องหลัง
    • ทำได้ก็จริง แต่ตอนนี้เรามีเทคโนโลยีที่ทำให้เรื่องแบบนั้นไม่จำเป็นแล้ว และดิสก์ก็ไม่ได้แพงขนาดนั้น จึงไม่มีเหตุผลนักที่จะไม่ทำ
    • โดยแก่นแล้ว Steam Deck ใกล้เคียงกับ Chromebook สำหรับวิดีโอเกม ดังนั้นแนวคิดพาร์ทิชันแบบที่พังยากของ ChromeOS ก็ดูสมเหตุสมผล
    • ช่วยยกตัวอย่างเรื่องที่ย้ายจาก NixOS เพราะคุณภาพแพ็กเกจของ Arch ได้ไหม?
      โดยรวมแล้วผมมองว่า คุณภาพของ แพ็กเกจ NixOS ค่อนข้างสูง
  • ช่วงนี้ได้ลองใช้ Legion Go ซึ่งเป็นอุปกรณ์พกพาสำหรับเล่นเกมรุ่นใหม่ และได้สัมผัส Linux มากขึ้น เมื่อก่อนเคยเลี่ยง เพราะดูเหมือนเป็นการเสียเวลาไปกับการปรับแต่งไม่รู้จบ และความเข้ากันได้กับสิ่งที่อยากใช้จริงก็มีข้อจำกัด
    พอได้อ่านเรื่องระบบไฟล์แบบ immutable และการที่ Linux แบบดั้งเดิมมักยอมให้ซอฟต์แวร์สารพัดชนิดได้สิทธิ์ root กันง่าย ๆ ก็เริ่มสนใจขึ้นมา
    ตอนนี้ใช้ NixOS อยู่ ซึ่งแน่นอนว่าอาจกลายเป็นการเสียเวลาไปกับการปรับแต่งได้ แต่เหมาะกับการสำรวจมาก สามารถลองคอมโพเนนต์ต่าง ๆ ได้ง่าย และถ้าตัดสินใจไม่เก็บไว้ ก็ลบออกได้หมดจด ยกเว้นแค่ระดับที่ ~/.config อาจปนเปื้อนอยู่บ้าง การแพตช์ก่อนติดตั้งก็เป็นเรื่องเล็กน้อย จึงเพิ่มแพตช์เคอร์เนลที่ทำให้ใช้ Linux บนฮาร์ดแวร์แปลก ๆ อย่างอุปกรณ์พกพาสำหรับเล่นเกมได้ง่าย
    มีชุมชน NixOS ชื่อ Jovian ที่นำ tarball SteamOS แบบสุ่มของ Valve มาจัดโครงใหม่ให้เป็นคอมมิตติดแท็กบน GitHub ทำให้สามารถไล่ดูซอร์สได้เหมือนพนักงาน Valve แค่เพิ่มไม่กี่บรรทัดในคอนฟิก Nix ก็สามารถติดตั้งสำเนา SteamOS ของตัวเองบน NixOS ได้
    คนกลุ่มนี้เป็นผู้เชี่ยวชาญ Linux อย่างชัดเจน และจากซอร์สจะเห็นได้ว่า พวกเขารับแพ็กเกจของ Valve มาโดยแทบไม่แตะต้อง ยกเว้นการปรับแก้ง่าย ๆ เช่น ตรวจสอบตำแหน่งปุ่มเปิด/ปิดแทนการ hardcode
    ถ้าต้องการประสบการณ์ SteamOS แบบบริสุทธิ์ แต่ไม่อยากดูแล mirror ของระบบอัปเดตของ Valve เอง หรืออยากสำรวจซอร์สของ Valve โดยไม่ต้องดาวน์โหลด tarball ขนาด 3GB ก็น่าลองใช้ Jovian
    คู่มือติดตั้ง: https://jovian-experiments.github.io/Jovian-NixOS/getting-st...
    mirror ซอร์สของ Valve: https://github.com/orgs/Jovian-Experiments/repositories?type...

    • ผมก็ใช้ Jovian-NixOS บน Steam Deck ได้ดีไม่มีปัญหา เลยแนะนำอย่างยิ่ง
  • bazzite.gg ก็ทำเรื่องนี้ได้ดีมาก บนฮาร์ดแวร์ AMD นั้น 120Hz VRR ใช้งานได้ทันที และยังสามารถทดสอบการรองรับ HDR แบบ alpha ได้ด้วย

    • เพิ่งเคยได้ยินชื่อ Bazzite
      “Bazzite เป็น OCI image ที่ใช้เป็นระบบปฏิบัติการทางเลือกสำหรับ Steam Deck ได้ และเป็นสภาพแวดล้อมคล้าย SteamOS ที่พร้อมเล่นเกมสำหรับคอมพิวเตอร์เดสก์ท็อป, พีซีโฮมเธียเตอร์ในห้องนั่งเล่น และพีซีพกพาหลายรุ่น”
      https://github.com/ublue-os/bazzite/
      ต่อให้ไม่สนใจ README ก็น่าอ่าน รายการสิ่งที่รวมมาให้ยาวมาก และหลายรายการก็ดูเจ๋งและมีประโยชน์มาก โดยเฉพาะสำหรับเกมเมอร์หรือสตรีมเมอร์
    • Bazzite และ immutable Linux โดยรวมเป็นเรื่องน่าสนใจ
      ยังไม่ได้ขุดลึกพอจะอธิบายให้กระชับและสมบูรณ์ได้ในคอมเมนต์ HN เดียว แต่แก่นคือมีดิสโทร Linux แบบอ่านอย่างเดียวที่ผ่านการตรวจสอบแล้วอยู่ที่ root แล้ววางแพ็กเกจซ้อนเป็นชั้นไว้ด้านบน โครงสร้างนี้ได้แรงบันดาลใจมากจากคอนเทนเนอร์ฝั่งเซิร์ฟเวอร์
      เป้าหมายคือให้ปลอดภัยกว่า เชื่อถือได้กว่า ทำซ้ำได้ และปรับแต่งง่ายกว่า Linux แบบดั้งเดิม ถ้าเขียนแพ็กเกจที่ต้องการไว้ใน container manifest เมื่อมีอัปเกรด ก็รันอัปเกรดแล้วติดตั้งแพ็กเกจเหล่านั้นซ้ำทับด้านบน
    • จุดที่เกี่ยวข้องมากกว่าคือ สามารถ fork Bazzite ได้ค่อนข้างง่าย เพื่อเพิ่มแพ็กเกจที่ขาดหรือการตั้งค่าที่ต้องใช้ลงในอิมเมจแบบกำหนดเอง แล้วปล่อยให้งานโครงสร้างพื้นฐานส่วนใหญ่เป็นหน้าที่ของ GitHub Actions
      https://universal-blue.org/guide/fork-your-own/
      และเพราะเป็น OS แบบ immutable ถ้าเกิดปัญหาก็สามารถ rollback กลับไปยังอิมเมจก่อนหน้าได้
    • จากสรุปสิ้นปีของ Steam ปี 2023 เป็นปีแรกที่เล่นเกมบน Linux อย่างเดียว และยังรวมถึงเกมบางส่วนที่ออกปีนี้ด้วย
      ส่วนใหญ่เล่นบน Steam Deck หรือใน virtual machine ที่รัน Bazzite พร้อม GPU passthrough ซึ่งทำออกมาได้ดีมากจริง ๆ
    • แปลกใจที่ Bazzite ไม่เป็นที่รู้จักมากกว่านี้ มันคือสิ่งที่ผมฝันไว้พอดี แต่จนไม่นานมานี้ยังไม่รู้ด้วยซ้ำว่ามีอยู่
  • พูดถึงพีซีในห้องนั่งเล่น เดี๋ยวนี้ไม่ค่อยใช้คำว่า HTPC หรือ “มีเดียเซ็นเตอร์” กันแล้วเหรอ?