Hello World ด้วย GNU Autotools

เรื่องของเรื่องก็คือ อยากจะหัดใช้ Autotools สักหน่อย .. ง่ายสุดก็ต้องกับโปรแกรม Hello World นี่ล่ะ :D

แนะนำ GNU Autotools

ปกติแล้ว ถ้าเราเขียนโปรแกรมด้วยภาษาซีบนลินุกซ์หรือยูนิกซ์โดยที่โปรแกรมมีซอร์สไม่กี่ไฟล์ เราสามารถสั่งคอมไพล์ด้วยคำสั่ง cc หรือ gcc ได้ไม่ยาก แต่ถ้าโปรแกรมมีความซับซ้อนมากขึ้น มีหลายโมดูล แยกเป็นหลายไดเรกทอรี การสั่ง cc/gcc เพื่อ build โปรแกรมจะเริ่มยุ่งยากขึ้น วิธีที่สะดวกกว่าโดยทั่วไปก็คือเขียน Makefile ขึ้นมา ซึ่งช่วยให้การ build โปรแกรมทำได้โดยสั่ง make

อย่างไรก็ตาม การเขียน Makefile สำหรับโครงการซอฟต์แวร์ใหญ่ๆ ไม่ใช่เรื่องง่ายนัก และบ่อยครั้งจะมีปัญหาว่าไม่สามารถนำ Makefile ที่เขียนสำหรับ build บนแพลตฟอร์มนึงไปใช้งานบนแพลตฟอร์มอื่นได้ แม้จะเป็นระบบที่ใกล้เคียงหรือเป็นยูนิกซ์เหมือนกันก็ตาม เหตุก็เพราะเงื่อนไขในการ build โปรแกรมบนแพลตฟอร์มต่างๆ มักไม่เหมือนกัน การ build ซอฟต์แวร์ตัวเดียวกันบนแพลตฟอร์มต่างกันจึงมักต้องใช้ Makefile ที่ต่างกันตามไปด้วย

จากปัญหาดังกล่าวจึงมีการพัฒนาเทคนิควิธีต่างๆ เพื่อทำให้ซอฟต์แวร์สามารถพอร์ตไปใช้บนแพลตฟอร์มต่างๆ ได้ง่ายขึ้น หนึ่งในนั้นก็คือ GNU Autotools .. ด้วยกลไกของ Autotools นักพัฒนาซอฟต์แวร์มีหน้าที่ระบุเงื่อนไขที่จำเป็นในการ build ซอฟต์แวร์นั้นๆ โดยไม่ต้องห่วงเรื่องของแพลตฟอร์ม Autotools มีชุดเครื่องมือในการสร้าง Makefile ให้สำหรับแพลตฟอร์มนั้นๆ อัตโนมัติ ทำให้ซอฟต์แวร์สามารถพอร์ตไปใช้งานต่างแพลตฟอร์มได้ง่ายขึ้น

ปัจจุบันมีการใช้งาน Autotools กันอย่างแพร่หลายบนลินุกซ์และยูนิกซ์ อย่างที่เรามักจะเห็นขั้นตอนการติดตั้งซอฟต์แวร์โดยสั่ง ./configure; make; make install นั่นก็เป็นผลของ Autotools เหมือนกัน เพราะสคริปต์ configure โปรแกรมไหนๆ ก็สร้างมาจาก Autotools เกือบทั้งนั้น

มาดูกันสักหน่อยว่า Autotools ประกอบด้วยอะไรบ้าง

เครื่องมือ

เครื่องมือของ GNU Autotools หลักๆ ประกอบด้วย autoscan aclocal autoconf autoheader และ automake แต่ละตัวใช้สร้างไฟล์ที่จำเป็นในการ build ซอฟต์แวร์ และมีความสัมพันธ์กันดังที่แสดงในภาพ

จะเห็นได้ว่า นอกจากซอร์สโปรแกรมแล้ว ในขั้นต่ำสุดมีเพียง Makefile.am และ configure.in (หรือ configure.ac) เท่านั้นที่นักพัฒนาซอฟต์แวร์ต้องเขียนเอง ที่เหลือ Autotools สามารถสร้างให้เองอัตโนมัติ

aclocal ทำหน้าที่ในการหามาโครที่จำเป็นต้องใช้จาก configure.in สร้าง เอาต์พุตเป็น aclocal.m4 หากมีไฟล์ acinclude.m4 (user-defined macro) ก็จะถูกรวมเข้าไปด้วยในขั้นตอนนี้ ไฟล์ aclocal.m4 นี้จะเป็นอินพุตสำหรับ autoconf และ autoheader ต่อไป

autoconf ทำหน้าที่สร้างสคริปต์ configure จาก configure.in และ aclocal.m4 .. configure เป็นสคริปต์ที่ใช้ตรวจสอบระบบตามเงื่อนไขและสร้าง Makefile ที่เหมาะสมกับระบบนั้นอัตโนมัติ การสร้าง Makefile นั้น สคริปต์ configure ต้องการไฟล์สำคัญอีกตัวคือ Makefile.in ซึ่งสร้างจาก Makefile.am โดย automake

