ใช้ x2x แทน KVM switcher

ผมมีเครื่องที่ใช้งานประจำอยู่สองเครื่องคือ Peorth และ Yggdrasil .. ปกติแล้วก็จะใช้มอนิเตอร์ คีย์บอร์ด เมาส์สองชุด โต๊ะเขาออกแบบให้วางคีย์บอร์ดและเมาส์เพียงชุดเดียว การจะวางสองชุดจึงไม่สะดวก ยิ่งผมต้องสลับการใช้งานบ่อยๆ ก็ยิ่งเป็นปัญหา สุดท้ายก็เลยกัดฟันซื้อ KVM Switcher ขนาดสี่พอร์ตมาตัวนึง ราคาประมาณสามพันกว่าบาท .. แต่เพราะผมมีจอแสดงผลอยู่แล้วสองจอ (จอ TFT ของ Peorth ซึ่งเป็นโน้ตบุ๊ก และมอนิเตอร์ของ Yggdrasil ที่เป็นเครื่องเดสก์ทอป) ผมเลยต่อเฉพาะคีย์บอร์ดและเมาส์เข้ากับ KVM switcher .. ไหนๆ ก็พูดถึง KVM แล้ว ขอบ่นหน่อยละกัน :P … เจ้า KVM Switcher ที่ผมซื้อมานี่มันมีฮอตคีย์สำหรับสลับการควบคุมไปยังแต่ละเครื่อง มันก็น่าจะสะดวกดีใช่มั้ยครับ ? แต่ฮอตคีย์ของมันคือ กด Ctrl+Alt+Shift พร้อมกันทีนึง จากนั้นกดเลขพอร์ต (1 2 3 หรือ 4) ทีนึง และกด Enter อีกทีนึง สรุปคือต้องกดตั้งห้าปุ่มในสามจังหวะ แบบนี้มันเป็น ‘ฮอต’ คีย์ตรงไหนฟะ เฮ่อ .. สมน้ำหน้าตัวเองไม่ถามให้ดีก่อน (.. แต่ตอนซื้อนั่นไม่คิดว่าจะมีฮอตคีย์ที่กดยากขนาดนี้นี่หว่า เคยใช้แต่กด Ctrl x 2 ก็เลยนึกว่าจะเหมือนกัน .. ซวยไปครับ)

แล้ววันนึง ระหว่างหาข้อมูลในกูเกิ้ลสายตาก็เหลือบไปเห็น Software-based KVM ซึ่งเป็นซอฟต์แวร์ที่ทำงานได้เหมือน KVM switcher คือสามารถใช้คีย์บอร์ด เมาส์ มอนิเตอร์ เพียงชุดเดียวในการควบคุมคอมพิวเตอร์หลายๆ เครื่อง โดยแต่ละเครื่องต้องรันซอฟต์แวร์ KVM และต้องเชื่อมกับเครือข่าย ผมเห็นว่าน่าสนใจก็เลยค้นเพิ่มเติมแล้วก็เจอ Software-based KVM switcher ที่เป็นโอเพ่นซอร์สด้วย ที่กล่าวถึงกันบ่อยๆ ก็มีสามตัวคือ Synergy x2vnc และ x2x … สองตัวแรกขั้นต้นผมลองแล้วแต่ไม่ประสบผลสำเร็จ ประกอบกับความต้องการของโปรแกรมดูจะมากเกินความจำเป็น ก็เลยข้ามมาลอง x2x ซึ่งกลายเป็นซอฟต์แวร์ที่ลงตัวที่สุดในเงื่อนไขที่ผมตั้งไว้ คือ สองเครื่อง สองจอ หนึ่งคีย์บอร์ด หนึ่งเมาส์ สลับการควบคุมง่าย โปรแกรมเล็ก และทำงานได้อย่างปลอดภัย (เรื่องมากจังแฮะ)

x2x

โปรแกรม x2x ยอมให้คีย์บอร์ดและเมาส์ที่เชื่อมกับคอมพิวเตอร์เครื่องหนึ่งไปควบคุมคอมพิวเตอร์อีกเครื่องนึงได้ นั่นคือ คีย์บอร์ดและเมาส์ชุดเดียว คุมเครื่องได้หลายเครื่อง (ผมเดาว่าได้เต็มที่สามเครื่อง เพราะอะไรเดี๋ยวมาดูกัน) .. จากชื่อคงพอเดาได้ว่ามาจาก X-to-X ซึ่งแปลว่ามันทำงานกับระบบเอ็กซ์วินโดว์โดยไม่จำกัดแพลตฟอร์ม (ถ้าติดตั้ง X บนวินโดว์ส ก็ใช้กับวินโดว์สได้) .. ขนาดโปรแกรม x2x ก็เพียงแค่ 20 กว่ากิโลไบต์เท่านั้นเอง และการสลับการควบคุมก็ทำได้โดยเลื่อนเมาส์ไปมาระหว่างสองจอภาพ สะดวกดีทีเดียว .. และเช่นเดียวกับ Software-based KVM ทั้งหลาย สิ่งที่ x2x ต้องการก็คือเครื่องที่จะใช้งานก็ต้องเชื่อมอยู่บนเครือข่าย

ภาพนี้เป็นคอนฟิกของผมที่ใช้อยู่ ประกอบด้วยคอมพิวเตอร์สองตัว Peorth กับ Yggdrasil .. มอนิเตอร์ของเครื่อง Yggdrasil อยู่ทางขวามือของโน้ตบุ๊ก Peorth ผมจะใช้คีย์บอร์ดและเมาส์ที่ต่อกับ Peorth ในการควบคุมทั้งสองเครื่อง

x2x ต้นฉบับให้มาเป็นซอร์ส สำหรับผู้ใช้ TLE 5.5 ผมทำ rpm ให้แล้ว apt-get ได้เลยครับ .. ดิสโตรอื่นจะคอมไพล์เองก็ได้ครับ ใช้แค่ทูลพื้นฐาน + Xlib เท่านั้นเอง

wget -c http://ftp.digital.com/pub/Digital/SRC/x2x/x2x-1.27.tar.gz
tar -xvzf x2x-1.27.tar.gz
cd x2x-1.27
xmkmf
make

ก็จะได้ x2x เป็นไบนารีมาหนึ่งตัว ก๊อบปี้ไปไว้ที่ ~/bin หรือ /usr/bin หรือ /usr/local/bin ก็ได้ เสร็จแล้วก็สั่งรันโดยระบุพารามิเตอร์ว่าจะเข้าไปควบคุม X display ตัวไหน อย่างกรณีของผม คือต้องการให้ Peorth สามารถควบคุม X display บน Yggdrasil ได้ ก็จะเรียกใช้ x2x บน Peorth ด้วยคำสั่ง:

x2x -to yggdrasil:0.0 -east

โดย

  • -to yggdrasil:0.0 เป็นการระบุ X display ที่ x2x จะเชื่อมเข้าไปควบคุม ในที่นี้คือ :0.0 ของ yggdrasil (yggdrasil เป็น hostname ของเครื่อง Yggdrasil ผมตั้งไว้ใน /etc/hosts .. ตรงนี้อาจจะใช้ FQDN หรือไอพีแอดเดรสไปเลยก็ได้)
  • -east เป็นการระบุว่า yggdrasil:0.0 นั้นอยู่ทิศตะวันออก หรือทางขวามือของ Peorth .. หากอยู่ซ้ายมือก็จะใช้ -west .. ตรงนี้เองที่ทำให้ผมเดาว่ามันคุมได้มากที่สุดสามเครื่อง คือเครื่องที่ต่อคีย์บอร์ดและเมาส์ เครื่องทางซ้ายมือ และเครื่องทางขวามือ

เมื่อสั่งงานแล้ว x2x ก็จะทำการเชื่อมไปยัง X display yggdrasil:0.0 ของ Yggdrasil และคอยตรวจจับการเคลื่อนไหวของเมาส์ที่เชื่อมกับ Peorth หากเคอร์เซอร์ของเมาส์เลื่อนมาจนเลยขอบขวาบนจอภาพของ Peorth เคอร์เซอร์ก็จะโผล่มาที่ขอบซ้ายบนจอภาพของ Yggdrasil ทั้งเมาส์และคีย์บอร์ดที่ต่อกับ Peorth ก็จะเข้ามาควบคุมเครื่อง Yggdrasil และในทำนองเดียวกัน หากเลื่อนเมาส์จนเลยขอบซ้ายของ Yggdrasil เคอร์เซอร์ก็จะกลับมาที่ Peorth การควบคุมก็จะโอนกลับมาที่ Peorth

ในช่วงแรก ผมต้องให้ X บน Yggdrasil เปิดพอร์ต 6000/TCP เพื่อรอรับการเชื่อมต่อจากเครื่องภายนอก และต้องสั่ง

xhost +peorth

เพื่ออนุญาตให้ Peorth เชื่อมต่อเข้ามาได้ (peorth = hostname ของ Peorth) .. แต่อย่างที่รู้กันว่า การเปิดพอร์ต 6000/TCP เป็นเรื่องที่ไม่ค่อยโสภาเท่าไหร่นัก เพราะมันเป็นการทำให้ระบบมีช่องโหว่ด้านความปลอดภัยรูบะเร่อ

ความปลอดภัย ?

x2x ไม่มีระบบความปลอดภัยใดๆ เลย การเชื่อมต่อของ x2x ใช้โพรโตคอลของ X เพียงอย่างเดียว ซึ่งค่อนข้างเปราะ โดยเฉพาะอย่างยิ่งเมื่อต้องเปิดให้ X ใช้งานผ่านเครือข่ายได้ นอกจากนี้การเชื่อมต่อ X display เปลือยๆ ก็ไม่ปลอดภัยเพราะไม่มีการปกป้องข้อมูลด้วยวิธีใดๆ เลย ถ้าเทียบ X เป็น remote login มันก็แย่พอๆ กับ telnet นั่นล่ะครับ .. โจทย์จึงกลายเป็นว่า ผมต้องหาทางใช้ x2x โดยไม่ผ่านพอร์ด 6000/TCP ของ X และต้องทำให้การเชื่อมต่อระหว่างสองเครื่องปลอดภัยมากพอด้วย ..

คำตอบของโจทย์นี้ไม่ยากเลย .. SSH tunnel นั่นเอง :D .. หลักการก็คือ แทนที่จะใช้ x2x เชื่อม X display เปลือยๆ ก็ใช้ SSH เชื่อมเข้าไปที่เครื่องปลายทางแล้วรัน x2x เชื่อมกับ :0.0 ที่ปลายทางเพื่อให้มันส่งข้อมูลผ่าน SSH tunnel กลับมาที่ต้นทาง .. ซึ่งหมายความว่าปลายทางจะต้องติดตั้ง x2x ไว้ ส่วนต้นทางที่เป็นตัวควบคุมไม่ต้องมีอะไรเลยนอกจาก SSH client :D ด้วยวิธีนี้ผมก็ไม่ต้องเปิดพอร์ต6000/TCP เพราะ x2x เชื่อมเข้า :0.0 ตรงๆ โดยไม่ผ่านชั้นของเครือข่าย จึงไม่ต้องสั่ง xhost ด้วย .. และการเชื่อมต่อทั้งหมดถูกห่อด้วย SSH ซึ่งมีการเข้ารหัสข้อมูลทุกชิ้นจึงไม่ต้องกังวลเรื่องข้อมูลรั่วบนเครือข่าย แถมการสั่งงานก็ไมได้ยากอะไรเลย แบบนี้ผมชอบแฮะ :D .. กลับมาดูคอนฟิกของผมอีกที

  • มอนิเตอร์เครื่อง Yggdrasil อยู่ขวามือของ Peorth
  • ใช้คีย์บอร์ดและเมาส์ของ Peorth
  • ติดตั้ง x2x บน Yggdrasil

การเชื่อมต่อที่เครื่อง Peorth ก็จะสั่งแบบนี้:

ssh -f yggdrasil x2x -to :0.0 -east

ssh ก็จะเชื่อมไปที่เครื่อง Yggdrasil แล้วรันคำสั่ง ‘x2x -to :0.0 -east’ ที่เครื่อง Yggdrasil ผลลัพธ์การทำงานจะถูกส่งกลับผ่าน tunnel ของ SSH ที่เราเชื่อมไปนั่นเอง ออปชัน -f เป็นการสั่งให้ SSH รันเป็น background ดังนั้นเมื่อ SSH เชื่อมต่อไป Yggdrasil ได้สำเร็จก็จะกลับมาที่เชลล์ทันที

