2008年3月5日 星期三

FlyBook惡搞日誌005

現在來到對硬體加強的時候了。基本上這台Flybook對於硬體的惡搞程度絕對不低於一般正常架構。因此對於各項硬體的驅動是一場混戰。它的強項觸控螢幕沒有驅動、第二強項滑鼠除了是XY相反(在2.6版的核心),所以有另類選擇:外接一隻usb滑鼠。

不過這場戰爭不是我的,因為已經有第一滴血了。更甚者還出現了wiki,未免.....
http://gentoo-wiki.com/HARDWARE_Dialogue_Flybook

修改滑鼠與觸控螢幕支援,不免要對kernel上下其手,因此本文可以順便兼職作為編譯kernel的小指南。

編譯核心的基礎知識其實是LPI level的超基礎知識,但是怎樣把核心編到呱呱叫(按:不就是加音效卡就會叫了?)就有點難度了。

首先我們要完成基本的編譯核心準備,稱為核心補完計畫,記得安裝程式要具有root權限,不然會常駐白宮:

apt-get install linux-source kernel-package build-essential
apt-get install libncurses5 libncurses5-dev ncurses-dev

套件libqt3-mt-dev是準備配合xconfig用的,因為我習慣使用menuconfig的籃底白字介面(by libncurse),所以沒安裝。如果你打算下載新版核心,也可以試著不安裝linux-source kernel-package兩套件。要下載的話可以這樣:

cd /usr/src
wget ftp://www.kernel.org/pub/linux/kernel/v2.6/版本.tar.bz2
tar xjvf 版本.tar.bz2

而習慣上我們會把這個原始碼目錄用連結的方式當成/usr/src/linux,而不用mv

ln -s 版本 linux
cd /usr/src/linux

不過事情沒有這麼美好,首先要對這個核心執行patch。很多初學者光是靠man就能理解patch的過程,那簡直是天才。所以本人充當教官,紀錄一下如何patch。

首先我們看到penmountlpc-20060121.diff,其實這是一個用diff比較程式做出來的差異文件。裡面就明載

diff -c -N -r linux-2.6.15.1/drivers/input/touchscreen/Kconfig \
linux-2.6.15.1-penmountlpc/drivers/input/touchscreen/Kconfig



因此如果你要使用patch < penmountlpc*.diff (內定值為 -p0 ),那麼就會得到「沒有這檔案或目錄」的訊息,除非你剛好也抓到2.6.15.1的核心(這麼巧啊?!)所以我們要減掉一層,用-p1的參數。配合減掉的這一層目錄,也就是/drives目錄,你就要把.diff檔案擺在可以看到drivers目錄的那一目錄,也就是/usr/src/linux。然後執行




patch -p1 < penmountlpc-20060121.diff




此時就會看到螢幕出現己行訊息,有的是patch成功的會出現.orig備份原始檔,有的是失敗而出現.rej檔案。而此案例中會對Makefile檔案產生.rej。不過這不是問題,因為我們可以手動編輯,看到原始.diff檔中紀錄




*** 11,13 ****
--- 11,14 ----
obj-$(CONFIG_TOUCHSCREEN_MTOUCH) += mtouch.o
obj-$(CONFIG_TOUCHSCREEN_MK712) += mk712.o
obj-$(CONFIG_TOUCHSCREEN_HP600) += hp680_ts_input.o
+ obj-$(CONFIG_TOUCHSCREEN_PENMOUNTLPC) += penmountlpc.o



原來是加上一個編譯標的,那就把他自己手動加上去,就OK了。



學會Patch後,接下來你還要學會自己Hack kernel程式碼來解決滑鼠錯亂的情形,建議先備份drivers/input/mouse/psmouse-base.c。根據wiki的指示,將




