busybox 的 mdev

mdev 實際上算是 udev 的替代品,代碼看起來很簡單。
下 mdev -s 會 enumerate /sys/class 下的檔案,並據此去建立 /dev 下的 device 檔案。如果 /etc 下有 mdev.conf,它會先參考這裡的設定,來決定 device 的 permission 與 user/group owner。
雖然說是 /sys/class,但是 /sys/class 下的檔案實際上都是 symbolic link,指向 /sys/device 下的檔案。
也可以下這行

echo /sbin/mdev > /proc/sys/kernel/hotplug

,直接讓 kernel detect 到新裝置時,就請 /sbin/mdev 去 /dev 建立新的 device 檔案。
kernel 是怎麼傳遞資訊給 mdev 的呢?答案是透過環境變數,kernel 在執行 /sbin/mdev 之前,會先填好 ACTION、DEVPATH跟SUBSYSTEM 這3個環境變數之後,再去呼叫,所以 mdev 才會知道要做些什麼。這也就是在 shell 下輸入 /sbin/mdev 會印出使用說明的原因,因為沒有這3個環境變數,mdev 就只印出說明了。
kernel mode 下的呼叫,還牽涉到 FIRMWARE 的部份,不過這邊目前沒用到,只有大致看一下。大底來說,就是如果有 FIRMWARE 環境變數時,他會試著去讀取 /lib/firmware/xxx 的 firmware 檔案內容,然後檢查 /sys/$dev/loading 這檔案,有了這檔案以後,再寫入 1,接著再把讀到的內容寫到 /sys/$dev/data 這個檔案裡去,完成載入外部 firmware 的動作。
程式相當的精簡,有空再來看看 udev。

initrd+busybox

kernel source 的 Documentation/initrd.txt 裡,把 initrd 、開機順序跟必要的程序講的很清楚,依法施為,大致就沒問題了。

雖然如此,我還是花了快一天的時間。這邊紀錄一下我的作法,我是用文件裡提到的 loop device 方法,也就是先用 dd if=/dev/zero of=initrd bs=4M count=1 製作出 initrd,再用 mke2fs 格式化,接著用 mount -o loop 把這檔案掛為檔案系統。

然後我 build BusyBox,參考 BusyBox 原始碼的 examples/bootfloppy/mkdevs.sh 裡的 code,把我要的 device 都建起來,然後把 BusyBox 的相關檔案放進去,再把 examples/boot/floopy/etc 放進去。接著修改 etc/init.d/rcS, etc/fstab, etc/inittab,調整成我要的樣子以後,就差不多了。

因為這份 initrd 在開機後,我就拋棄了,所以 etc/init.d/rcS 最後得掛上真正的 device,並且切換過去:

# mount your device to /newroot.
mkdir /newroot
mount -t ext3 /dev/your_device /newroot
cd /newroot
mkdir /initrd
/sbin/pivot_root . initrd
exec /usr/sbin/chroot . /init </dev/console >/dev/console 2>&1

最後,umount,再用 gzip -9 壓縮得到 initrd.gz 之後,大致上就是這樣子。

xargs

以前就看過 xargs 這指令了,不過那時只有看人家的範例,沒有理解為什麼要這樣用。等到想試著用的時候,才發現原來是這樣子。
因為我之前完全誤解了。
舉例來說,這樣的命令:

ls | xargs echo

假設我目前目錄有 file0, file1, file2 這3個檔案,我以為 xargs 會根據 stdin,執行 echo 三次,這當然是錯誤的。
xargs 會讀取 stdin 的內容,然後轉成以空白分格的字串,再將結果作為指定命令的參數。所以上面最後會執行的指令其實是:

echo file0 file1 file2

用 bash source 時,出現 “file not found”

今天遇到很鳥的問題。
情境是這樣的:目前的目錄下有 .config,而 scripts 目錄下有個 shell script ,名稱是 Configure。Configure 的內容很簡單,就是 source .config。接著,在目前的目錄下輸入 sh scripts/Configure,你就會遇到 “.config: file not found” 的訊息。
試了好久,雖然知道可以用 bash 執行來解決,但是就是覺得奇怪,因為 9.04 的 bash 3.2 是沒問題的,但到了 9.10 的 bash 4.0 就不行了。
最後在這裡:Re: source command differs if in bash or sh mode 找到答案:

This is a property of bash posix mode when you don’t have `.’ in $PATH:
28. The `.’ and `source’ builtins do not search the current directory
for the filename argument if it is not found by searching `PATH’.
> This behavior is new in version 4, old version 3.2 works fine.
The bash-3.2 behavior was a bug. Its fix is listed in CHANGES:
ggg. Fixed a bug that caused a shell running in Posix mode to search $PWD for
a file specified as an argument to source/. when the file was not found
in $PATH.

對,這是 bug,bash 3.2 沒問題,是因為他是 bug,4.0 的時候修正了,所以就有問題了,你必須要在 PATH 裡加入 . 才行。
好鳥。

gwibber 的 spell 問題

如果你用 gwibber 時,碰到下面錯誤的話,這是因為沒有中文的 aspell 資料檔的關係:

File "/usr/lib/python2.6/dist-packages/gwibber/gwui.py", line 455, in __init__
self.spell = gtkspell.Spell(self, None)
glib.GError: enchant error for language: zh_TW.UTF-8

解法很簡單,修改 /usr/lib/python2.6/dist-packages/gwibber/gwui.py 把 455 行的前後加上 exception handling 即可:

try:
self.spell = gtkspell.Spell( self, None )
except:
pass

修改時要注意縮排問題,python 對這點可是很講究的!

解決 opera 10 不能用 ibus 問題

環境:
Ubuntu 9.10
Opera 10
輸入法:ibus
解決方法:
編輯 /usr/bin/opera,在 OPERA_BINARYDIR 之下加上

export QT_IM_MODULE=XIM

,然後重新啟動就行了。

grub 從不是第1個硬碟開機

我承認,這標題下的很爛,但一時也想不到更好的。

情況是這樣的,我第一個硬碟已經裝了 Linux,這時候我卻想裝 Windows,是故,我只能裝在第二個硬碟上。Windows 非常機車,如果第一個硬碟沒有 NTFS 的 partition 是不給你裝的。這時候只能先拔第一個硬碟的電源,把 Windows 裝到第二個硬碟上之後,再重新把第一個硬碟的電源裝回去。

接下來,因為不想老是在 BIOS 裡切換開機順序,所以把腦筋動到 grub 上。根據 grub 的 manual,只要利用 map 就行了,但我還是試了好一陣子,後來才發現是順序的問題,我試的時候把 map 放到最前面去了。正確的順序是這樣的:

title		Windows XP
root		(hd1,0)
makeactive
map (hd0) (hd1)
map (hd1) (hd0)
chainloader	+1

這樣就可以不用在 BIOS 裡切換開機順序了。如果你不是用第二個硬碟,而是第3個或第四個硬碟,只要類推為 hd2、hd3 即可。

wine 的選單

我用的是 Ubuntu。
用 wine 安裝程式以後,Wine 選單裡會多出該程式的項目,但移除程式以後,這些項目還存在,即便你之前有備份 .wine,將備份檔案回存了,也不會有用。關鍵在於 wine 其實是把這些選單項目放在 $HOME/.config/menus/applications-merged 下,所以只要把該刪除的項目從這個資料夾下刪除即可。
2009/10/14 補充:$HOME/.local/share/applications/wine/Programs 下的也要記得刪掉,否則會出現在”其他”選單裡…

Mustek Bearpaw 1200TA in Ubuntu

如果你正好用的掃描器跟我一樣是 Mustek BearPaw 1200TA 或者是開啟 xsane 遇到 gt68xx:libusb 錯誤時,你可以試著到這裡:SANE GT68xx Backend Homepage 去下載適當的 .usb 檔案。下載以後,把它複製到 /usr/share/sane/gt68xx 目錄下,變更權限為 a+r,然後重新開啟 xsane,這樣就能正常使用掃描器了。

在 Ubuntu 9.04 使用 svk 出現 Can’t locate Time/Progress.pm

在公司正想用 svk 把 monodevelop source code 拉回來時,發現有 Can’t locate Time/Progress.pm 訊息,然後就停止運行了。
Launchpad 找了一下,發現已經有人回報了:Bug #317487 in svk (Ubuntu): “2.2.1 needs Time::Progress”,後續的回覆裡,也提供了好幾個 workaround,我選擇直接修改 Notify.pm,因為以後 apt-get upgrade 時,新檔案會把舊檔案覆蓋掉。