เท่าที่ทดลองดูวิธีห่อ x2x ด้วย SSH นี่ได้ผลดีทีเดียว การตอบสนองก็รวดเร็วดี .. ผมลองวัดอย่างหยาบๆ พบว่า ถ้าขยับเมาส์ไม่หยุดจะมันจะส่งข้อมูลเข้าเครือข่ายในอัตราประมาณ 20 กิโลไบต์ต่อวินาที ถ้ากดคีย์บอร์ดค้างก็ใช้ราวๆ 8 กิโลไบต์ต่อวินาที ซึ่งผมคิดว่าไม่ใช่เรื่องใหญ่เพราะการใช้งานลักษณะนี้เครื่องคอมพิวเตอร์ทั้งสองเครื่องต้องอยู่ใกล้ๆ กัน (หรืออย่างน้อยจอมอนิเตอร์ก็ต้องอยู่ใกล้ๆ กัน) การเชื่อมต่อก็น่าจะอยู่บนเครือข่ายเดียวกัน อัตราการส่งข้อมูล 20-30 กิโลไบต์ต่อวินาทีจึงไม่ใช่ปัญหา .. ห้องแล็บที่ผมนั่งประจำมีเครือข่ายสามวง สอง ASes ผมลองย้าย Yggdrasil ไปอยู่เครือข่ายอื่นก็ใช้งานได้ไม่มีปัญหา

สรุปตอนนี้ผมก็ไม่จำเป็นต้องใช้ KVM Switcher แล้ว .. มีใครสนใจจะซื้อต่อมั้ยอ่ะ :P

ติดตั้งลินุกซ์เคอร์เนล 2.6

ผมเริ่มทดลองติดตั้งเคอร์เนล 2.6 บน peorth ตั้งแต่ 2.6.0-test10 แต่ไม่ประสบผลสำเร็จซักที ก็เลยไม่ได้เขียนวิธีการติดตั้งเป็นเรื่องเป็นราว ปัญหาใหญ่สุดของผมคือ usbmouse ไม่ทำงาน และ touchpad ก็มีอาการกระโดดๆ จนถึง 2.6.0 released อาการนี้ก็ยังไม่หาย จนไม่นานนี้เอา 2.6.0-1.30 ของ Fedora Core 2 (FC2) เป็น rpm มาติดตั้งรวดเดียวผ่านฉลุย ก็เลยได้กลับมาลองเคอร์เนล 2.6 อีกครั้ง

ฟีเจอร์ใหม่ๆ ของ 2.6 ที่ต่างไปจากวานิลลา 2.4.24 ก็มีเยอะเหมือนกัน และก็จะมีบางส่วนที่ removed/deprecated/obsoleted ด้วย ที่เห็นชัดจะมีเรื่องการสนับสนุนฮาร์ดแวร์ และระบบขนาดใหญ่ … รายละเอียดปลีกย่อยมันเยอะ (มากๆๆ) ครับ ลองหาอ่านเอาเองนะครับ อย่างไรก็ตามอยากแนะนำให้เริ่มเปลี่ยนเคอร์เนลเป็น 2.6 กันได้เลยครับ เพราะข่าวจาก Marcelo Tosatti ที่เป็น 2.4 kernel maintainer จะเป็นรีลีสสุดท้ายของเคอร์เนล 2.4 และจะเริ่มเข้าสู่ maintainance mode ซึ่งจะไม่มีการพัฒนาฟีเจอร์เพิ่มกันอีก จะเหลือแต่แก้ไขบักเล็กน้อยเท่านั้น นักพัฒนาเคอร์เนลก็จะมุ่งไปที่เคอร์เนล 2.6 (stable branch) และ 2.7 (development branch) แทน .. (2.4.24 จะเป็นรีลีสสุดท้ายหรือเปล่า ตอนนี้ไม่แน่ใจเหมือนกันครับ เพราะออกก่อนกำหนดตั้งเดือนครึ่ง ด้วยต้องการแก้บักด้านความปลอดภัยหลายๆ ตัว)

Configuration

หลังจากลอง kernel-2.6.0-1.30 ของ FC2 แล้วประสบผลสำเร็จดี ผมก็เลยเอา kernel-source-2.6.0-1.30 มาทำ custom kernel แต่ในวันเดียวกันนั้นเอง ลินุสก็ออก 2.6.1 ผมเลยเอามาติดตั้งด้วย แล้วไม่กี่ชั่วโมงต่อมาก็มีแพตช์ mm1 ของ แอนดรูว์ มอร์ตัน ออกมา ตามด้วย mm2 ในวันเดียวกันอีก สรุปว่าผมลงเคอร์เนล 2.6 ห้าตัวในวันเดียว เล่นเอาพื้นที่ในดิสก์เกือบจะไม่พอ

วิธีการคอนฟิกเคอร์เนลหากใช้ make menuconfig จะเห็นว่าอินเทอร์เฟซแทบไม่เปลี่ยนเลย แต่ถ้าใช้ make xconfig จะกลายเป็นอินเทอร์เฟซที่ใช้ QT แทนที่จะเป็น tcl/tk และที่เพิ่มมาอีกอันคือ make gconfig สำหรับอินเทอร์เฟซที่ใช้ GTK .. แรกๆ อาจจะไม่ค่อยคุ้นนัก แต่ลองได้คอนฟิกบ่อยๆ เดี๋ยวก็ชิน มาดูส่วนที่น่าสนใจกันสักนิด

  • General setup -> Loadable module
    • Automatic kernel module loading : เคอร์เนลจะสั่ง modprobe อัตโนมัติเมื่อต้องการใช้โมดูลบางตัว -> Y
  • Power Management support
    • ถ้าฮาร์ดแวร์สนับสนุน ACPI แนะนำให้ใช้ ACPI แทน APM ครับ
    • โน๊ตบุ๊คที่ใช้ CPU/Chipset ที่สนับสนุน CPU Frequency scaling (e.g., Speedstep-ICH, Pentium-M, PowerNow!, LongRun, …) แนะนำให้ enable CPU Frequency scaling ด้วยครับ
  • Device drivers -> ATA/ATAPI/MFM/RLL support
    • ถ้ามี IDE/ATAPI CD Writer .. เคอร์เนล 2.6 ไม่จำเป็นต้องใช้ SCSI emulation (BLK_DEV_IDESCSI) แล้วครับ
  • Device drivers -> Input Device
    • ต้องเลือก Y สำหรับออพชั่นหลักสี่ตัวคือ
      • หากต้องการใช้ PC Speaker ต้องเลือก PC Speaker support (INPUT_PCSPKR) ในเมนู Misc ด้วยครับ
  • File systems -> Pseudo filesystems
    • /proc file system support (PROC_FS) -> Y
    • sysfs support (SYSFS) -> Y จำเป็นมากๆ
  • Device drivers -> Character devices
    • Virtual terminal (VT) -> Y
    • Support for console on virtual terminal (CONSOLE_VT) -> Y
  • Device drivers -> Graphics support -> Console display driver support
    • ถ้าต้องการใช้ Framebuffer ต้องเลือก Y ออพชั่นต่อไปนี้ครับ
      • VGA Text console (VGA_CONSOLE)
      • Video mode selection support (VIDEO_SELECT)
      • Framebuffer Console support (FRAMEBUFFER_CONSOLE)
  • Sound
    • แนะนำให้ใช้ ALSA แทน OSS ครับ เท่าที่ทดสอบคือต้องคอมไพล์เป็นโมดูลเท่านั้นครับถึงจะใช้งานได้ ดังนั้นสำหรับ ALSA ให้เลือกเป็น M แทน Y นะครับ และควร config เพื่อให้ ALSA จำลองตัวเองเป็น OSS สำหรับแอพพลิเคชั่นที่ยังไม่สนับสนุน ALSA ครับ
      • OSS API emulation (SND_OSSEMUL)
      • OSS Mixer (SND_MIXER_OSS)
      • API OSS PCM API (SND_PCM_OSS)
      • OSS Sequencer API (SND_SEQUENCER_OSS)

Installation

2.6 ไม่ต้อง make dep แล้วครับ ขั้นตอนการ build จะเหลือเพียง

make
make modules_install
make install

และรายละเอียดช่วงคอมไพล์ก็จะถูกตัดทอนไปเยอะ เหลือเพียงสถานะบอกว่ากำลังทำอะไรกับโมดูลไหนเท่านั้น

Post Installation

หลังจากติดตั้งแล้ว ทีนี้ก็เป็นเรื่องคอนฟิกระบบสำหรับใช้กับเคอร์เนล 2.6 นะครับ มีจุดที่ต้องแก้อยู่นิดหน่อย

ใน 2.6 ‘จำเป็น’ ต้องใช้ sysfs ครับ ดังนั้น /etc/fstab ต้องเพิ่ม entry สำหรับ sysfs เข้าไป โดยเพิ่มบรรทัด

none                    /sys                    sysfs   defaults        0 0

และสร้างไดเรคทอรี่ /sys เตรียมไว้โดย

mkdir /sys

ใน /etc/rc.sysinit ส่วนของ HID คอมเมนต์บรรทัด keybdev กับ mousedev ออกครับ เพราะใน 2.6 ส่วนของ HID (Human Interface Device) ออกแบบใหม่ครับ และจะไม่มี keybdev กับ mousedev แล้ว ถ้าไม่คอมเมนต์ออกมันจะฟ้องตอนบูตว่า modprobe หาโมดูลไม่ได้ .. ที่จริงก็ไม่ได้สร้างปัญหาอะไรครับ แต่มันน่ารำคาญเท่านั้นล่ะ :P

คอนฟิกโมดูลใน 2.4 จะใช้ /etc/modules.conf แต่ใน 2.6 จะเป็น /etc/modprobe.conf ครับ ดังนั้นต้องย้ายคอนฟิกใน /etc/modules.conf ไปไว้ที่ /etc/modprobe.conf ด้วย ผมใช้วิธีถึกๆ แบบนี้

cat /etc/modules.conf > /etc/modprobe.conf

แล้วค่อยไปแก้ไขเอาทีหลัง

สำหรับ ALSA ต้องเพิ่มข้างล่างนี้ใน /etc/modprobe.conf ด้วย คอนฟิก ALSA ของ 2.4 กับ 2.6 จะต่างกันเล็กน้อยครับ ลองตรวจเช็คดูครับ ตัวอย่างข้างล่างเป็นคอนฟิกสำหรับ Intel AC’97 นะครับ โมดูลที่ใช้ชื่อ snd-intel8x0 สำหรับเครื่องที่ใช้ซาวด์การ์ดต่างไปจากนี้ก็แก้ที่สองบรรทัดแรกให้ตรงกับโมดูลที่ต้องการใช้ครับ

alias snd-card-0 snd-intel8x0
alias sound-slot-0 snd-intel8x0
alias char-major-116 snd
alias char-major-14 soundcore
alias sound-service-0-0 snd-mixer-oss
alias sound-service-0-1 snd-seq-oss
alias sound-service-0-3 snd-pcm-oss
alias sound-service-0-8 snd-seq-oss
alias sound-service-0-12 snd-pcm-oss
install sound-slot-0
  /sbin/modprobe --ignore-install sound-slot-0 &&
  { /bin/aumix-minimal -f /etc/.aumixrc -L >/dev/null 2>&1; /bin/true;  }
remove sound-slot-0
  { /bin/aumix-minimal -f /etc/.aumixrc -S >/dev/null 2>&1; /bin/true; };
  /sbin/modprobe -r --ignore-remove sound-slot-0

NVIDIA Driver ลำบากสักหน่อยครับเพราะติดตั้งกับ 2.6 ตรงๆ ไม่ได้ ต้องแพตช์กันเล็กน้อยก่อนครับ โดยดาวน์โหลดแพตช์สำหรับ NVIDIA Driver ได้ที่ http://www.minion.de ครับ เลือกแพตช์ที่ตรงกับเวอร์ชั่นของไดรเวอร์นะครับ ตัวอย่างของผมคือใช้ไดรเวอร์ NVIDIA-Linux-x86-1.0-5328-pkg1.run ก็จะต้องใช้แพตช์ NVIDIA_kernel-1.0-5328-2.6.diff ขั้นตอนการติดตั้งต้องทำตามนี้ครับ

# sh NVIDIA-Linux-x86-1.0-5328-pkg1.run --extract-only

เพื่อแตกซอร์สที่อยู่ในแพคเกจออก ซอร์สจะแตกไว้ที่ ./NVIDIA-Linux-x86-1.0-5328-pkg1 จากนั้นก็ต้องแพตช์

cd NVIDIA-Linux-x86-1.0-5328-pkg1/usr/src/nv
cat ../../../../NVIDIA_kernel-1.0-5328-2.6.diff | patch -p1
ln -s Makefile.kbuild Makefile
cd ../../../

เสร็จแล้วก็คอมไพล์และติดตั้ง

make SYSSRC=/usr/src/linux-2.6.1-mm2/ install

อย่างที่บอกว่า IDE/ATAPI CD Writer ไม่ต้องจำลอง SCSI กันแล้ว ทำให้ลดภาระงานของเคอร์เนลที่ต้องจำลอง SCSI ลงไปเยอะครับ เท่าที่ทดสอบเขียน CD ที่ 24X ไดรว์ Lite-On 40x12x48 บนเครื่อง Athlon XP 2000+ ใช้ SCSI emulation กินซีพียูไปเกือบๆ 100% ในขณะที่ไม่ใช่ SCSI emulation เหลือราวๆ 5% เท่านั้น เบากว่ากันเยอะเลย แถม disk throughput ก็สูงกว่าด้วย :D

ทีนี้มาดูเรื่องการสั่งงานนิดนึง เพราะเราไม่ได้จำลอง SCSI แล้ว คำสั่งในการเขียนแผ่นด้วย cdrecord กับ ATAPI CD Writer ก็เลยเปลี่ยนไปเล็กน้อยครับ คือไม่ได้ระบุเป็น dev=bus,target,lun แล้ว แต่จะระบุดีไวซ์ตรงๆ เป็น dev=/dev/hdd เลย อย่างจะ simulate การเขียน ISO อิมเมจลงแผ่นก็ประมาณ:

[kitt@yggdrasil kitt]$ cdrecord -v dev=/dev/hdd speed=40 -dao -dummy driverop
ts=burnfree -overburn -data 4.9-i386-mini.iso
Cdrecord-Clone 2.01a19 (i686-redhat-linux-gnu) Copyright (C) 1995-2003 Jฟrg Schi
lling
TOC Type: 1 = CD-ROM
scsidev: '/dev/hdd'
devname: '/dev/hdd'
scsibus: -2 target: -2 lun: -2
Warning: Open by 'devname' is unintentional and not supported.
Linux sg driver version: 3.5.27
Using libscg version 'schily-0.7'
cdrecord: Warning: using inofficial libscg transport code version (schily - Red
Hat-scsi-linux-sg.c-1.75-RH '@(#)scsi-linux-sg.c       1.75 02/10/21 Copyright 1
997 J. Schilling').
Driveropts: 'burnfree'
SCSI buffer size: 64512
atapi: 1
Device type    : Removable CD-ROM
Version        : 0
Response Format: 2
Capabilities   :
Vendor_info    : 'LITE-ON '
Identifikation : 'LTR-40125S      '
Revision       : 'ZS0N'
Device seems to be: Generic mmc CD-RW.
Current: 0x0002
Profile: 0x000A
Profile: 0x0009
Profile: 0x0008
Profile: 0x0002 (current)
Using generic SCSI-3/mmc   CD-R/CD-RW driver (mmc_cdr).
Driver flags   : MMC-3 SWABAUDIO BURNFREE FORCESPEED
Supported modes: TAO PACKET SAO SAO/R96P SAO/R96R RAW/R16 RAW/R96P RAW/R96R
FIFO size      : 4194304 = 4096 KB
Track 01: data   206 MB
Total size:      237 MB (23:30.98) = 105824 sectors
Lout start:      237 MB (23:32/74) = 105824 sectors
Current Secsize: 2048
ATIP info from disk:
  Indicated writing power: 7
  Is not unrestricted
  Is not erasable
  ATIP start of lead in:  -11597 (97:27/28)
  ATIP start of lead out: 359849 (79:59/74)
Disk type:    Short strategy type (Phthalocyanine or similar)
Manuf. index: 20
Manufacturer: Princo Corporation
Blocks total: 359849 Blocks current: 359849 Blocks remaining: 254025
cdrecord: Operation not permitted. WARNING: Cannot set RR-scheduler
cdrecord: Permission denied. WARNING: Cannot set priority using setpriority().
cdrecord: WARNING: This causes a high risk for buffer underruns.
Forcespeed is OFF.
Starting to write CD/DVD at speed 40 in dummy SAO mode for single session.
Last chance to quit, starting dummy write    0 seconds. Operation starts.
Waiting for reader process to fill input buffer ... input buffer ready.
BURN-Free is ON.
Sending CUE sheet...
Writing pregap for track 1 at -150
Starting new track at sector: 0
Track 01:  206 of  206 MB written (fifo 100%) [buf  99%]  27.5x.
Track 01: Total bytes read/written: 216727552/216727552 (105824 sectors).
Writing  time:   77.203s
Average write speed  18.3x.
Min drive buffer fill was 98%
Fixating...
WARNING: Some drives don't like fixation in dummy mode.
Fixating time:    3.531s
BURN-Free was never needed.
cdrecord: fifo had 3414 puts and 3414 gets.
cdrecord: fifo was 0 times empty and 2436 times full, min fill was 85%.
[kitt@yggdrasil kitt]$

ข่าวดีคือ K3B ก็สนับสนุนการสั่งงานแบบนี้แล้ว ถ้าใช้ K3B เป็น frontend ให้ cdrecord อยู่แล้วก็ใช้งานได้ทันทีครับ K3B จะใส่พารามิเตอร์ที่เหมาะสมให้เอง

ส่วน cdrdao ไม่มีการอัพเดตมาเป็นปีแล้ว ดังนั้นตัวต้นฉบับแท้ๆ ยังจำเป็นต้องใช้ SCSI emulation ครับ … แต่ .. ข่าวดีอีกแล้ว .. cdrdao ใช้ไดรเวอร์ของ cdrecord ครับ ก็เลยมีคนแฮ็คเอาไดรเวอร์ตัวใหม่ของ cdrecord ไปใส่ใน cdrdao ผลก็คือได้ cdrdao รุ่นพิเศษที่สนับสนุน ATAPI CD Writer ในทำนองเดียวกับ cdrecord .. อันนี้ผมแฮ็คและทำเป็น rpm ไว้แล้ว (เพราะยังไงผมก็ใช้เองอยู่ดีล่ะ) พารามิเตอร์ในการระบุดีไวซ์สำหรับ cdrdao (hacked) ก็จะประมาณ --device=/dev/hdc ครับ ส่วน --driver ก็ใช้เป็นตัวเดิม เช่นสั่ง cdrdao ให้ simulate การเขียน toc/cue อิมเมจก็จะได้ดังนี้ครับ

[kitt@yggdrasil kitt]$ cdrdao simulate --device /dev/hdd --driver generic-mmc test.toc
Cdrdao version 1.1.7-tle - (C) Andreas Mueller
  SCSI interface library - (C) Joerg Schilling
  Paranoia DAE library - (C) Monty

Check http://cdrdao.sourceforge.net/drives.html#dt for current driver tables.

Warning: This version of libscg has not been configured via the standard
autoconfiguration method of the Schily makefile system. There is a high risk
that the code is not configured correctly and for this reason will not behave
as expected.
Using libscg version 'schily-0.8'

/dev/hdd: LITE-ON LTR-40125S    Rev: ZS0N
Using driver: Generic SCSI-3/MMC - Version 2.0 (options 0x0000)

Starting write simulation at speed 40...
Pausing 10 seconds - hit CTRL-C to abort.
Process can be aborted with QUIT signal (usually CTRL-).
WARNING: No super user permission to setup real time scheduling.
Turning BURN-Proof on
Writing track 01 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 02 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 03 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 04 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 05 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 06 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 07 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 08 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 09 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 10 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 11 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 12 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Writing track 13 (mode MODE2_FORM_MIX/MODE2_FORM_MIX )...
Wrote 650 of 650 MB (Buffer 100%).
Wrote 289952 blocks. Buffer fill min 81%/max 100%.
Flushing cache...
Simulation finished successfully.
[kitt@yggdrasil kitt]$

.. นอกจากนี้ผมแฮ็ค K3B ให้สนับสนุนการสั่งงาน cdrdao ให้ใช้กับ ATAPI CD Writer ด้วย .. สรุปว่า ใครที่ใช้เคอร์เนล 2.6 และ ATAPI CD Writer สามารถถอด SCSI emulation ออกแล้วใช้ cdrecord + cdrdao (hacked) + K3B (hacked) ได้เลยครับ ดาวน์โหลด cdrdao (hacked) กับ k3b (hacked) ได้ที่ ftp://ftp.kitty.in.th/pub/TLE/5.5/kitty-tle/RPMS ครับ :)

สำหรับคนที่ไม่ได้ใช้ rpm วิธีแฮ็ค cdrdao ที่ใช้คือ เปลี่ยนไดรเวอร์ scg ของ cdrdao-1.1.7 เป็นของ cdrecord 2.01a2? ครับ วิธีการคือ

  1. untar ซอร์สของ cdrdao-1.1.7 กับ cdrecord-2.01a2?
  2. ลบไดเรคทอรี่ scsilib/libscg ใน cdrdao-1.1.7/ ออก
  3. ก๊อปปี้ไดเรคทอรี่ libscg ของ cdrecord-2.01 มาใส่ใน scsilib/ ของ cdrdao-1.1.7
  4. build ด้วยขั้นตอนปกติครับ

สรุป

เท่าที่ใช้งานเคอร์เนล 2.6 เสถียรดีครับ ผลการทดสอบจากหลายๆ แห่งก็แสดงให้เห็นว่า 2.6 ทำงานได้เร็วกว่า 2.4 เมื่อระบบต้องรับภาระงานหนักๆ เช่น พวกเซิร์ฟเวอร์ที่ต้องรันแอพพลิเคชั่นหลายๆ ตัวพร้อมๆ กัน ตรงนี้เข้าใจว่าเป็นเพราะ scheduler ของ 2.6 มี scalability ดีกว่า 2.4 .. ในแง่การใช้งานเป็นเดสก์ท็อป 2.6 มีฟีเจอร์ preemptible kernel ที่ช่วยให้ระบบตอบสนองต่อการทำงานแบบ interactive หรือ real-time ได้ดีขึ้น มี NPTL ที่ทำให้การทำงานกับเธรดเร็วขึ้น อย่างไรก็ตามเท่าที่ผมและหลายๆ คนเจอคือถ้ารันแอพพลิเคชั่นตัวเดียวเดี่ยวๆ อาจจะพบว่าการทำงานบน 2.6 ช้ากว่า 2.4 ดังนั้นจะสรุปว่า 2.6 ทำงานเร็วกว่า 2.4 ทุกด้านคงไม่ได้ แต่โดยภาพรวมแล้วการทำงาน 2.6 จะตอบสนองได้ดีกว่า การทำงานราบรื่นกว่า 2.4 ครับ

หลายคนอาจจะมีคำถามในใจว่าจะอัพเกรดเป็น 2.6 ดีหรือไม่ ผมว่าอัพเกรดน่ะต้องทำแน่ๆ อยู่แล้ว แต่ว่าเมื่อไหร่แค่นั้นเอง ณ เวลานี้ 2.4 ยังถือว่าใช้งานได้ดี แต่หลังจาก 2.4.24 ที่เพิ่งรีลีสไปไม่นานนี้ และอาจจะไม่มี 2.4 รีลีสอีกแล้ว ผู้ใช้ส่วนใหญ่จึงถูกกระตุ้นให้ย้ายไปใช้ 2.6 โดยปริยาย เน้นว่า ‘กระตุ้น’ นะครับ ไม่ใช่ ‘บังคับ’ เพราะการสนับสนุนเคอร์เนล 2.4 จะยังอยู่อีกนาน (เช่นเดียวกับ 2.2 ซึ่งหยุดพัฒนาไปนานแล้ว แต่ยังมีการสนับสนุนอยู่จนถึงทุกวันนี้)

โดยส่วนตัว ผมย้ายมาใช้ 2.6 อย่างเต็มตัวแล้ว (แต่ยังแอบมี 2.4 มีไว้สำรองไว้เผื่อใช้เปรียบเทียบ) .. เวลานี้บรรดาดิสโตรฯ เริ่มทดสอบ และทำแพคเกจเคอร์เนลใหม่กันมาพักนึงแล้ว อย่าง FC2 ก็ทำ 2.6 ไว้แล้ว SuSE Mandrake ก็ทำไว้แล้วเหมือนกัน ผมว่ารีลีสหน้าของดิสโตรเหล่านี้คงเปลี่ยนมาใช้เคอร์เนล 2.6 กันแน่ๆ … คำถามก็อาจจะกลายเป็นว่า เราจะเริ่มเองวันนี้ ? หรือจะรอใช้ 2.6 ที่มากับดิสโตรในอีกไม่กี่เดือนข้างหน้า ? … ตัดสินใจเอาเองครับ :)

อัพเดตครับ ตะกี้เห็นแวบๆ ที่ http://kernel.org มี 2.4.25-pre6 แล้ว (พร้อมกับ 2.6.1-mm4) .. ถ้า Marcelo ยังยืนยันกำหนดการเดิม 2.4.25 น่าจะรีลีสราวๆ กลางเดือนกุมภาพันธ์ครับ (Updated on Fri Jan 16 2004 22:22)

Fedora Core 1 on Acer TravelMate 361EVi

Recently, I have upgraded Linux on my Acer TravelMate 361Evi to Fedora Core 1. The main reason to upgrade is that FC1 is the basis to develop packages for LinuxTLE 5.5, the next major release of Thai Linux distro that I have contributed my works to.

Kernel

FC1 comes with kernel 2.4.22-1.2115.nptl, which is – like RH’ve done before – a collection of many patches ahead of 2.4.22 backported to 2.4.22. So, their kernel is very unique and sometimes we are not comfortable with that when we recompile our custom kernel :(

First thing you should know that FC1 provides 3 versions of gcc: 3.3.2, 3,2,3 and 2.96. For kernel and kernel modules, you should use gcc 3.2.3. There are reasons for this (try google, or RHN if you want to know about). So. every time you compile kernel or kernel modules, be sure that you export CC=gcc32.

The first kernel issue of FC1 is that the yenta_socket problem is back! I don’t know the reason why it happens again, but this can easily be fixed like before, just disable PCMCIA/Cardbus support in kernel and use the pcmcia-cs package instead. — done! (One thing I’ve noticed is that those yenta_socket problem always comes when I use RH kernel, but not if I use vanilla).

Okay, yenta_socket could be workaround. The next thing is that FC1 will not start ACPI by default, So I have to put “ACPI=on” as a boot parameter. Well, 361EVi does need ACPI. Otherwise, it would not shutdown when asking OS to do so (and I need to push the power button). So, put ACPI=on in /etc/grub.conf. Oh, by the way, if you use lilo, I’d suggest you to upgrade to grub, lilo will be deprecated soon.

So far, that’s all the MUST do things in kernel. The rest are optional but I’d recommend you to look around.

Display

There are things you should do in your kernel to make display works properly. First, VESA Framebuffer won’t work anymore, but they introduced the new Intel Framebuffer (CONFIG_FB_INTEL), which should work better. So I used intelfb, and ignore the vesafb. I can still put VGA=xxx as a boot parameter, though.

For better graphic performance, AGPGART should be enabled (either CONFIG_AGP_INTEL or CONFIG_AGP_I810). DRM should be set to i830 (CONFIG_DRM_I830). I got nearly 600 fps of glxgears with 16-bit depth.

For XFree86, the device section should be something like this:

Section "Device"
        Identifier  "Videocard0"
        Driver      "i810"
        VendorName  "Videocard vendor"
        BoardName   "Intel 830"
EndSection

Sound

You can use sound support from the kernel (CONFIG_SOUND_ICH) if you want to. if you want to use ALSA as I do, here is the way. First, kernel should enable sound support (CONFIG_SOUND) but *DO NOT* select any drivers. Then, grab alsa-driver source, extract, and

./configure --with-cards=intel8x0,virmidi
make
make install

You may also want to change /etc/modules.conf to be:

alias snd-card-0 snd-intel8x0
alias snd-card-1 snd-virmidi
alias sound-slot-0 snd-card-0
alias sound-slot-1 snd-card-1
alias char-major-116 snd
alias char-major-14 soundcore
options snd major=116 cards_limit=2
options snd-intel8x0 index=0
options snd-virmidi index=1
alias sound-service-0-0 snd-mixer-oss
alias sound-service-0-1 snd-seq-oss
alias sound-service-0-3 snd-pcm-oss
alias sound-service-0-8 snd-seq-oss
alias sound-service-0-12 snd-pcm-oss
alias sound-service-1-1 snd-seq-oss
alias sound-service-1-8 snd-seq-oss

PCMCIA

Okay, for FC1, pcmcia-cs driver is needed as I described above.

My /etc/sysconfig/pcmcia is:

PCMCIA=yes
PCIC=i82365
PCIC_OPTS="do_scan=0"
CORE_OPTS=
CARDMGR_OPTS=

If you use vanilla kernel instead, you can just ignore pcmcia-cs package, then use kernel PCMCIA driver, and /etc/sysconfig/pcmcia should be changed to:

PCMCIA=yes
PCIC=yenta_socket
PCIC_OPTS=
CORE_OPTS=

As usual, enabling PCMCIA makes the Orinoco Wireless LAN works immediately because it is hard-wired on 361EVi board.

10/100 Ethernet

This should work by default, but if it does not, or you want to

customize your kernel, be sure to choose either CONFIG_E100 or CONFIG_EEPRO100 (I use EEPRO100 compile in kernel). If you choose to compile as a module, put this into your /etc/modules.conf

alias eth0 eepro100

or

alias eth0 e100

Ports/Combo Drive

All should work.

Power Management

Well, I’d suggest you to use ACPI instead of APM. ACPI seems to be better than APM for 361EVi. FC1’s kernel also supports CPU Frequency Scaling (a.k.a SpeedStep, PowerNow!, those kind of things to switch CPU frequency on-the-fly). I enabled CPU Frequency Scaling to save battery when power is offline. These are things I set in your kernel:

#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_PROC_INTF=y

#
# CPUFreq governors
#
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_24_API=y

#
# CPUFreq processor drivers
#
CONFIG_X86_SPEEDSTEP_ICH=y

Rebuild the kernel, and after reboot the new kernel, I got these in /proc/cpufreq:

         minimum CPU frequency  -  maximum CPU frequency  -  policy
CPU  0       731500 kHz ( 73 %)  -     997500 kHz (100 %)  -  performance

I can set frequency and power policy to save mode by:

echo -n "0:731500:997500:powersave" > /proc/cpufreq

And bring them back to full-speed by:

echo -n "0:731500:997500:performance" > /proc/cpufreq

Use cpufreqd if you want it changes frequency and/or policy automatically.

Fedora Core 1 and NPTL

Fedora Core introduces a new thread library called NPTL (Native POSIX Thread Library). Linux will use this sooner or later. NPTL increases speed of your programs by implementing thread operations natively. This would increase speed of operations like start/stop threads, etc. People have tested the performance of NPTL and it can be 4xx faster than non-NPTL. But, a bad news is that it is not backward compatible to Linux thread, so your programs may crash (segfault, etc..)… Fedora people know this and already put a workaround. By setting LD_ASSUME_KERNEL environment, you can force to disable NPTL support. So, try:

$ LD_ASSUME_KERNEL=2.4.19 /path/to/your/program

if your program fails to operate on FC1.

Well, that should be all for now. Have fun !

ปรับความถี่ซีพียูบนลินุกซ์ด้วย CPU Frequency Scaling

ลินุกซ์สนับสนุนการปรับความถี่การทำงานของซีพียูโดยใช้ CPU Frequency scaling support ซึ่งเหมาะกับคอมพิวเตอร์ใช้ซีพียูที่สนับสนุนการปรับความถี่ เช่น ซีพียูที่สนับสนุน Intel SpeedStep (P-III Tuaalatin), Intel Enhanced SpeedStep (Centrino), AMD PowerNow!, Transmeta LongRun (Crusoe) เป็นต้น การปรับความถี่จะทำได้ทันที โดยไม่ต้อง reboot เครื่อง จึงเหมาะกับคอมพิวเตอร์โน๊ตบุ๊คที่ต้องการประหยัดพลังงานเมื่อใช้แบตเตอรี่

คอนฟิกฯ ส่วนของเคอร์เนล

การใช้ CPU Frequency scaling ต้อง patch kernel source เพื่อให้เคอร์เนลสนับสนุนเสียก่อน แนะนำให้ใช้ stable kernel ตัวล่าสุด + ac patch ตัวล่าสุดสำหรับเคอร์เนลดังกล่าว

ส่วนที่ต้องคอนฟิกฯ ในเคอร์เนลมีดังนี้:

#
# CPU Frequency scaling
#
CONFIG_CPU_FREQ=y
CONFIG_CPU_FREQ_TABLE=y
CONFIG_CPU_FREQ_PROC_INTF=y

#
# CPUFreq governors
#
CONFIG_CPU_FREQ_GOV_USERSPACE=y
CONFIG_CPU_FREQ_24_API=y

และเลือก Driver ตัวที่ตรงกับซีพียู/ฮาร์ดแวร์ที่ใช้งานอยู่:

#
# CPUFreq processor drivers
#
CONFIG_X86_POWERNOW_K6=y สำหรับ mobile AMD K6-2+,  K6-3+
CONFIG_X86_POWERNOW_K7=y สำหรับ mobile AMD Athlon/Duron K7
CONFIG_ELAN_CPUFREQ=y สำหรับ AMD Elan SC400 / SC410
CONFIG_X86_LONGHAUL=y สำหรับ VIA Samuel/CyrixIII, Samuel/C3, Cyrix Ezra, Cyrix Ezra-T
CONFIG_X86_SPEEDSTEP_ICH=y สำหรับ mobile P-III (Coppermine), P-III-M (Tulaatin), P4-Ms
CONFIG_X86_SPEEDSTEP_CENTRINO สำหรับ Pentium M (Centrino)
CONFIG_X86_LONGRUN=y สำหรับ Transmeta Crusoe ที่สนับสนุน LongRun
CONFIG_X86_GX_SUSPMOD=y สำหรับ NatSemi Geode ที่สนับสนุน suspend modulation

จากนั้นคอมไพล์และติดตั้งเคอร์เนลใหม่ หลังจาก reboot แล้ว ข้อมูลของ frequency scaling จะปรากฏใน /proc/cpufreq

# cat /proc/cpufreq
          minimum CPU frequency  -  maximum CPU frequency  -  policy
CPU  0       731500 kHz ( 73 %)  -     997500 kHz (100 %)  -  performance

การปรับความถี่

หลังจากเคอร์เนลสนับสนุน CPU frequency scaling แล้ว การปรับความถี่สามารถทำได้โดยส่ง string redirect ไปที่ /proc/cpufreq โดยใช้ฟอร์แมตดังนี้

<CPUID>:<min freq>:<max freq>:<policy>

CPUID เป็นหมายเลขอ้างอิงซีพียู สำหรับเครื่องส่วนใหญ่ที่เป็น uniprocessor จะเป็น 0 เพราะมีซีพียูเพียงตัวเดียว (0 คือ ID ของซีพียูตัวแรกของระบบ) ความถี่กำหนดในหน่วย kHz .. policy กำหนดได้สองอย่างคือ เป็น performace เพื่อเลือกการทำงานเต็มประสิทธิภาพ หรือ powersave เพื่อเลือกการทำงานในโหมดประหยัดพลังงาน ตัวอย่างเช่น

echo -n "0:731500:997500:powersave" > /proc/cpufreq

เป็นการกำหนดให้ซีพียูตัวแรก ทำงานที่ความถี่ช่วง 731500 kHz (~ 733 MHz) ถึง 999750 (~ 1 GHz) ในโหมดประหยัดพลังงาน

ถ้าต้องการกำหนดความถี่เป็นเปอร์เซ็น สามารถทำได้โดยใช้ฟอร์แมตนี้:

<CPUID>:<min freq>%<max freq>%<policy>

เราสามารถดูความถี่ปัจจุบันของซีพียูได้จาก /proc/cpuinfo

# cat /proc/cpuinfo
processor       : 0
vendor_id       : GenuineIntel
cpu family      : 6
model           : 11
model name      : Intel(R) Pentium(R) III Mobile CPU      1000MHz
stepping        : 1
cpu MHz         : 733.272
cache size      : 512 KB
fdiv_bug        : no
hlt_bug         : no
f00f_bug        : no
coma_bug        : no
fpu             : yes
fpu_exception   : yes
cpuid level     : 2
wp              : yes
flags           : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 mmx fxsr sse
bogomips        : 1464.72

ปรับความถี่อัตโนมัติโดยใช้ cpufreqd

CPU Frequency scaling ในเคอร์เนลไม่ได้ควบคุม/ปรับความถี่หรือ power policy อัตโนมัติ การเพิ่ม CPU Frequency scaling support ในเคอร์เนลเป็นการ enable ให้เราปรับความถี่ได้เท่านั้น แต่จะปรับความถี่ เมื่อไหร่ อย่างไร ขึ้นอยู่กับผู้ใช้ ซึ่งอาจจะปรับความถี่เองด้วยวิธีการข้างต้น หรือ ใช้ CPU Frequency daemon เช่น cpufreqd, cpudyn เพื่อปรับความถี่ซีพียูตามเงื่อนไขโดยอัตโนมัติ

cpufreqd เป็น daemon ที่ตรวจเช็คสถานะต่่างๆ ของระบบ เช่น AC status, battery level, CPU workload, running application และปรับความถี่ power policy ให้อัตโนมัติตามเงื่อนไขที่กำหนดไว้ใน configuration file (/etc/cpufreqd.conf) การทำงานของ cpufreqd จึงจำเป็นต้องอาศัย Power Management support ในเคอร์เนล (เช่น APM, ACPI) เพื่อรายงานสถานะของระบบด้วย

ซอร์ส ของ cpufreqd สามารถดาวน์โหลดได้จาก http://cpufreqd.sourceforge.net extract, configure, make, make install เพื่อติดตั้ง

RPM สำหรับ LinuxTLE 5.5/Fedora Core 1 จะ release ในแผ่นติดตั้งของ LinuxTLE 5.5 หรือสามารถดาวน์โหลดได้จาก ftp://ftp.kitty.in.th/pub/TLE/5.5/kitty-tle

Sync ปาล์ม / คลีเอ้ผ่านพอร์ตอินฟราเรด (IrDA) บนลินุกซ์

ขั้นตอน config

เริ่มแรกก็ตรวจสอบก่อนว่าเคอร์เนลมองเห็นพอร์ตอินฟราเรดแล้วหรือยัง โดยดูได้จากรายชื่อของพอร์ตสื่อสารที่ปรากฏใน dmesg:

[kitt@peorth kitt]$ dmesg | grep ttyS
ttyS00 at 0x03f8 (irq = 4) is a 16550A
ttyS01 at 0x02f8 (irq = 3) is a 16550A

หนึ่งในนั้นควรจะเป็นพอร์ตอินฟราเรด เช่น เครื่องที่ผมใช้ ttyS01 (หรือ COM2) คือพอร์ตที่เป็นอินฟราเรด เวลาใช้งานพอร์ตนี้ก็จะติดต่อผ่านดีไวซ์ /dev/ttyS1 เมื่อรู้ว่าใช้ดีไวซ์ตัวไหนแล้วก็ไปตั้งใน/etc/sysconfig/irda อย่างนี้

[kitt@peorth kitt]$ cat /etc/sysconfig/irda
IRDA=yes
DEVICE=/dev/ttyS1
DISCOVERY=yes

มาถึงตรงนี้ก็เป็นอันเสร็จขั้นตอนการ config พอร์ตอินฟราเรดสำหรับลินุกซ์ หากรีบูตระบบหรือสั่ง service irda start ลินุกซ์ก็พร้อมที่จะติดต่อกับพอร์ตอินฟราเรดแล้ว :)

แต่ต้องทำความเข้าใจอีกนิดว่าพอร์ตอินฟราเรดนั้นสามารถทำงานได้หลายรูปแบบขึ้นกับว่าใช้โปรโตคอลในการสื่อสารแบบไหน .. กรณีปาล์ม/คลีเอ้จะเชื่อมต่อด้วยโปรโตคอลแบบเดียวกับพอร์ตสื่อสาร (ircomm-tty) ซึ่งจะทำงานผ่านดีไวซ์ /dev/ircomm0 ครับ .. หาก sync ปาล์ม/คลิเอ้ผ่านอินฟราเรดเป็นประจำก็ควรทำ symlink จาก /dev/pilot ไปที่ /dev/ircomm0 ไว้เลยครับ เพราะโปรแกรมส่วนใหญ่จะใช้ /dev/pilot เป็นดีไวซ์ในการสื่อสารโดยปริยาย

(as root)
[kitt@peorth kitt]# ln -sf /dev/ircomm0 /dev/pilot

ทีนี้เราก็พร้อมจะเริ่ม sync กันแล้ว :D

วิธี synchronize ข้อมูล

โปรแกรมพื้นฐานที่สุดในการนี้ก็คือ pilot-xfer (หากไม่มี ให้ติดตั้งแพคเกจ pilot-link) การ backup/sync/restore/install ใช้คำสั่งนี้เพียงคำสั่งเดียวเลย

  • pilot-xfer -b สำหรับ backup (ทุก file)
  • pilot-xfer -s สำหรับ sync (backup เฉพาะ update ที่มีการ update)
  • pilot-xfer -r สำหรับ restore
  • pilot-xfer -i foo.prc สำหรับติดตั้ง foo.prc ลงในเครื่องปาล์ม/คลีเอ้

หากสั่งงานเหมือนข้างบนนี้ pilot-xfer จะใช้ดีไวซ์ /dev/pilot ในการเชื่อมกับปาล์ม/คลีเอ้ และเก็บข้อมูลลง $HOME/.pilot ซึ่งเป็น default directory ที่ใช้เก็บข้อมูล .. รายละเอียดอื่นๆ (อีกเยอะ) ดูได้ด้่วยการสั่ง man pilot-xfer ครับ มันมีโปรแกรมสำหรับ อ่าน/เขียน todo, memo, datebook, etc. ด้วย

อื่นๆ

Diagram การเชื่อมต่อจะประมาณนี้ครับ:

pilot-link -> /dev/pilot -> /dev/ircomm0 -> [ircomm-tty -> ircomm -> irda] ->
/dev/irda0 -> Hardware IrDA device -> palm

ข้างใน [ … ] คือส่วนของเคอร์เนลครับ ถ้า compile irda เป็น kernel module แล้ว lsmod ดูจะเห็นว่ามี

ircomm-tty             38528   0  (autoclean)
ircomm                 18252   0  [ircomm-tty]
irtty                  10048   2  (autoclean)
irda                  191872   0  (autoclean) [ircomm-tty ircomm irtty]

กรณีที่ compile kernel เองและต้องการใช้พอร์ดอินฟราเรดตรวจดูตามนี้ครับ

CONFIG_IRDA=m
CONFIG_IRLAN=m
CONFIG_IRNET=m
CONFIG_IRCOMM=m
CONFIG_IRDA_ULTRA=y
CONFIG_IRDA_CACHE_LAST_LSAP=y
CONFIG_IRDA_FAST_RR=y
CONFIG_IRDA_DEBUG=y
CONFIG_IRTTY_SIR=m
CONFIG_IRPORT_SIR=m

ส่วน Dongle / FIR ก็ config ตามฮาร์ดแวร์ที่มีอยู่ครับ

บางระบบจะไม่ probe ircomm-tty อัตโนมัติ ถ้าเจอกรณีนี้ก็ต้อง modprobe/insmod เองครับ โดย

(as root)
[kitt@peorth kitt]# modprobe ircomm-tty

จากนั้นค่อยเริ่ม pilot-xfer

มี palm หลายๆ รุ่น (หรืออาจจะทุกรุ่น ?) ที่จำเป็นต้องตั้ง flow control ของ IR เป็น off ด้วย ไม่งั้น

มันไม่ sync ครับ วิธีตั้งก็

HotSync -> Options -> Connection Setup -> IR to a PC/Handheld ->
Edit ... -> Details ... -> Flow Ctl: -> Off

ถ้าติดปัญหาเรื่อง permission เช็คที่ /etc/security/console.perm ควรจะมีสองบรรทัดนี้

<pilot>=/dev/pilot /dev/usb/ttyUSB* /dev/ircomm*
....
<console> 0600 <pilot>      0660 root.uucp

ถ้าไม่มี หรือมีแต่ไม่เหมือน ก็แก้ไขให้ได้ตามนี้ครับ จากนั้นก็ logout แล้ว login เข้ามาใหม่

Clie networking with Linux – พาน้องเอ้ท่องอินเทอร์เน็ต

วันนี้เกิดคึกอะไรขึ้นมาก็ไม่ทราบได้ อยากลองต่อ Clie เชื่อมอินเทอร์เน็ตผ่าน USB ดูว่าจะทำได้มั้ย วิธีการที่คิดไว้ก็คือใช้ PPP ผ่าน USB Serial ครับ … ก่อนอื่นก็ต้องเซ็ตค่าน้องเอ้ก่อน

Pref ==> Network:
Service: My Network
User Name: ไม่ต้องใส่
Password: ไม่ต้องใส่
Connection: Cradle/Cable

[Details...]
Connection type: PPP
Idle timeout: Never
Query DNS: Checked
IP Address: Checked Automatic

[Script...]
บรรทัดแรก เลือก End:

ส่วนของลินุกซ์ ..

ความต้องการพื้นฐานทางฝั่งลินุกซ์นี่แบ่งได้เป็นสองส่วนครับ ส่วนแรกคือส่วนของ USB Serial ซึ่งจำลอง USB เป็นดีไวซ์แบบซีเรียลเหมือน /dev/ttyS0 ทำให้เราใช้ PPP บน USB connection ได้ .. ส่วนที่สองก็คือส่วนของ PPP protocol .. มาเริ่มที่ USB Serial ก่อน .. ตรวจสอบเคอร์เนลตามนี้ครับ

CONFIG_USB_SERIAL=y or m
CONFIG_USB_SERIAL_GENERIC=y or m
CONFIG_USB_SERIAL_VISOR=y or m

อันสุดท้ายไม่เกี่ยวกับงานนี้เท่าไหร่ แต่จะได้ใช้แน่ๆ ถ้าต้องการ sync ข้อมูลระหว่าง Clie กับลินุกซ์ก็เลยเอามารวมไว้ด้วย .. ส่วนของ PPP ก็มี:

Network device support
CONFIG_DUMMY=y or m
CONFIG_PPP=y or m
CONFIG_PPP_ASYNC=y or m
CONFIG_PPP_DEFLATE=y or m
CONFIG_PPP_BSDCOMP=y or m

หลังจากเคอร์เนลสนับสนุน USB Serial และ PPP แล้วทีนี้ก็มาทดสอบกัน

กรณีของผม peorth ใช้ไอพีแอดเดรส 192.41.170.215 อยู่ในเครือข่าย 192.41.170.0/24 ผมแอบขโมยไอพี 192.41.170.217 มาใช้กับ Clie เป็นการชั่วคราว .. ส่วน Yggdrasil (192.41.170.225) เอาไว้ทดสอบการเชื่อมต่อ .. ก่อนอื่นต้อง enable IP Forwarding เสียก่อนด้วยการสั่ง

[root@peorth root]# echo "1" > /proc/sys/net/ipv4/ip_forward

เราจำเป็นต้องใช้ IP Forwarding เพราะว่าแพคเก็ตจะต้องส่งข้ามอินเทอร์เฟซ eth0 และ ppp0 .. จากนั้นที่ Clie เลือก Pref ==> Network ==> [Connect] ลองเช็ค /var/log/messages ก็จะเห็น

Jun 30 01:48:59 peorth /etc/hotplug/usb.agent: Setup visor for USB product 54c/9a/100
Jun 30 01:48:59 peorth kernel: usbserial.c: USB Serial support registered for Handspring Visor / Treo / Palm 4.0 / Cli้ 4.x
Jun 30 01:48:59 peorth kernel: usbserial.c: Handspring Visor / Treo / Palm 4.0 / Cli้ 4.x converter detected
Jun 30 01:48:59 peorth kernel: host/usb-uhci.c: interrupt, status 2, frame# 1833
Jun 30 01:48:59 peorth kernel: usbserial.c: Handspring Visor / Treo / Palm 4.0 / Cli้ 4.x converter now attached to ttyUSB0 (or usb/tts/0 for devfs)
Jun 30 01:48:59 peorth kernel: usbserial.c: Handspring Visor / Treo / Palm 4.0 / Cli้ 4.x converter now attached to ttyUSB1 (or usb/tts/1 for devfs)
Jun 30 01:48:59 peorth kernel: usbserial.c: USB Serial support registered for Sony Cli้ 3.5
Jun 30 01:48:59 peorth kernel: visor.c: USB HandSpring Visor, Palm m50x, Treo, Sony Cli้ driver v1.7

สุดท้ายก็รัน pppd:

[root@peorth root]# pppd /dev/usb/ttyUSB0 115200 10.0.0.1:192.41.170.217 ms-dns 192.41.170.15 noauth nodetach proxyarp
<code>
หลังจากสั่งคำสั่งเรียบร้อยแล้ว pppd จะไม่หลุดมาที่พรอมพ์แต่จะแสดงข้อความบอกสถานะการเชื่อมต่อ:
<code>
Using interface ppp0
Connect: ppp0  /dev/usb/ttyUSB0
Cannot determine ethernet address for proxy ARP
local  IP address 10.0.0.1
remote IP address 192.41.170.217