input_report_rel(dev, REL_X, packet[1] ? (int) packet[1] - (int) ((packet[0] << 4) & 0x100) : 0); 
input_report_rel(dev, REL_Y, packet[2] ? (int) ((packet[0] << 3) & 0x100) - (int) packet[2] : 0);




改為




input_report_rel(dev, REL_X, packet[1] ? (int) ((packet[0] << 4) & 0x100) - (int) packet[1] : 0);

input_report_rel(dev, REL_Y, packet[2] ? (int) packet[2] - (int) ((packet[0] << 3) & 0x100) : 0);




為甚麼選擇hack kernel code這個險路呢?因為原因非常明顯,你不可能在這筆電上換隻PS2滑鼠,或是新增出第二支PS2滑鼠。



然後要製造出.config這個配置檔。通常是先擷取舊系統配置再自行定義。




make oldconfig

make menuconfig || make xconfig




編譯ubuntu核心有個陷阱,就是你要把你根目錄的檔案格式(ext3)內建在核心裡,不然開機時會「大水沖倒龍王廟」的怪事。而對於flybook這台小筆電,其實2.6的核心很多功能是多餘的(即便是Generic),比如說SMT、多處理器、vm等功能,CRUSOE已經爆慢了,還搞什麼虛擬機器。很多不必要的模組也可以關關掉免編譯,如PCI Express Bus支援,請問這麼小台筆電如何加裝PCI Express介面?如何加裝SATA硬碟?或是把onboard ATI Mobility RADEON改成其他高級晶片?或是捨棄內建的8139+網路卡,外接PCMAIA或usb網卡,會這樣做的機率真的很低,真發生的時候再重編也還有救。



不過這些東西最好不要亂拿掉




Compressed ROM File System Support (cramfs)

Ram Disk Support


Initial RAM Disk (initrd)


VGA 16 Color Graphics Suport


Vesa VGA Graphics support


Framebuffer Console Support


Bootsplash Screen




掌握上述要領後,記得存檔就可以進入編譯核心的第二步:編譯



首先是用懶人方法




make-kpkg --initrd kernel_image kernel_headers




就會產生兩個.deb套件,然後用dpkg -i *.deb安裝,就會自動配置完GRUB以及initrd,並且可以用套件管理程式移除。不過本篇並沒有就此打住,因為我們可以走其他險路,比如按照傳統方法手動的編譯:make。



若是純手動make完以後,還要記得安裝modules




make modules_install; ls /lib/modules




然後找到/arch/i386/boot/vmlinuz.bz,將它改名複製到/boot,同時照慣例把.config -> config.VERSION 與System.map -> System.map.VERSION 一起複製到/boot裡面。



幸運的是你可以make help就會發現其實有現成包裝成deb的參數。



如果你有更強力的CPU,你將會發現一件事(或者你應該有概念),其實你可以在雙核心電腦編譯老電腦的核心、打包,丟回老電腦安裝。



這樣沒結束,因為還要製造initrd,不然會開不了機。對於initrd的介紹,我推薦這篇:深入理解 Linux 2.6 的 initramfs 機制。雖然牛頭不對馬嘴,不過根據學習理論,「有比較,有記住。」。不過看完以後,我們還是要回頭繼續用initrd,因為菜嘛。




cd /boot/

mkinitrd -o /boot/initrd.img-kernel_version kernel_version




理論上就會從/lib/modules/kernel_version下面根據/boot/config.kernel_version指示做出initrd.img。當然還有更變態的方法,你可以查看抓下來的/usr/src/linux/Documentation/initrd.txt。你將會看到如何使用cpio、gzip與一堆管線製造出initrd.img的原始方法。



然後手動編輯GRUB




vi /boot/grub/menu.lst




依樣畫葫蘆把新核心開機設定填上去,就可以開機測試。



不過在X裡面用觸控螢幕,並沒有想像中的容易完成。你還要參考wiki下載evtouch版的驅動來湊合著用,然後再手動修改xorg.conf。不過本篇不記載這段。

沒有留言: