2013年1月24日 星期四




如何在ubuntu中compile kernel(12.10)


我老師曾告訴我,在他那個年代Compile kernel是一件常常做的事;今天,主流Linux發行版(如ubuntu, fedora)都是每半年就更新一次,除非真的需要最新driver而該driver只在最新kernel才有而且連等幾個月的時間也沒有,否則最長只要等半年,就可以用上update的kernel,應該已經很少需要再自己compile kernel了。

既然大部分人已不再需要自己compile kernel,那為甚麼今天我要親手compile呢?話說大學的作業系統課有個加分作業,需要在linux kernel中加入system call,為了這5分,我必須自己compile kernel,於是,就有了這篇教學。

要在Debian架構的Linux(如Ubuntu)中 compile kernel其實不難,compile完成後就已經是.deb檔,直接安裝即可,最麻煩的,好可能只是compile時CPU風扇的翁翁聲。

要compile kernel,當然要先下載source code。我是到kernel.org下載,當然你也可以使用git,Debian系列還有一招叫apt-get,不過apt-get得到的通常都不是最新版。無論你是用那個方法,先去下載kernel source code 吧。

下載完成後,我把它放到桌面(~/Desktop),你可以把它放在其他地方。


  • 首先解壓:
    cd ~/Desktop
    tar xvjf linux-3.7.2.tar.bz2
  • 為方便,再建立一個soft link:
    ln -s linux-3.7.2 linux
  • 安裝會用到的套件:
    sudo apt-get install fakeroot build-essential kernel-package libncurses5 libncurses5-dev
  • 把現時kernel的config複製出來:
    cd ~/Desktop/linux
    cp /boot/config-`uname -r` ./.config
    make menuconfig
  • 進入這個畫面,選擇Load an Alternate Configuration File

    剛才已把復製過來的config file改名成.config,所以直接enter即可

    然後,回到剛才那個menu,按兩下Esc再選Yes,把新的.config儲存。

    准備好,真的去compile kernel了:
    make-kpkg clean
    fakeroot make-kpkg --initrd kernel_image kernel_headers
    
    接著,便是漫長的等待,你可以做其他事了,例如去洗個澡、睡個覺、上個Facebook、給我一個讚…

    (PS: 對多核心處理器,可以加入-j [邏輯核心數] 參數加速compile,以及最好不要在virtual machine裏compile,否則好可能會像我這樣,一台i5-460M (Dual-core 2.4GHz) CPU notebook,晚上23:58開始編譯,卻到凌晨3:30睡覺前還未完成!後來我再compile 64bit時用回host並配合-j 8參數,兩小時就完成)


  • 經過漫長的等待,終於compile完成了!立即把它們安裝:
    sudo dpkg -i linux-image-3.7.2_3.7.2-10.00.Custom_i386.deb
    sudo dpkg -i linux-headers-3.7.2_3.7.2-10.00.Custom_i386.deb
    
  • 然後是reboot。

    成功重新開機後,檢查是否這是否已經是你的新kernel:
    uname -a
    
    3.7.2,太好了!!!
    恭喜,你現在使用的,就是自己compile出來的新kernel了。

    11 則留言:

    1. cd ~/Desktop/linux
      cp /boot/config-`uname -r` ./.config
      make menuconifg
      我做完這個步驟之後是顯示一大推要選擇N/y/?的语句,做出選擇後還是要做選擇,這是怎麼回事呢?並沒有顯示你所說的畫面喔,還是畫面是要自己按某個地方按進去的?

      回覆刪除
      回覆
      1. 沒出現畫面不是你指令有打錯就是相依的套件沒裝對,其實這篇作者在做的事情不需要去用到menuconfig,該動作目的是去讀取舊的設定檔,再按照新版的差異把設定寫進去,但沒有要手動進行微調的話用menuconfig只是額外增加相依性,而且步驟上更麻煩,直接用make olddefconfig就可以了,這樣會自動去讀舊的(.config)設定檔,新版多出來的選項採用預設值

        刪除
      2. 是打錯指令,謝謝!不過我compile完成后輸入sudo dpkg -i linux-image-3.6.0_3.6.0-10.00.Custom_i386.deb(我用的是3.6.0版)顯示的是
        dpkg:error processing linux-image-3.6.0_3,6,0-10.00.Custom_i386.deb(--install):
        cannot access archive:No such file or directory
        Errors were encountered while processing:
        linux-image-3.6.0_3.6.0-10.00.Custom_i386.deb
        是怎么回事呢?

        刪除
      3. 我手動安裝好了,不過前面的都沒錯,結果還是無法調出systemcall,這是怎麼回事呢?

        刪除
      4. system call似乎有bug,第一次運行程式看不到的,運行第二次才能看到

        刪除
      5. 請問一下為什麼@@我使用 make menuconfig 後跳出視窗
        可是我找不到Load an Alternate Configuration File
        我的最後一個是library routines

        刪除
    2. 打錯字囉,不是make menuconifg,而是make menuconfig

      回覆刪除
    3. 想問一下為什麼照著流程build完之後重開機版本還是沒改變?

      回覆刪除
      回覆
      1. 可能是沒有成功安裝到,或者開機時使用了舊版本的 kernel 去啟動

        刪除
    4. 搭配上其他網頁的教程成功compile!
      不得不說中文的手把手教程看得真是心曠神怡 <3

      回覆刪除