เครื่องมืออีกตัวคือ autoheader ใช้สร้าง config.h.in ซึ่งเป็นเท็มเพลตของ header ที่ configure จะเอาไปใช้งานอีกที

ลองมาดูตัวอย่างการใช้ Autotools กับโปรแกรมยอดฮิต Hello World!

Hello World Project

ก่อนอื่นสร้างไดเรกทอรีสำหรับโครงการก่อน ไฟล์ทั้งหมดในโครงการจะเก็บไว้ในไดเรกทอรีเดียวกันนี้

ไฟล์แรกที่ต้องเขียนก่อนก็คือซอร์สของ hello.c

#include <stdio.h>
int main() {
    printf("Hello world !");
    return 0;
}

แล้วก็เขียน configure.in อย่างง่ายๆ ประกอบด้วย

AC_INIT(hello.c)
AM_INIT_AUTOMAKE(hello,0.1)
AC_PROG_CC
AC_PROG_INSTALL
AC_OUTPUT(Makefile)

AC_INIT เป็นบรรทัดบังคับที่ต้องมีและต้องเป็นมาโครแรกของ configure.in เสมอ AM_INIT_AUTOMAKE ก็เป็นอีกหนึ่งบรรทัดที่จำเป็นต้องมีเมื่อต้องใช้งาน automake ส่วน AC_PROG_CC และ AC_PROG_INSTALL เป็นการระบุโปรแกรมที่ต้องการใช้งาน ในที่นี้คือ C compiler และโปรแกรม install บรรทัดสุดท้ายเป็นการระบุให้สคริปต์ configure สร้างผลลัพธ์เป็น Makefile

ได้ configure.in เรียบร้อยแล้ว ก็มาเขียน Makefile.am กัน … อย่างง่ายๆ ก็มีเพียงสองบรรทัด ระบุโปรแกรมที่จะ build และซอร์สของโปรแกรม

bin_PROGRAMS = hello
hello_SOURCES = hello.c

ขั้นตอนการสร้างสคริปต์ configure ก็มีเพียง

aclocal
autoconf
touch NEWS README AUTHORS ChangeLog
automake --add-missing

บรรทัดที่สามอาจจะดูประหลาดกว่าเพื่อน และไม่ได้เป็นส่วนหนึ่งของ Autotools คำสั่ง touch ใช้ในการแก้ไข timestamp ของไฟล์ แต่เราสามารถนำมาใช้สร้างไฟล์ dummy (ขนาดเป็น 0 byte) ได้ด้วย ในตัวอย่างนี้ใช้ touch สร้าง dummy ไฟล์ชื่อ NEWS README AUTHORS ChangeLog ตามลำดับ ทั้งสี่ไฟล์ไม่มีข้อมูลอะไรเลย แต่ที่ต้องสร้างไว้เพราะ automake จะตรวจหาไฟล์เหล่านี้ขณะทำงาน ถ้าไม่พบไฟล์ทั้งสี่ก็จะเกิด error ขึ้น .. ในภายหลังเราอาจจะแก้ไขไฟล์เหล่านี้เพื่อเพิ่มรายละเอียดเกี่ยวกับการพัฒนาซอฟต์แวร์ แต่ตอนนี้ทำเป็นอย่างนี้ไว้ก่อน

ออปชัน --add-missing ที่ใส่ให้กับ automake เป็นการบอกให้ automake สร้างไฟล์ที่ขาดไปอัตโนมัติ เสร็จขั้นตอน automake แล้วเราก็พร้อมที่จะ build โปรแกรม Hello World กัน

./configure
make
make install

ที่จริงแล้ว Makefile ที่สร้างโดยสคริปต์ configure จะเตรียมกฏในการ make ไว้ให้อีกหลายตัว เช่น

make uninstall
make clean
make maintainer-clean
make distclean
make dist
make distcheck

ทั้งหมดนี่ก็เป็นตัวอย่างง่ายๆ ในการใช้ GNU Autotools .. รายละเอียดของ Autotools ยังมีอีกเยอะมาก เรายังไม่ได้ลองใช้ autoscan และ autoheader กันเลย การพัฒนาโครงการซอฟต์แวร์ในทางปฏิบัติยังมีรายละเอียดอีกพอสมควร อย่างเช่น การจัดไดเรกทอรี และการทำไลบรารี เอาไว้วันหลังจะมาเล่าให้ฟัง


Reference

  1. เทพพิทักษ์ การุณบุญญานันท์, แนะนำ GNU autotools, ประชุมเชิงปฏิบัติการ “การใช้ Development Tool เพื่อการพัฒนาซอฟต์แวร์บนลีนุกซ์“, มหาวิทยาลัยขอนแก่น, สิงหาคม 2546
  2. G. V. Vaughan, B. Elliston, T. Tromey and I. L. Taylor, “GNU Autoconf, Automake, and Libtools“, http://sources.redhat.com/autobook/

ใช้ 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)