ถ้าใครคอมไพล์ PPP เป็นเคอร์เนลโมดูลลอง lsmod ดูควรจะปรากฏรายชื่อโมดูลประมาณนี้:

ppp_deflate             4504   0 (autoclean)
zlib_deflate           21528   0 (autoclean) [ppp_deflate]
bsd_comp                5464   0 (autoclean)
ppp_async               9440   1 (autoclean)
ppp_generic            20156   3 (autoclean) [ppp_deflate bsd_comp ppp_async]
slhc                    6756   1 (autoclean) [ppp_generic]

ออพชั่นที่ใส่ให้ pppd ประกอบด้วยซีเรียลดีไวซ์ที่ต้องการใช้งาน (/dev/usb/ttyUSB0) อัตราการส่งข้อมูล 115200 บิตต่อวินาที กำหนดไอพีแอดเดรสของ ppp0 ฝั่งลินุกซ์เป็น 10.0.0.1 (เอา private IP หมายเลขไหนก็ได้ที่ไม่มีใครใช้) pppd จะกำหนดไอพีของ Clie เป็น 192.41.170.217 (ตามที่แอบขโมยมาใช้ :P) และกำหนดไอพีแอดเดรสของ DNS Server ที่ให้ Clie ใช้เป็น 192.41.170.15 ออพชั่น noauth ทำให้เชื่อมต่อได้ทันทีโดยไม่ต้องมี Authentication (แปลว่าไม่ต้องใส่ login/password) .. nodetach ทำให้ pppd คงการควบคุมพอร์ตไว้ ถ้าไม่ใส่ pppd จะปล่อยการควบคุมให้กับระบบทันทีที่การเชื่อมต่อทำได้สำเร็จ และสุดท้าย proxyarp ทำให้เครื่องอื่นๆ มองเห็น Clie เป็นเครื่องหนึ่งในเครือข่ายเดียวกับ Peorth … จากตรงนี้ถ้าเช็ค ifconfig ก็จะมีอินเทอร์เฟซ ppp0 ปรากฏขึ้นมาไอพีแอดเดรสของ ppp0 คือ 10.0.0.1 เชื่อม Point-to-Point ไปยังไอพีแอดเดรส 192.41.170.217 ที่กำหนดให้กับ Clie:

ppp0      Link encap:Point-to-Point Protocol
          inet addr:10.0.0.1  P-t-P:192.41.170.217  Mask:255.255.255.255
          UP POINTOPOINT RUNNING NOARP MULTICAST  MTU:1500  Metric:1
          RX packets:4 errors:0 dropped:0 overruns:0 frame:0
          TX packets:5 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:3
          RX bytes:82 (82.0 b)  TX bytes:97 (97.0 b)

จะลอง ping ไปยัง Clie ดูก็ได้ครับ:

[kitt@yggdrasil kitt]$ ping 192.41.170.217
PING 192.41.170.217 (192.41.170.217) from 192.41.170.225 : 56(84) bytes of data.
64 bytes from 192.41.170.217: icmp_seq=1 ttl=254 time=15.1 ms
64 bytes from 192.41.170.217: icmp_seq=2 ttl=254 time=4.89 ms
64 bytes from 192.41.170.217: icmp_seq=3 ttl=254 time=1.31 ms
64 bytes from 192.41.170.217: icmp_seq=4 ttl=254 time=0.431 ms

ถ้าได้ขนาดนี้ Clie ก็ท่องอินเทอร์เน็ตได้ละ .. :D

มีข้อสังเกตเล็กน้อยที่ผลของคำสั่ง ping .. 192.41.170.217 และ 192.41.170.225 อยู่ในเครือข่ายเดียวกันคือ 192.41.170.0/24 ซึ่งปกติแล้วเมื่อสั่ง ping ค่า TTL (Time-To-Live) ของแพคเก็ตจะเป็น 64 หรือ 255 .. แต่ในกรณีนี้ TTL=254 เพราะแพคเก็ตต้อง forward ข้าม eth0 ไปยัง ppp0 ที่เชื่อมกับ Clie (เสมือนกับมีเราท์เตอร์คั่นอยู่ 1 hop) ทำให้ TTL มีค่าลดลงไป 1 ค่า

ถ้าไม่มีไอพีสำหรับ Clie

ในกรณีที่ไม่มีไอพีแอดเดรสที่จะกำหนดให้กับ Clie ก็ต้องทำ IP Masquerading บน eth0 กันล่ะครับ เพื่อให้ Clie ใช้ private IP เชื่อมต่ออินเทอร์เน็ตได้ผ่านทาง Peorth .. เอาล่ะครับ เช็คเคอร์เนลกันก่อนเลย

Networking option:
CONFIG_NETFILTER=y

IP: Netfilter Configuration:
CONFIG_IP_NF_CONNTRACK=y or m
CONFIG_IP_NF_IPTABLES=y or m
CONFIG_IP_NF_NAT=y or m
CONFIG_IP_NF_NAT_NEEDED=y
CONFIG_IP_NF_TARGET_MASQUERADE=y or m

จัดการเคอร์เนลเสร็จเรียบร้อยแล้วก็

[root@peorth root]# cat "1" > /proc/sys/net/ipv4/ip_forward
[root@peorth root]# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

คำสั่งนี้เป็นการทำ IP Masquerading อย่างง่ายๆ ครับ ถ้าใครเลือกคอมไพล์ออพชันต่างๆ เป็นโมดูลก็ลอง lsmod ดูครับ

ipt_MASQUERADE          2168   1  (autoclean)
iptable_nat            21272   1  (autoclean) [ipt_MASQUERADE]
ip_conntrack           27336   1  (autoclean) [ipt_MASQUERADE iptable_nat]
ip_tables              14904   4  [ipt_MASQUERADE iptable_nat]

ทีนี้ก็กด Connect ใน Pref ==> Network ==> [Connect] ของ Clie แล้วก็

[root@peorth root]# pppd /dev/usb/ttyUSB0 115200 10.0.0.1:10.0.0.2  ms-dns 192.41.170.15 noauth nodetach

ก็จะปรากฏ

Using interface ppp0
Connect: ppp0  /dev/usb/ttyUSB0
Cannot determine ethernet address for proxy ARP
local  IP address 10.0.0.1
remote IP address 10.0.0.2

จะเห็นว่าไอพีแอดเดรสของ Clie ตอนนี้ถูกกำหนดเป็น 10.0.0.2 แทน แต่ Clie ก็ยังใช้งานอินเทอร์เน็ตได้เหมือนกับ public IP จะต่างกันก็ตรงที่เครื่องอื่นๆ ไม่สามารถ ping ไปยัง Clie ได้เพราะมัน masquerade อยู่นั่นเอง .. ข้อสังเกตอีกอย่างคือ กรณีที่ทำ IP Masquerading เครื่อง Clie จะอยู่ใน private network จึงไม่จำเป็นต้องใช้ proxy ARP

แต่ไม่ว่าจะยังไง คราวนี้ก็ผมก็ sync AvantGo ผ่าน Mobile Link หรือ AG Connect ได้ไม่ยากแล้ว หรือจะเช็คเมล์ ไอซีคิว ฯลฯ ก็ยังไหว .. โฮ่ๆๆ :D

อื่นๆ

สำหรับลินุกซ์ทะเล RedHat และดิสตริบิวชั่นที่มีพื้นฐานจาก RedHat สามารถกำหนดให้ทำ IP Forwarding ถาวรเลยก็ได้ครับ โดยเพิ่มบรรทัด

FORWARD_IPV4=true

เข้าไปใน /etc/sysconfig/network แต่ผมไม่แนะนำให้ทำ เพราะเราคงไม่ได้ต่อ Clie ใช้อินเทอร์เน็ตบ่อยครั้งนัก จึงไม่จำเป็นต้องเปิด IP Forwarding ไว้ตลอดเวลา เขียนเชลล์สคริปต์ให้ทำงานเป็นครั้งๆ ไปจะดีกว่า .. ส่วนออพชั่นของเคอร์เนลถ้าเป็นไปได้ก็ควรเลือกคอมไพล์เป็นโมดูลด้วยเหตุผลเดียวกัน

คำสั่ง pppd จำเป็นต้องเรียกใช้ “หลัง” สั่ง Connect ที่ Clie เพราะดีไวซ์ /dev/usb/ttyUSB0 จะไม่ปรากฏในระบบจนว่า Clie จะเริ่มการเชื่อมต่อเข้ามาทาง USB .. หากเรียก pppd ก่อนสั่ง Connect จะมี error message ขึ้นมาประมาณว่า

Failed to open /dev/usb/ttyUSB0: No such device

ส่วนเวลาที่สั่ง disconnect ที่ Clie pppd มักจะค้างและมี error ขึ้น เป็นเพราะว่าดีไวซ์ /dev/usb/ttyUSB0 มันหายไปจากระบบแล้ว pppd จึงไม่สามารถสั่ง flush ดีไวซ์ได้ ให้กด Ctrl+C เพื่อออกจาก pppd

สุดท้าย .. หากอะไรๆ ไม่เป็นไปอย่างที่คาดหวัง หรือไม่เป็นไปตามที่ผมเขียนๆ ไว้ .. ลอง tail /var/log/message lsmod modprobe tcpdump man และ google อาจจะพอช่วยได้ .. ไปนอนล่ะคร้าบบ

MIDI SoftSynth บนลินุกซ์ด้วย ALSA VirMIDI + TiMidity

