站長新書 站長開講 首頁 最新文章 站長著作及審校 FreeBSD 筆記 Linux 筆記 Windows 筆記 虛擬化筆記 網管人雜誌 遊山玩水 關於本站
站長新書 VMware vSphere ICM 團購開跑了!!

Kernel-編輯適合您的核心

前言

FreeBSD 安裝完成後所使用的核心為通用核心 (GENERIC KERNEL),但裡面其實有許多我們用不到的驅動程式 (例如 Wireless Card Driver...etc),所以我們可依不同的主機硬體來修改核心,讓核心更符合我們的硬體也讓系統效能更好、開機更快。

實作環境

安裝及設定

步驟1.複製 GENERIC

在 /usr/src/sys/i386/conf 目錄內 GENERIC 為通用核心、NOTES 為完整的核心及說明、LINT 則是所有核心能使用的參數 (需自行編譯產生)

我們可利用 make 指令來產生 LINT 檔

 #cd /usr/src/sys/i386/conf 
 #make LINT
 cat ../../conf/NOTES NOTES | sed -E -n -f ../../conf/makeLINT.sed > LINT

複製通用核心 (GENERIC KERNEL) 來進行修改

 #cd /usr/src/sys/i386/conf
 #cp GENERIC /etc/newkernel       //複製一份到 etc 下 
 #ln -s /etc/newkernel            //搞個連結吧 (重新 cvsup 就知有差了)

步驟2.修改核心

 #vi /etc/newkernel               //編輯新 kernel   

編輯 kernle 中請注意,下列五項不可註解掉,否則在編譯核心的過程中可能會出現錯誤

 ident                            //修改為新 kernel 的名字
 device   isa                     //ISA 匯流排
 device   scbus                   //SCSI 匯流排 
 device   miibus                  //MII 匯流排 (有線網卡支援)
 device   wlan                    //無線網卡支援

步驟3.編譯核心

在編譯核心 (Compile kernel) 之前我們先去修改 make.conf 檔案,讓系統知道我們使用的新的核心 (適合我們機器的核心) 檔案名稱,否則屆時系統會去抓預設的通用核心 (GENERIC KERNEL) 來進行編譯

 #vi /etc/make.conf 
 KERNCONF=newkernel                      //加入此行 (newkernel 為新核心的檔案名稱)

開始編譯核心,下列的 make kernel 指令等於是 make buildkernel 加上 make installkernel,如果你的機器夠強的話你還可加上參數 -j (ex. -j8) 來加快編譯速度,但前提是你的機器必須夠強 (請自行測試適合您機器的參數值)。

 #cd /usr/src
 #make kernel                            //開始編譯核心 (多執行序編譯核心 make -j8 kernel)
 #rm –rf /usr/obj/usr/src/sys/newkernel //清除編譯過程中產生的檔案

當編譯失敗無法開機的處理

  1. 首先先要去尋找錯誤訊息
  2. 在開機過程中,當倒數 10 秒時按 ENTER 會直接開機的地方,此時按下空白鍵 (只要不是 Enter 即可) 便會進入所謂的使用者模式,開機完後再去把先前 newkernel 錯誤的地方改掉,再去照上面的步驟重新編譯 kernel 就可以了。
 boot:?                       //顯示能用的指令 
 boot:lsmod                   //看現在所用的 kernel
 boot:unload                  //將不能開機的 kernel 卸載 
 boot:load kernel.GENERIC     //載入 FreeBSD 預設的 GENERIC kernel 
 boot:boot                    //開機  

忘了 root 密碼

 boot menu選擇 Boot FreeBSD in single user mode
 mount -u /
 mount -a
 passwd root
 Ctrl+D進入系統

如何使核心支援多行程 CPU (SMP / HTT Support)

Pentium 4-XEON or Pentium 4-HT 都算是 SMP,使用新的 ULE 調度器通常可以獲得更好的性能。它是專門為 FreeBSD 在 SMP 上執行而設計的調度器,但在 ULE 系統上也能工作得很好,這兩個調度器必須選擇一個否則編譯 kernel 時會失敗

 #options     SCHED_4BSD             # 4BSD scheduler (預設值,我把此行 Mark 掉)
 options     SCHED_ULE               # ULE scheduler
 device      apic                    # I/O APIC
 # To make an SMP kernel, the next line is needed
 options     SMP                     # Symmetric MultiProcessor Kernel
 # Optional:
 options     MPTABLE_FORCE_HTT       # Enable HTT CPUs with the MP Table
 options     IPI_PREEMPTION

以我這台機器為例 (HP XW4300 WorkStation P4 HT) 我加上這幾行後 make kernel,重開機後 dmesg 可發現 cpu 是二顆了(記得 BIOS HT 功能要打開)

 FreeBSD/SMP: Multiprocessor System Detected: 2 CPUs
 cpu0 (BSP): APIC ID:  0
 cpu1 (AP): APIC ID:   1

或使用 sysctl 指令來查看

 #sysctl -a |grep cpu
 kern.threads.virtual_cpu: 2    //表示已支援 HT 功能
 kern.smp.cpus: 2               //表示系統認為有二顆 CPUs

