kerneld mini-HOWTO 1.7 版,上次由 Henrik Storner [1](storner@osiris.ping.dk)於 1997 年 7 月 19 日(storner@osiris.ping.dk) 更新。 曾達康 [2](a9504480@graduate.hku.hk) 於 1998 年 6 月 14 日完成翻譯。 _________________________________________________________________ 導言 此文件解釋如何使用 Linux 核心中的 kerneld 功能。它會說明: * [3]kerneld 是什麼 * [4]為什麼要用它 * [5]如何取得所需東西 * [6]如何設定它 * [7]如何告訴 kerneld 它不認識的模組的資料 * [8]如何偵察 kerneld (設定時可能有用) * [9]kerneld 的特別用途 * [10]常見問題及怪事 此文件的最新版本可在 [11]http://eolicom.olicom.dk/~storner/kerneld-mini-HOWTO.html 找到。( 譯按:中文版則可在 [12]http://www.linux.org.tw/CLDP/mini/Kerneld.html 找到)在此 mini-HOWTO 推出的正式版本期間,你可在 [13]http://eolicom.olicom.dk/~storner/kern.html 找到未經組織的更新清單 。 榮譽 如果你發現此文件中出現錯誤,請告訴文章的原作者。以下各人都曾對本文作出 貢獻: * Bjorn Ekwall * Ben Galliart * Cedric Tefft * Brian Miller * James C. Tsiao 我非常感謝此 mini-HOWTO 讀者寄給我們的鼓勵和提議。 (譯按︰當然,如果問題出在譯文中,請通知曾達康 ) _________________________________________________________________ kerneld 是什麼? kerneld 是由 [14]Bjorn Ekwall 引入 1.3 版的發展核心 (development kernel) 的功能。它可在所有 2.0 及 2.1 版本的核心找到。它令模組 (modules)─即驅動程式 (device drivers)、網絡驅動器 (network drivers)、 檔案系統 (filesystems)─自動在有需要時載入,而不需自行使用 modprobe 或 insmod。 還有更有趣的東西,雖然它們尚未整合到標準的核心中︰ * 它可設定成不使用內定的空白畫面,而讓你選擇其他程式,使你可自選螢幕 保護器 (screen saver)。 * 和螢幕保護器相似,你可把主控台 (console) 的‘嗶’聲改為完全不同的東 西… kerneld 包括兩個獨立部分: * 核心向監控程式 (daemon) 就所需模組提出要求的支援。 * 懂找出所需模組來滿足核心要求的使用者層面 (user-level) 監控程式。 要使用 kerneld,兩個部分都要正常運作。只設定好其中一個是沒用的。 _________________________________________________________________ 為什麼要用它? 有不少好理由去使用 kerneld。這裡提出的是我個人的──其他人可能有其他的 理由。 * 如果你要為多個只有少許不同的系統(如使用不同的網絡控制卡)建立核心 ,你只需建立一個核心和數個模組,而不需為每個系統建立不同的核心。 * 對開發人員而言,模組比較容易測試─你不需重新啟動電腦以載入及卸下驅 動程式(這點適用於所有模組,並不限於 kerneld 載入的)。 * 它減少核心佔用的記憶體,即你有更多記憶體供其他程式使用。核心所佔用 的記憶體是 *永不* 被換出 (swap-out) 的,所以如果你的核心中有 100kB 沒用的驅動程式的話,那只是在浪費你的記憶體。 * 有一些我要用的東西,如 ftape floppy-tape driver 或 iBCS,只以模組形 式出現。但我懶得自己載入和卸下它們。 * Linux 發行者不再需要建立 284 個不同的開機影象 (boot images) ─使用 者只載入配合其硬件的驅動程式。例如 RedHat 4.0 就使用了這方法。 當然,你也有不使用它的理由─你可能喜歡在一個核心映象 (kernel image) 中 包括所有你要的驅動程式。如果是這樣,你看錯文章了。 _________________________________________________________________ 如何取得所需東西? 對 kerneld 的支援始於 1.3.57 版。如果你正使用較舊的版本,你需要更新它才 可用 kerneld 了。所有主要的 Linux ftp 台都有核心的原程式碼。我建議你更 新至最新版本的穩定核心,2.0,目前是嵌補等級 (patch level) 2.0.29 (譯按 :現時已是 2.0.35): [15]ftp://sunsite.unc.edu/pub/Linux/kernel/v2.0/linux-2.0.29.tar.gz [16]ftp://tsx-11.mit.edu/pub/linux/sources/system/v2.0/linux-2.0.29.tar.gz [17]ftp://ftp.funet.fi/pub/Linux/PEOPLE/Linus/v2.0/linux-2.0.29.tar.gz 使用者層面的監控程式包含在 modules-1.2.8 及更新的 modules-2.0 中。它們 一般會和核心源程式碼在同一地點找到,而官方位置包括: [18]ftp://sunsite.unc.edu/pub/Linux/kernel/v2.0/modules-2.0.0.tar.gz [19]ftp://tsx-11.mit.edu/pub/linux/sources/sbin/modules-2.0.0.tar.gz [20]ftp://ftp.funet.fi/pub/Linux/tools/modules-2.0.0.tar.gz 注意:如果你想在 2.1 版的開發核心嘗試載入模組,你必須用最新的 modutils-(不是 modules-)。但請看 [21]以下有關模組和 2.1 版核心部分的 問題。 _________________________________________________________________ 如何設定它? 首先要取得所需的東西:合用的核心部分及最新版的 modules-utilities。之後 你要安裝 modules-utilities。十分簡單:只需把原程式碼解壓及執行 make install. 這樣便會編譯 genksysm, insmod, lsmod, modprobe, depmod, kerneld,及把它們安裝到 /sbin。我建議你加數行到你的開機命令手稿 (startup-script) 來完成啟動時所需的設定。如果你使用 Slackware,請把以下 數行加入你的 /etc/rc.d/rc.S 檔,如果你使用 SysVinit,如 Debian, RedHat, Caldera,請把以下數行加入你的 /etc/rc.d/rc.sysinit 檔。(譯按: 據我所知,RedHat 5.0的 SysVinit已加入此功能): # Start kerneld - this should happen very early in the # boot process, certainly BEFORE you run fsck on filesystems # that might need to have disk drivers autoloaded if [ -x /sbin/kerneld ] then /sbin/kerneld fi # Your standard fsck commands go here # And you mount command to mount the root fs read-write # Update kernel-module dependencies file # Your root-fs MUST be mounted read-write by now if [ -x /sbin/depmod ] then /sbin/depmod -a fi 第一部分啟動 kerneld。 第二部分開始時執行 'depmod -a'。depmod 建立所有可找到的模組的清單及分析 它們之間互相依賴的情況。所以,它會知道載入一個模組前是否需要先載入其他 模組。 注意︰最新版本的 kerneld 可選擇鏈結 (link) GNU 的 dbm 程式庫 libgdbm。 如果在編譯 module-utilities 時作了此抉擇,找不到 libgdbm 時 kerneld 便 不能啟動。這很有可能當 /usr 在另一個磁碟分區 (partition),而企圖在掛 (mount) /usr 前啟動 kerneld 時發生。建議的解決方法是把 libgdbm 從 /usr/lib 移到 /lib,或靜態連結 kerneld (link kerneld statically)。 之後,你要把核心的源程式解壓,設定及建立一個你喜歡的核心。如果你未試過 這樣做,你必須閱讀在 Linux 源程式碼頂層目錄 (top directory) 中的 README 檔。在執行 make config 設定核心時,你要注意數條在早期出現的問題 : Enable loadable module support (CONFIG_MODULES) [Y/n/?] Y 你要選擇 loadable module support,否則根本不會有模組讓 kerneld 載入。答 Yes。 Kernel daemon support (CONFIG_KERNELD) [Y/n/?] Y 當然,這也是需要的,很多東西都可建立為模組。你會見到類似的問題: Normal floppy disk support (CONFIG_BLK_DEV_FD) [M/n/y/?] 你可回答 'M' 來代表模組。通常只有開機時必須的驅動程式,如硬碟機驅動程式 ,和根目錄的檔案系統等必需建立在核心中。其他皆可建立為模組。 完成 'make config' 後,執行 'make dep', 'make clean', 'make zImage' 或 'make zlilo', 'make modules' 和 'make modules_install'。 成功! 'make zImage' 會把你的新核心映像 (kernel image) 放到 arch/i386/boot/zImage。你要把它拷貝到你放置啟動映像的地方或用 LILO 安裝 它。 想得到更多有關設定,建立及安裝核心部分的資料,請閱讀定時貼上 comp.os.linux.answers 的[22]Kernel-HOWTO ,你也可在 sunsite.unc.edu 的 /pub/Linux/docs/HOWTO 找到它。(譯按:中文版可在 [23]http://www.linux.org.tw/CLDP/Kernel-HOWTO.html找到。) _________________________________________________________________ 試用 kerneld 現在你可用新的核心部分開機。在系統啟動後,執行 'ps -ax',你應該會見到 kerneld 的一行: PID TTY STAT TIME COMMAND 59 ? S 0:01 /sbin/kerneld kerneld 其中一個好處是只要你有所需的核心及安裝好監控程式,你只需作很少 設定。現在,你可嘗試用一個建立成模組的驅動程式─它多數會不需再作設定而 能使用。我把軟磁碟的驅動程式建立成模組,所以我放入一只 DOS 磁碟及 osiris:~ $ mdir a: Volume in drive A has no label Volume Serial Number is 2E2B-1102 Directory for A:/ binuti~1 gz 1942 02-14-1996 11:35a binutils-2.6.0.6-2.6.0.7.diff.gz libc-5~1 gz 24747 02-14-1996 11:35a libc-5.3.4-5.3.5.diff.gz 2 file(s) 26689 bytes 即是說軟磁碟的驅動程式運作正常─當我嘗試使用軟磁碟時,它被自動載入。 要看到軟磁碟的模組真的被載入,你可執行 /sbin/lsmod,它會列出現時載入了 的模組。 osiris:~ $ /sbin/lsmod Module: #pages: Used by: floppy 11 0 (autoclean) "(autoclean)" 代表如果有一分鐘沒用此模組,它就會被 kerneld 自動移走。所 以,那 11 頁記憶體(44 kB,一頁等於 4kB)只會在我使用軟碟機時被佔用。如 果我一分鐘不用軟碟,它會被釋放。如果你的記憶體不敷應用,這就太棒了! _________________________________________________________________ kerneld 如何知道該載入什麼模組? 雖然 kerneld 本身對常用的模組有所認識,有時它會不知如何應付核心提出的要 求。例如光碟機驅動程式或網絡驅動程式等可能需要超過一個模組的情形。 kerneld 從核心部分會收到以下種類的要求: * [24]區塊設備驅動程式 (a block-device driver) * [25]字元設備驅動程式 (a character-device driver) * [26]二元格式 (a binary format) * [27]tty 連線規則 (a tty line discipline) * [28]檔案系統 (a filesystem) * [29]網絡設備 (a network device) * 網絡服務 (a network service),如 rarp * [30]網絡協定 (a network protocol),如 IPX kerneld 從架構檔案 (configuration file) /etc/conf.modules 中得知有什麼 模組需要載入。這裡有兩類項目:路徑 (paths)(模組檔案的位置)和代號 (aliases)(要載入什麼模組)。如果你未有此檔,你可用以下方法自己製造: /sbin/modprobe -c | grep -v '^path' >/etc/conf.modules 如果你想加多一個路徑到預定路徑中,你必須包括所有現有的路徑。因為在 /etc/conf.modules 裡的一個路徑項目會取代 所有 modprobe 內置的路徑! 通常你是不用自己加上路徑的,因為預設的路行將己照顧到所有正常的設定。我 可保證! 另一方面,如果你只想加入代號 (alias) 或者選項 (option directive),你在 /etc/conf.modules 的新項目會加入到 modprobe 所知的。如果你想再定義一個 代號或選擇,你在 /etc/conf.modules 中的項目會凌駕預設那個。 區塊設備 如果你執行 '/sbin/modprobe -c',你會得到一個 kerneld 已知的模組的名單及 它們所對應的要求。例如,導致載入軟碟驅動程式的要求是主號碼 (major number) 是 2 的區塊設備。 osiris:~ $ /sbin/modprobe -c | grep floppy alias block-major-2 floppy 為什麼是 block-major-2?因為軟碟設備 /dev/fd* 的主號碼 (major number) 是 2 ,又是區塊設備。 osiris:~ $ ls -l /dev/fd0 /dev/fd1 brw-rw-rw- 1 root root 2, 0 Mar 3 1995 /dev/fd0 brw-r--r-- 1 root root 2, 1 Mar 3 1995 /dev/fd1 字元設備 字元設備的方法處理也差不多。例如 ftape floppy tape driver 的是 major-device 27: osiris:~ $ ls -lL /dev/ftape crw-rw---- 1 root disk 27, 0 Jul 18 1994 /dev/ftape 但 kerneld 本身並不知道 ftape 驅動程式,它不會在 '/sbin/modprobe -c' 的 結果中出現。 所以,要使 kerneld 載入 ftape 驅動程式,我要加一行到 kerneld 的設定檔 /etc/conf.modules 中: alias char-major-27 ftape 網絡設備 你也可以用設備的名稱來代替那些 'char-major-xxx' 或 'block-major-yyy' 設 定。這樣對網絡設備尤其有用,例如把 ne2000 網絡卡用作 eth0 可以籍此載入 : alias eth0 ne 如果你需要傳遞一些選項給你的驅動程式,例如告訴模組這網絡卡使用什麼 IRQ ,你可加上如下一 'options' 行: options ne irq=5 這樣會使 kerneld 用以下指令來載入 NE2000 驅動程式︰ /sbin/modprobe ne irq=5 當然,實際上所用的選項會因應所用模組而有所不同。 二元格式 二元格式也以相似的方法處理。每當你嘗試執行一個核心不懂載入的程式 ,kerneld 便會收到一個 "binfmt-xxx" 的要求, xxx 是一個由檔案開頭數個字 元決定的數字。使 kerneld 為 ZMAGIC (a.out) 執行檔載入 binfmt_aout 模組 的設定是: alias binfmt-267 binfmt_aout 因為 ZMAGIC 檔的幻數 (magic number) 是 267。(如果你查看 /etc/magic,你 會見到 0413 這個數字,但 /etc/magic 使用八進位數 (octal numbers) 而 kerneld 使用十進數 (decimal),而八進位的 413 即十進數的 267。)由於 a.out 格式共有三款稍為稍為不同的可執行檔 (NMAGIC, QMAGIC and ZMAGIC), 要全面支援 binfmt_aout 模組我們需要 alias binfmt-264 binfmt_aout # pure executable (NMAGIC) alias binfmt-267 binfmt_aout # demand-paged executable (ZMAGIC) alias binfmt-204 binfmt_aout # demand-paged executable (QMAGIC) kerneld 可自動辨認 a.out, Java 和 iBCS 二元格式,毋須特別設定。 連線規則 (slip, cslip and ppp) 連線規則用 "tty-ldisc-x"來作要求,而 x 一般是 1 (slip) 或 3 (ppp) 。kerneld 本身都認識這兩樣。 說起 ppp,如果你想 kerneld 載入 bsd_comp 資料壓縮模組,你需要加兩行到 /etc/conf.modules 中: alias tty-ldisc-3 bsd_comp alias ppp0 bsd_comp 網絡協定 (IPX, AppleTalk, AX.25) 部分網絡協定也可以模組載入。核心要用到一個網絡家族 (network family)(如 IPX)時,會向 kerneld 作出對一個類似 "net-pf-X" 的要求,而 X 是一個代表 所屬家族的數字。例如 net-pf-3 是 AX.25,net-pf-4 是 IPX,而 net-pf-5 是 AppleTalk。(這些數字是由 linux 源程式檔 include/linux/socket.h 中 AF_AX25, AF_IPX 的定義而來的。)故此要自動載入 IPX 模組,你要加一個類似 以下的項目到 /etc/conf.modules 中: alias net-pf-4 ipx 也請閱讀以下有關防止開機時出現關於未定義的協定的[31]常見問題。 檔案系統 有關檔案系統的 kerneld 要求就是檔案系統的名稱。一個常見的用途是為光碟載 入 isofs 的模組,例如 "iso9660" 檔案系統: alias iso9660 isofs _________________________________________________________________ 需要特別設定的設備 部分設備不只要使用代碼 (aliasing),還要其他設定,如模組的設備 (a device to a module)。 * 主數碼 10 的字元設備:[32]雜項設備 (The miscellaneous devices) * [33]SCSI 設備 * [34]需特別初始化 (initialization) 的設備 char-major-10:滑鼠、看門狗和隨機數 (Mice, watchdogs and randomness) 大多數硬件設備都以主數碼分辨,例如 ftape 是 char-major-27。但如果你看看 在 /dev 中主數碼是 10 的字元設備,你會見到一堆毫無關連的設備,包括: * 各種各樣的滑鼠(bus mice, PS/2 mice) * 看門狗設備 (watchdog devices) * 核心的 'random' 設備 * APM 介面 (Advanced Power Management interface) 很明顯,這些設備是由多個不同的模組控制的。所以,這些雜項設備的 kerneld 設定用到主號碼及副號碼 (the major number and the minor number): alias char-major-10-1 psaux # For PS/2 mouse alias char-major-10-130 wdt # For WDT watchdog 要用到此特性,你需要一個 1.3.82 或之後的核心部分。較舊的核心不會把副號 碼傳給 kerneld,因此,kerneld 不能找出所需要的雜項設備。 載入 SCSI 驅動程式: scsi_hostadapter 項目 SCSI 設備包括一個 SCSI 配接卡 (SCSI host adapter, 例如 Adaptec 1542)及 一個所需設備(如硬碟機 (hard disk)、光碟機 (CD-ROM) 或磁帶機 (tape-drive))的驅動程式。這全都可以模組來載入。但是,當你想存取連接到 Adaptec 卡的光碟機時,核心和 kerneld 只知道它需要載入 sr_mod 模組來支援 那 SCSI 光碟機─它不知道那光碟機連接到什麼 SCSI 控制器 (SCSI controller),所以不知道載入什麼模組來支援那光碟機。 要解決這問題,你可加一個你的 SCSI 驅動程式的項目到你的 /etc/conf.modules 中,籍以告訴 kerneld 如何在眾多 SCSI 控制器模組中選擇 : alias scd0 sr_mod # sr_mod for SCSI CD-ROM's ... alias scsi_hostadapter aha1542 # ... need the Adaptec driver 這只適用於 1.3.82 或之後的核心。 這方法只當你只用一個 SCSI 控制器時適用。如果你有超過一個,難度就高一點 。 一般來說,如果已經載入了一個配接器,你不能再叫 kerneld 載入另一個。你可 把兩個都編譯到核心中(不用模組),或自己把模組載入。 事實上,有一個方法可使 kerneld 載入多個 SCSI 驅動程式。James Tsiao 有以 下提議: 只要你親手建立 modules.dep 的倚賴 (dependency),你可很輕易使 得 kerneld 載入第二個 SCSI 驅動程式。你只需一個類似的項目: /lib/modules/2.0.30/scsi/st.o: /lib/modules/2.0.30/scsi/aha1542.o 來使 kerneld 在載入 st.o 前先載入 aha1542.o。我家中的電腦就使用 了幾乎相同的設定,對我所有二級 SCSI 設備 (secondary scsi devices), 包括磁帶機、光碟機和其他一般的 SCSI 設備都沒問題。缺點是 'depmod -a' 不能自動查出這些倚賴,所以你要自己加入這些,而且不 可在開機時執行 'depmod -a'。但只要設定好了,kerneld 就能自動載入 aha1542.o。 你要知道這技考只當你有不同種類的 SCSI 設備接駁在兩個控制器時才有用,例 如,把硬碟駁在其中一個,而把光碟機、磁帶或其他 SCSI 駁到另一個。 要載入超過一個模組時:“post-install”項目 有時,只把模組載入不足以使設備運作。例如,如果你把音效卡編譯為模組,你 也會希望調整至適當音量。問題題你的設定在下次載入時便會失去。這裡是由 Ben Galliart (bgallia@luc.edu) 提供的秘訣: 最終的解決方法需要安裝 setmix-0.1 ( ftp://sunsite.unc.edu/pub/Linux/apps/sound/mixers/setmix-0.1.tar.gz ) 之後把以下一行加到我的 /etc/conf.modules: post-install sound /usr/local/bin/setmix -f /etc/volume.conf 這樣,當音效的模組載入後,kerneld 會執行 'post-install sound' 項目的指 令。因此該模組會被 '/usr/local/bin/setmix -f /etc/volume.conf 指令設定 好。 這方法對其他模組也有用,例如 lp 模組可籍以下一句用 tunelp 程式設定好: post-install lp tunelp 只有 1.3.69f 版或之後的 kerneld 才支援這些選項。 注意: :此 mini-HOWTO 的較舊版本曾提及一個 "pre-remove" 選項,讓你可在 kerneld 卸下一個模組時執行一個指令。但這從未成功,因此並不鼓勵使用。這 個選項多數會在未來版本的 kerneld 中消失。所有有關模組 "設定" 的事情都在 改變中,在你看到這文件時,可能已有所不同了。 _________________________________________________________________ 偵察 kerneld 如果你什麼方法都已試過,但仍找不出核心在要在 kerneld 做什麼,你可用一個 方法找出 kerneld 收到什麼要求,從而知道該加什麼到 /etc/conf.modules。你 需要 kdstat 程式。 這個好用的程式已包括在 modules-package 中,但預定是不會編譯及安裝的。你 可用以下方法建立它: cd /usr/src/modules-2.0.0/kerneld make kdstat 之後,要使 kerneld 顯示它正在做什麼,執行 kdstat debug kerneld 便會開始在主控台印出其工作的資料。當你執行所需的指令時,你會見 到 kerneld 收到的要求。這些要求可放到 /etc/conf.modules 中,加上所需模 組的別名 (alias),便可使工作完成。 要停止除錯時,執行 '/sbin/kdstat nodebug'。 _________________________________________________________________ kerneld 的特殊用途 我知道你想問如何設定螢幕保護程式 (screensaver) 的模組… modules-package 的 'kerneld/GOODIES' 目錄中有一些和螢幕保護程式及主控台 嗶聲支援有關的核心修補 (kernel patches)。它們尚未在官方的核心出現。所以 你要自行修正及重新編譯核心。 要安裝修補,你要用 "patch" 指令: cd /usr/src/linux patch -s -p1