ปัญหานึงของซาวด์การ์ดหลายๆ รุ่นคือไม่มีมิดี้ที่เป็นฮาร์ดแวร์ หรือ FM Synth ก็เลยไม่สามารถเล่นมิดี้บนลินุกซ์ได้ (ถ้าเป็นวินโดวส์ ไดรเวอร์จะจำลองมิดิ้ให้ เป็นซอฟต์ซินธ์ด้วย (SoftSynth/Software Wave Table Emulation) แต่นับว่าโชคดีที่ลินุกซ์ทะเลใช้ระบบเสียงของ ALSA (Advanced Linux Sound Architecture) ก็เลยมีทางที่จะเซ็ตซอฟต์ซินธ์บลินุกซ์ด้วยเหมือนกันโดยใช้ไดรเวอร์ Virtual MIDI และซอฟต์แวร์ชื่อ TiMidity++ … ขั้นตอนมีดังนี้ครับ

เริ่มกันที่ ALSA

คอมไฟล์ alsa-driver โดยระบุให้สร้างไดรเวอร์ virmidi ด้วย ถ้าติดตั้งลินุกซ์ทะเลปกติ จะมีไดรเวอร์นี้อยู่แล้ว แต่สำหรับคนที่ recompile alsa-driver ใหม่ถ้าระบุออพชั่น –with-cards ให้ใส่ virmidi เข้าไปด้วยประมาณนี้

./configure --with-sequencer=yes --with-oss=yes --with-cards=virmidi,intel8x0

จากนั้นก็ make และ make install ตามปกติ หลังจากติดตั้ง alsa-driver แล้ว ทีนี้ก็ลอง load kernel module กัน ..

[kitt@peorth kitt]$ modprobe snd-virmidi index=1

ถ้า lsmod ดูควรจะเห็นอะไรประมาณนี้

snd-virmidi             2144   0 (autoclean)
snd-seq-virmidi         5096   0 (autoclean) [snd-virmidi]
snd-seq-midi-event      5672   0 (autoclean) [snd-seq-virmidi]
snd-seq                47408   0 (autoclean) [snd-seq-virmidi snd-seq-midi-event]
snd-intel8x0           24228   1
snd-pcm                83360   0 [snd-intel8x0]
snd-timer              19688   0 [snd-seq snd-pcm]
snd-ac97-codec         44640   0 [snd-intel8x0]
snd-page-alloc          8552   0 [snd-intel8x0 snd-pcm]
snd-mpu401-uart         5184   0 [snd-intel8x0]
snd-rawmidi            18752   0 [snd-seq-virmidi snd-mpu401-uart]
snd-seq-device          6364   0 [snd-seq snd-rawmidi]
snd                    43332   0 [snd-mixer-oss snd-virmidi snd-seq-virmidi
snd-seq-midi-event snd-seq snd-intel8x0 snd-pcm snd-timer snd-ac97-codec
snd-mpu401-uart snd-rawmidi snd-seq-device]

ลองสั่ง cat /proc/asound/cards

[kitt@peorth kitt]$ cat /proc/asound/cards
0 [82801CAICH3    ]: ICH - Intel 82801CA-ICH3
                     Intel 82801CA-ICH3 at 0x9800, irq 10
1 [VirMIDI        ]: VirMIDI - VirMIDI
                     Virtual MIDI Card 1

จะเห็นว่ามีซาวด์การ์ดสองใบ หนึ่งในนั้นเป็นซาวด์การ์ดจริง (ในตัวอย่างนี้คือ 82801CA ICH3 ของชิพเซ็ต i830) อีกตัวเป็น VirMIDI เป็นการ์ดที่จำลองขึ้นมาโดย module snd-virmidi ..

TiMidity

ที่จริงลินุกซ์ทะเลให้ TiMidity++ มาด้วยนะครับ แต่ว่าไม่ได้คอมไพล์ให้ใช้กับ ALSA ได้ .. ก็ต้องดาวน์โหลดเวอร์ชันที่คอมไพล์ ALSA และ ALSA Sequencer Client ด้วย .. ไม่ต้องไปหาไกล ผมทำให้แล้วล่ะ คิดว่าคงอยู่ใน TLE Update แล้ว จะใช้ Synaptic หรือจะสั่ง apt-get install หรือ apt-get update/upgrade เอาก็ได้ หรือดาวน์โหลด rpm ก็ได้ที่

ftp://ftp.kitty.in.th/pub/rpms/timidity++-2.11.3-4_1kit.i386.rpm

เชื่อม Virtual MIDI กับ TiMidity

Virtual MIDI ไม่ได้เล่นมิดี้ได้ด้วยตัวเองครับ มันแค่จำลองเป็นมิดี้อินเทอร์เฟซเท่านั้น จะทำให้มันเล่นมิดี้ มีเสียงได้ต้องทำให้ Virtual MIDI ส่งข้อมูลมิดี้ไปยัง TiMidity++ ให้ได้เสียก่อน .. อืมม จะอธิบายหลักการตรงนี้ก็เป็นเรื่องยาว .. ขอตัดบทเลยก็แล้วกัน ก่อนอื่น TiMidity++ เป็นโหมด ALSA Sequencer Client โดยระบุออพชัน -iA เข้าไป

[kitt@peorth kitt]$ timidity -iA -Os &
[1] 1106
Requested buffer size 32768, fragment size 8192
ALSA pcm 'default' set buffer size 32768, period size 8192 bytes
TiMidity starting in ALSA server mode
can't set sched_setscheduler - using normal priority
Opening sequencer port: 128:0 128:1

จากนั้นหาหมายเลขพอร์ตของ Virtual MIDI โดยดูจากไฟล์ /proc/asound/clients หรือ /proc/asound/seq/clients

[kitt@peorth kitt]$ cat /proc/asound/seq/clients
Client info
  cur  clients : 6
  peak clients : 6
  max  clients : 192

Client   0 : "System" [Kernel]
  Port   0 : "Timer" (Rwe-)
  Port   1 : "Announce" (R-e-)
Client  72 : "Virtual Raw MIDI 1-0" [Kernel]
  Port   0 : "VirMIDI 1-0" (RWeX)
Client  73 : "Virtual Raw MIDI 1-1" [Kernel]
  Port   0 : "VirMIDI 1-1" (RWeX)
Client  74 : "Virtual Raw MIDI 1-2" [Kernel]
  Port   0 : "VirMIDI 1-2" (RWeX)
Client  75 : "Virtual Raw MIDI 1-3" [Kernel]
  Port   0 : "VirMIDI 1-3" (RWeX)
Client 128 : "Client-128" [User]
  Port   0 : "TiMidity port 0" (-We-)
  Port   1 : "TiMidity port 1" (-We-)
  Output pool :
    Pool size          : 500
    Cells in use       : 0
    Peak cells in use  : 0
    Alloc success      : 0
    Alloc failures     : 0
  Input pool :
    Pool size          : 1000
    Cells in use       : 0
    Peak cells in use  : 0
    Alloc success      : 0
    Alloc failures     : 0

จะเห็นว่ามี Virtual RAW MIDI อยู่ 4 ไคลเอนด์ หมายเลข 72, 73, 74 และ 75 ตามลำดับ ทุกตัวมีพอร์ต 0 … ส่วน TiMidity++ อยู่ที่ 128 มีสองพอร์ตคือ 0 และ 1 .. เมื่อได้หมายเลขพอร์ตแล้วก็สั่งเชื่อมพอร์ตได้แล้ว ที่ต้องทำก็คือเชื่อมพอร์ต 0 ของ Virtual RAW MIDI ตัวแรก เข้าไปที่พอร์ต 0 ของ TiMidity++ โดยคำสั่ง aconnect

[kitt@peorth kitt]$ aconnect 72:0 128:0

ดู /proc/asound/seq/clients อีกครั้ง

[kitt@peorth kitt]$ cat /proc/asound/seq/clients
Client info
  cur  clients : 6
  peak clients : 7
  max  clients : 192

Client   0 : "System" [Kernel]
  Port   0 : "Timer" (Rwe-)
  Port   1 : "Announce" (R-e-)
Client  72 : "Virtual Raw MIDI 1-0" [Kernel]
  Port   0 : "VirMIDI 1-0" (RWeX)
    Connecting To: 128:0
Client  73 : "Virtual Raw MIDI 1-1" [Kernel]
  Port   0 : "VirMIDI 1-1" (RWeX)
Client  74 : "Virtual Raw MIDI 1-2" [Kernel]
  Port   0 : "VirMIDI 1-2" (RWeX)
Client  75 : "Virtual Raw MIDI 1-3" [Kernel]
  Port   0 : "VirMIDI 1-3" (RWeX)
Client 128 : "Client-128" [User]
  Port   0 : "TiMidity port 0" (-We-)
    Connected From: 72:0
  Port   1 : "TiMidity port 1" (-We-)
  Output pool :
    Pool size          : 500
    Cells in use       : 0
    Peak cells in use  : 0
    Alloc success      : 0
    Alloc failures     : 0
  Input pool :
    Pool size          : 1000
    Cells in use       : 0
    Peak cells in use  : 1
    Alloc success      : 1
    Alloc failures     : 0

จะเห็นว่า Client 72 มีข้อความ Connected To: 128:0 และที่ TiMidity++ มีข้อความ Connected From: 72:0

แสดงว่าเชื่อมต่อเป็นที่เรียบร้อยแล้ว ถ้าสั่ง playmidi หรือใช้โปรแกรมอะไรก็ตามที่ใช้งานมิดี้ ข้อมูลของมิดี้จะส่งผ่าน external MIDI ซึ่งจำลองขึ้นมาโดยไดรเวอร์ Virtual MIDI ไปยัง TiMidity++ แล้วเราก็จะได้ยินเสียงมิดี้กันล่ะ :)

คอนฟิกระบบ

ถ้าต้องการคอนฟิกให้ลินุกซ์เรียก Virtual MIDI อัตโนมัติทุกครั้งที่บูตก็สามารถทำได้โดยแก้ /etc/modules.conf ประมาณนี้

alias snd-card-0 snd-intel8x0
alias snd-card-1 snd-virmidi
alias sound-slot-0 snd-card-0
alias sound-slot-1 snd-card-1
alias char-major-116 snd
alias char-major-14 soundcore
options snd major=116 cards_limit=2
options snd-intel8x0 index=0
options snd-virmidi index=1
alias sound-service-0-0 snd-mixer-oss
alias sound-service-0-1 snd-seq-oss
alias sound-service-0-3 snd-pcm-oss
alias sound-service-0-8 snd-seq-oss
alias sound-service-0-12 snd-pcm-oss

ที่ต้องเพิ่มเข้าไปใน /etc/modules.conf ก็คือ บรรทัด

alias snd-card-1 snd-virmidi
alias sound-slot-1 snd-card-1
options snd-virmidi index=1

และต้องเปลี่ยน cards_limit เป็น 2

ทีนี้ทุกครั้งที่บูต snd-virmidi module ก็จะได้รับการติดตั้งอัตโนมัติ ส่วนการเชื่อม Virtual MIDI กับ TiMidity++ ทำเป็นครั้งๆ ไปเมื่อต้องการใช้ดีกว่า เพราะยังต้องรัน timidity -iA -Os ก่อนถึงจะสั่ง aconnect ได้ .. จะให้มันรันตอนบูตเลยดูจะเป็นการเปลืองทรัพยากรระบบเปล่าๆ

อื่นๆ

ยังมีเทคนิคอีกเล็กน้อยสำหรับ TiMidity++ เพื่อให้การทำงานกับมิดี้ตอบสนองได้ดีขึ้นครับ … ปกติ TiMidity ใช้บัฟเฟอร์ขนาดใหญ่เพื่อให้เพลย์ได้ราบรื่น แต่ก็ทำให้มี latency เยอะซึ่งไม่เหมาะกับโปรแกรมที่ต้องการทำงานแบบเรียลไทม์ เช่น โปรแกรมซีเควนเซอร์ อย่าง Rosegarden หรือ Noteedit ทางแก้คือกำหนดบัฟเฟอร์ให้เล็กลงด้วยออพชัน -B ค่าที่เหมาะๆ มีคนแนะมาว่าใช้ -B2,8 ส่วนตัวผมใช้ -B8,8 กำลังพอดี

ถ้า TiMidity++ กินซีพียูเยอะ และต้องการลดมันลง สามารถทำได้โดยยกเลิกเอฟเฟกต์ต่างๆ เช่น reverb และ/หรือ chorus โดยกำหนดออพชัน -EFreverb=0 และ/หรือ -EFchorus=0 ตามลำดับ

ถ้ายังไม่พอใจอีก ก็ต้องลองรัน TiMidity++ ด้วย root หรือตั้ง suid root วิธีนี้ทำให้ TiMidity++ สามารถตั้ง scheduling เป็น FIFO ด้วย priority สูงสุดเท่าที่จะทำได้ (ซึ่งมีเฉพาะ root ที่มีสิทธิตั้งค่าแบบนั้น) วิธีนี้ทำให้การตอบสนองดีขึ้นโดยเฉพาะกับโปรแกรมที่ทำงานแบบเรียลไทม์

.. วันนี้ยาวแฮะ

ใช้ภาษาญี่ปุ่นบนลินุกซ์

พยายามกับภาษาญี่ปุ่นบนลินุกซ์มานานแล้ว วันนี้ก็เห็นผลเสียทีครับ เรื่องของเรื่องก็คือลินุกซ์ทะเล 5.0 ไม่มีภาษาญี่ปุ่นให้เลือก ตอนติดตั้ง .. glibc ก็เลยไม่สนับสนุน locale ญี่ปุ่นเลย หลังจากเอาเวลาว่างๆ ไปค้นข้อมูลหลายหน ก็ได้ข้อสรุปมาบ้างแล้ว

อย่างแรกเลยคือเรื่องของ locale ภาษาญี่ปุ่นที่ต้องเพิ่มเข้าไปใน glibc .. ทำได้ไม่ยากเลย แต่กว่าจะรู้วิธีนี้ก็เสียเวลางมหาซะนาน กุญแจอยู่ที่ localedef นั่นเองครับ .. สำหรับภาษาญี่ปุ่นนิยมใช้ ja_JP.eucJP ก็ localedef ได้เป็น

# localedef -v -c -i ja_JP -f EUC-JP /usr/lib/locale/ja_JP.eucJP

ลองสั่ง locale -a ดูถ้ามี ja_JP ก็ใช้ได้แล้ว

อย่างที่สองคือ keyboard input .. ต้องติดตั้งหลายตัวหน่อย

Canna
Canna-libs
FreeWnn
FreeWnn-libs
FreeWnn-common
Wnn6-SDK
kinput2-canna-wnn6
kterm

ไม่ต้องคิดมาก ลงๆ ไปเลย apt-get install kinput2 เอาก็ได้ เดี๋ยวมันลาก dependencies มาลงให้เอง :)

วิธีทดสอบ

ก็ลองกันด้วย kterm นี่ล่ะครับ .. สตาร์ท canna เซิร์ฟเวอร์ก่อน ตามด้วย kinput2 เพื่อเชื่อมกับ canna แล้วค่อยเรียก kterm:

# service canna start
# kinput2 -canna &
# kterm &

ใน kterm กด shift-space จะเข้าสู่โหมด input ภาษาญี่ปุ่น ลองพิมพ์ภาษาญี่ปุ่นด้วยอักษรโรมาจิ .. เอาเป็น konnichiha ก็ได้ จะเห็นว่ามันแสดงเป็นตัวอักษรฮิระงานะ มีเส้นขีดใต้ข้อความ เส้นนี้เป็นตัวบอกว่าข้อความไหนที่ kinput2 กำลังประมวลผลอยู่ ลองเคาะ space ดูมันจะแสดงตัวคันจิขึ้นมาด้วย ถ้าเคาะ space อีกครั้ง kinput2 จะแสดงหน้าต่างให้เลือกตัวคันจิ คะตะคะนะ และฮิระงานะด้วย