參考

[FreeBSD 使用手冊]

[twbsd.org - FreeBSD 6.0 架設管理與應用-第八章 編譯核心]

Me FAQ

Q1.make kernel出現錯誤訊息 undefined reference to `ieee80211_watchdog'?

Error Message:

修改核心檔之後編譯核心卻出現如下錯誤訊息

 if_ural.o(.text+0x19c4): In function `ural_watchdog':
 /usr/src/sys/dev/usb/if_ural.c:1370: undefined reference to `ieee80211_watchdog'
 if_ural.o(.text+0x1ad2): In function `ural_ioctl':
 /usr/src/sys/dev/usb/if_ural.c:1417: undefined reference to `ieee80211_ioctl'
 if_ural.o(.text+0x1f58): In function `ural_set_chan':
 /usr/src/sys/dev/usb/if_ural.c:1606: undefined reference to `ieee80211_chan2ieee'
 *** Error code 1
 Stop in /usr/obj/usr/src/sys/mykernel.
 *** Error code 1
 Stop in /usr/src.
 *** Error code 1
 Stop in /usr/src. 

Ans:

找了 google 後發現這也有人回報出現這個錯誤訊息[FreeBSD 6 non-GENERIC kernel build fails]關鍵句子如下

 You have ural(4) in your kernel, but no wlan(4).The ural(4) manual says that wlan(4) is required. 

就試試說的方法把 wlan 這行 mark 拿掉在重新編譯一次核心並順利編譯成功

 device          wlan            # 802.11 support

Q2.make kernel 出現錯誤訊息 objcopy --only-keep-debug if_zyd.ko.debug if_zyd.ko.symbols?

Error Message:

修改核心檔之後編譯核心卻出現如下錯誤訊息

 /usr/src/sys/modules/zyd/../../dev/usb/if_zyd.c
 ld  -d -warn-common -r -d -o if_zyd.kld if_zyd.o
 :> export_syms
 awk -f /usr/src/sys/modules/zyd/../../conf/kmod_syms.awk if_zyd.kld  export_syms | xargs -J% objcopy % if_zyd.kld
 ld -Bshareable  -d -warn-common -o if_zyd.ko.debug if_zyd.kld
 objcopy --only-keep-debug if_zyd.ko.debug if_zyd.ko.symbols
 objcopy --strip-debug --add-gnu-debuglink=if_zyd.ko.symbols if_zyd.ko.debug if_zyd.ko
 1 error
 *** Error code 2
 1 error
 *** Error code 2

Ans:

若您有使用 -j 參數來加快編譯核心請移除此參數後再次進行編譯核心即可,詳細內容請參考 [Fail to compile kernel in Freebsd 7.0 R - The FreeBSD Forums]

 #make -j4 kernel              //出現錯誤訊息
 #make kernel                  //順利編譯核心

Q3.make kernel出現錯誤訊息 undefined reference to `ieee80211_amrr_node_init'?

Error Message:

修改核心檔之後編譯核心卻出現如下錯誤訊息

 linking kernel.debug
 if_ural.o(.text+0xeb0): In function `ural_attach':
 /usr/src/sys/dev/usb/if_ural.c:515: undefined reference to `ieee80211_amrr_init'
 if_ural.o(.text+0x2b89): In function `ural_amrr_update':
 /usr/src/sys/dev/usb/if_ural.c:2508: undefined reference to `ieee80211_amrr_choose'
 if_ural.o(.text+0x32bc): In function `ural_task':
 /usr/src/sys/dev/usb/if_ural.c:2450: undefined reference to `ieee80211_amrr_node_init'
 if_rum.o(.text+0x149b): In function `rum_attach':
 /usr/src/sys/dev/usb/if_rum.c:554: undefined reference to `ieee80211_amrr_init'
 if_rum.o(.text+0x2e07): In function `rum_amrr_update':
 /usr/src/sys/dev/usb/if_rum.c:2423: undefined reference to `ieee80211_amrr_choose'
 if_rum.o(.text+0x315f): In function `rum_task':
 /usr/src/sys/dev/usb/if_rum.c:2366: undefined reference to `ieee80211_amrr_node_init'
 *** Error code 1
 Stop in /usr/obj/usr/src/sys/DELL1950.
 *** Error code 1
 Stop in /usr/src.
 *** Error code 1
 Stop in /usr/src.

Ans:

本次解決方式為,將支援 Wireless (IEEE 802.11) 相關項目編入核心 (沒有註解掉) 即可成功編譯,詳細內容請參考 [kern/121292: FreeBSD-7.0 kernel build fails on FreeBSD-6.3]

 device          wlan            # 802.11 support
 device          wlan_wep        # 802.11 WEP support
 device          wlan_ccmp       # 802.11 CCMP support
 device          wlan_tkip       # 802.11 TKIP support
 device          wlan_amrr       # AMRR transmit rate control algorithm
 device          wlan_scan_ap    # 802.11 AP mode scanning
 device          wlan_scan_sta   # 802.11 STA mode scanning
Go To Oddmuse OrgGo To FreeBSD OrgCreative Commons 2.5 Taiwansitestates.com