ใช้ space หรือปุ่มลูกศรเลือกคำที่ต้องการ แล้วก็เคาะ enter .. หน้าต่างก็จะปิดลง เคาะ enter อีกครั้ง เส้นใต้ข้อความจะหายไป กด shift-space อีกครั้งก็จะออกจากโหมด input ภาษาญี่ปุ่น ..พอใช้ kterm ได้โปรแกรมอื่นๆ ที่ run เป็น text mode บน kterm ก็ควรจะใช้ภาษาญี่ปุ่นได้ด้วย .. ลองดูก็แล้วกัน

บน GNOME2

สำหรับ GNOME2 สามารถเซ็ตให้โปรแกรมใช้ kinput2 ได้โดยใช้ XIM .. อย่างแรกก็ต้องตั้ง XMODIFIERS ให้ input method เป็น kinput2 ก่อน

export XMODIFIERS="@im=kinput2"

ทีนี้ kinput2 จะทำงานอัตโนมัติถ้าโปรแกรมนั้นทำงานด้วย locale ญี่ปุ่น สมมติเป็น gedit บน terminal สั่ง

LANG=ja_JP gedit

จะ start gedit โดยกำหนดให้ LANG ที่ใช้เป็น ja_JP ครับ ทีนี้ใน gedit ให้คลิกขวาเลือก input method เป็น X Input Method ก็จะใช้ภาษาญี่ปุ่นได้เหมือนบน kterm .. อ่อ อย่าลืมเปลี่ยนฟอนต์เป็นภาษาญี่ปุ่นด้วยนะครับ ถ้าไม่มีก็ติดตั้งแพคเกจ ttfonts-ja ได้จากแผ่นติดตั้งลินุกซ์ทะเล หรือ apt-get install เอาก็ได้

เฮ่อ .. ได้ขนาดนี้ก็พอใจแล้ว .. วันนี้เอาไว้เท่านี้ก่อนครับ :)

ปรับขนาดพาร์ติชันบนลินุกซ์โดยไม่ต้องลบ/ย้ายข้อมูล

อยากลองใช้ transcode แปลง DVD เป็น VCD ดูสักหนล่ะครับ แต่พาร์ติชันขนาด 5 GB ที่กันไว้ตอนแรกไม่พอเสียแล้ว .. ก็แค่ซอร์สของ DVD แผ่นนึงก็หมดไป 4 กิ๊กแล้ว .. อิมเมจของ VCD ที่จะสร้างด้วย transcode ก็ใช้พื้นที่อีกประมาณ 1.4 GB (เท่ากับแผ่นซีดี 700 MB สองแผ่นไง) แต่เวลา encode ต้องมีพื้นที่ว่างๆ ประมาณสามเท่าของอิมเมจ รวมๆ กันแล้วต้องใช้พื้นที่ 8-9 GB .. เฮ่อ .. ฮาร์ดดิสก์ 60 GB จะหมดก็คราวนี้ล่ะฟะ .. วกกลับมาเรื่องพาร์ติชัน 5 GB กันต่อ .. ในเมื่อมันไม่พอก็ขยายพาร์ติชันสิ ข่าวดี (หรือหรือข่าวเก่าแล้วก็ไม่รู้) คือพาร์ติชันที่ใช้ไฟล์ซิสเต็มแบบ ext2/ext3 สามารถย่อ/ขยาย ได้โดยข้อมูลไม่สูญหาย ไม่ต้องลบ หรือย้ายข้อมูลก่อนด้วย .. โอ๊ะ .. ทำได้ไงๆๆ …

สิ่งที่ต้องทำมีสองส่วนคือปรับขนาดของไฟล์ซิสเต็ม และปรับขนาดของพาร์ติชันครับ .. การปรับขนาด ext2/ext3 ทำได้ด้วย resize2fs ส่วนขนาดของพาร์ติชันก็ใช้ fdisk นี่ล่ะ .. เริ่มกันเลย ..

สมมติว่าต้องการขยาย /dev/hda7 ก่อนอื่นต้อง fdisk ก่อน ดูให้แน่ใจว่ามีที่ว่ามีที่ว่างต่อจากพาร์ติชันที่ต้องการขยาย จากนั้นทำตามขั้นตอนนี้

  1. unmount file system ที่จะขยายเสียก่อน
  2. เรียกโปรแกรม fdisk
  3. จดตัวเลข start ของ /dev/hda7 .. จดสิๆๆ
  4. ลบ {{/dev/hda7 ทิ้ง ..เอ่อ.. ไม่ต้องห่วงๆ เพราะข้อมูลทุกอย่างยังไม่หายไปไหน มันแค่ลบ entry ในตารางพาร์ติชันของฮาร์ดดิสก์ ไม่ได้ลบข้อมูล .. แต่ถ้าต้องการให้มันกลับมาก็ต้องสร้างพาร์ติชันที่มีตำแหน่งเริ่มต้นตรงที่เดิม นั่นเป็นเหตุผลว่าทำไมต้องจด start ของ /dev/hda7 ไว้ ..
  5. สร้างพาร์ติชัน /dev/hda7 เริ่มต้นที่เลข start ตัวเดิม กำหนดขนาดตามต้องการ แต่ไม่เกินพื้นที่ว่างที่เหลืออยู่
  6. บันทึกการเปลี่ยนแปลง ออกจาก fdisk
  7. รีบูต .. เพื่อความแน่นอน.. รีบูตเลยครับ .. ผมเคยพลาดมาแล้ว ใจร้อน ไม่ยอมรีบูต ไฟล์ซิสเต็มหาย ข้อมูลไปหมดเลย กู้กันสามวันสามคืน ได้ข้อมูลสำคัญๆ กลับมา 3-4 MB แต่ชีวิตหลังจากนั้นเหมือนกลับไปอยู่อดีต 3 เดือนก่อน เพราะแบคอัพล่าสุดอายุประมาณนั้น
  8. หลังจากรีบูตแล้ว e2fsck -f /dev/hda7 พาร์ติชันก่อนหนึ่งที
  9. จากนั้นสั่ง resize2fs /dev/hda7 แล้วก็ลุ้น.. ไม่ต้องกลั้นหายใจนะครับ ถ้าขยายไฟล์ซิสเต็มให้โตขึ้นใหญ่มากๆ ก็ต้องรอนานเป็นนาทีเหมือนกัน :)

ส่วนการย่อขนาดพาร์ติชัน ต้องสั่ง resize2fs เพื่อเปลี่ยนขนาดไฟล์ซิสเต็มก่อน แล้วค่อย fdisk ไปแก้ขนาดพาร์ติชัน สมมติว่าจะย่อ /dev/hda7 ให้เหลือแค่ 1048576 blocks ก็สั่ง

resize2fs /dev/hda7 1048576

จากนั้นก็เข้า fdisk จดตำแหน่งเริ่มต้นของพาร์ติชัน ลบพาร์ติชันของ /dev/hda7 ทิ้ง แล้วสร้างใหม่แบบเดียวกับการขยาย ข้อควรระวังคือ ต้องกำหนดขนาดพาร์ติชันไม่ให้เล็กไปกว่าขนาดที่ระบุตอน resize2fs (เช่น ในตัวอย่างนี้คือ 1048576 blocks) เพราะจะทำให้ข้อมูลหายได้

เสร็จแล้ว ขอตัวไป RIP DVD ก่อนละคร้าบบบ

แชร์ไฟล์/พรินเตอร์ผ่านโปรโตคอล AppleTalk ด้วยลินุกซ์

ที่ห้องแล็ป IRL พรินเตอร์จะต่อตรงกับเครื่อง Yggdrasil แล้วก็แชร์ผ่าน Samba ให้คนอื่นๆ ได้ใช้ แต่แล้วก็เกิดมีเครื่อง Apple PowerBook และ Apple iBook โผล่เข้ามาในเน็ตเวิร์ค แรกๆ ก็ไม่คิดว่าจะยุ่งยากอะไรจนกระทั่งได้รู้ว่า MacOS X มันไม่สามารถพิมพ์ผ่าน SMB ได้ …แปลกแฮะ ที่จริง OSX ก็มี SMB นะครับ แต่ว่ามันใช้ได้กับไฟล์เท่านั้น .. เท่าที่ google หาดูก็มีทางออกอยู่ 2-3 ทางคือ ซื้อ DAVE มาใช้ โปรแกรมนี้คงเรียกได้ว่าเป็น Samba for Mac แต่ไม่ฟรี (~ US$150) .. หรืออีกทางนึงก็คือคอนฟิกให้ Yggdrasil รู้จัก AppleTalk แล้วแชร์ไฟล์และพรินเตอร์ผ่าน netatalk .. อืมม.. วิธีหลังนี่น่าสนใจครับ :)

เคอร์เนลของลินุกซ์มี AppleTalk นานพอสมควรแล้ว และมีแพคเกจสำหรับแชร์ไฟล์ ไดเรคทอรี่ และพรินเตอร์ได้ .. แพคเกจที่ว่านี่ก็คือ netatalk (อ่านว่า เนต–ทอล์ค ลากเสียง ‘เนต’ ยาวๆ) .. ก่อนอื่น จัดการกับเคอร์เนลซะก่อน เช็คดูก่อนว่าเคอร์เนลสนับสนุน AppleTalk หรือยัง ถ้ายังก็ต้อง recompile เคอร์เนลครับ

CONFIG_ATALK=y or m

จากนั้นติดตั้ง netatalk มี rpm เยอะแยะ หาดาวน์โหลดเอา ดีฟอลต์คอนฟิกฯ จะแชร์โฮมไดเรคทอรีให้อัตโนมัติ ค่อนข้างสะดวก ที่ต้องเพิ่มเข้าไปก็เป็นพวก แชร์พรินเตอร์ หรือ ไดเรคทอรีอื่นๆ

สำหรับลินุกซ์ทะเล ใช้ CUPS ก็แก้ /etc/atalk/papd.conf โดยเพิ่ม

HP4:
:pr=|/usr/bin/lpr:
:op=root:
:pd=/etc/cups/ppd/HP4.pdd:

บรรทัดแรก เป็นชื่อพรินเตอร์ที่จะปรากฏเมื่อเชื่อมผ่าน AppleTalk

บรรทัดที่สอง เป็นคำสั่งในการพิมพ์งาน กรณีของ CUPS จะใช้คำสั่งอย่างที่ปรากฏในตัวอย่างนี้ ส่วนอื่นๆ .. google เอา

บรรทัดที่สาม เป็น queue operator ของทะเลใช้ lp หรือไม่ก็ root ไปเลย

บรรทัดสุดท้าย เป็น ppd ที่จะใช้ ..ปกติแล้วเมื่อติดตั้งพรินเตอร์ CUPS จะสร้าง ppd เก็บไว้ที่ /etc/cups/ppd ก็เอามาใช้ได้เลย

ส่วนแชร์ไดเรคทอรี สามารถเพิ่มใน /etc/atalk/AppleVolumes.default เช่น

/usr2/public "Shared Space"

จากนั้นก็สตาร์ทเซอร์วิส atalk และ/หรือ คอนฟิกให้เรียกใช้เมื่อบูต

ทางฝั่งเครื่องแมค ให้ enable AppleTalk ใน System Preference -> Network จากนั้นก็เพิ่มพรินเตอร์เข้าไปในระบบโดยเลือกตามรูป

อย่าลืมเลือก Printer Model เป็น Generic เพราะเท่าที่ทดสอบดูถ้าเลือกเป็นอย่างอื่นจะพิมพ์ไม่ออก หลังจากเพิ่มเข้าไปแล้วเน็ตเวิร์คพรินเตอร์นี้ก็จะเข้าไปเป็นพรินเตอร์ตัวนึงของระบบ ตั้งเป็นดีฟอลต์ก็ได้ถ้าต้องการ

จากนั้นก็ลองสั่งพิมพ์เอกสารดู ..

ถ้าไม่สำเร็จ ให้ลองดู log ของ atalk และ cups ที่เซิร์ฟเวอร์ครับ จากนั้นก็ตัวใครตัวมันละครับ แก้ปัญหากันเอาเอง :P .. ที่จริงยังเหลือไม้ตายอีกทางหนึ่งคือ พิมพ์ผ่าน IPP (Internet Printing Protocol) ไปที่ CUPS บน Yggdrasil .. แต่เอาไว้โอกาสหน้าก็แล้วกัน