編譯Linux內核


下面的實驗以 debian7.5 64bit 為例.

獲取源碼

獲取 debian7.5 本身的源碼非常簡單:

sudo apt-get install linux-source

https://www.kernel.org/ 的git上提供的源碼分支非常多, 剛開始學習源碼主要關注下面幾個分支:

  1. linus分支: https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/
    linux創始人的分支, 不用說肯定最重要, 它是所有分支的根源. 處於 "mainline" 的地位.
    這個分支還有個好聽的名字 – "vanilla(香草)" 內核.
  2. linux-next樹: https://git.kernel.org/cgit/linux/kernel/git/next/linux-next.git/
    這個一個為發布將來的版本而積累新代碼並進行測試的源碼樹.
    由 Stephen Rothwell 等人進行管理和維護
  3. stable樹: https://git.kernel.org/cgit/linux/kernel/git/stable/linux-stable.git/
    這是一個主要針對過去發布的內核版本進行bug修改, 使其更加穩定的樹.
    由 Greg Kroah-Hartman, Chris Wright 進行管理和維護.
    針對某個Linus樹的穩定版維護一般持續6個月左右, 也有更持久的.

上面的列出的git樹中都可以獲取想要的源碼.

編譯內核

其實編譯內核和編譯普通軟件也沒多大區別, 只是內核編譯的參數非常之多.
下面就來先看看如何設置內核編譯參數

內核編譯選項

  1. 編譯選項個數
    內核的編譯選項的個數非常多, v2.6.38的內核中就有 12 000 個左右的設置選項(這是包含所有arch的配置選項).
    內核編譯選項不僅多, 有些編譯選項之間還存在依賴關系, 所以手動設置編譯選項幾乎是不可能的.
    值得慶幸的是, 只要知道自己需要設置的那些選項, 就可以使用 make ***config 來進行設置, 它還會自動處理依賴關系.

  2. 配置編譯選項:
    設置內核編譯選項是通過 kconfig 這個工具來完成的.
    kconfig 的源碼就是內核代碼中 script/kconfig 目錄下

    各個編譯選項的選擇有3種方式:

    1. =y :: 直接編譯到內核中
    2. =m :: 以模塊方式編譯到內核中
    3. 不設置 :: 不編譯

    編譯方法:

    1. make menuconfig :: 源碼根目錄下生成 .config (沒有會自動生成), .config中就是各個內核編譯選項的選擇狀況.
    2. make defconfig :: 根據當前系統的架構默認 .config 生成內核源碼目錄下的 .config (每個架構的配置文件: ex. arch/x86/configs/x86_64_defconfig)
    3. make oldconfig :: 將已有的 .config 放到源碼根目錄下后執行, 目的是為了復用之前的內核編譯選項的配置.
    4. make xconfig :: 圖形化配置, 需要qt3, 個人覺得沒有必要, 有 make menuconfig 就足夠了.
    5. make localmodconfig :: 生成以正在使用的內核模塊為對象的 .config

編譯

編譯很簡單, 內核編譯選項設置好之后, 只需簡單的命令 make, 就可以編譯了.
由於內核代碼的龐大, 所以和一般應用程序相比, 編譯時間會很長. 可以嘗試以下方法來加快編譯速度:

  1. 不用的驅動程序都不要設置, 這樣就不會編譯

  2. 利用make的 -j 選項來並發編譯, ex. make -j N (N是並發數). 如果你的機器有2個CPU, 可以用 make -j 2 來提高編譯速度

  3. 使用 make localmodconfig 來生成僅以正在使用的內核模塊為對象的 .config (一般這樣生成的.config中包含的內核模塊最少, 所以編譯速度快)

  4. 編譯時間比較: 測試環境 - debian v7.5虛擬機(cpu: 單核, 內存: 512MB)

.config生成 make時間 生成的modules 備注
make menuconfig 1小時13分41秒 3052個.ko, 共1.2GB 默認配置, 什么也不選擇
make localmodconfig 19分36秒 337 個.ko, 共176MB  

modules 是通過 make modules_install 之后, 在 /lib/modules 中根據編譯內核版本號來查看的
查看有多少個 .ko 文件的方法:

cd /lib/modules/3.2.60
find . -name '*.ko' | wc -l

分開編譯

模塊和內核不在一起的編譯, 就是在現有的內核中追加一些內核模塊時, 不需要將內核也重新編譯.
模塊分開編譯的方法很簡單, 參考之前的博客: 《Linux內核設計與實現》讀書筆記(六)- 內核數據結構 這篇博客中的例子就是和內核分開編譯的模塊.

交叉編譯

交叉編譯就是在當前平台上編譯其他平台上的內核二進制映像, 比如在 x86_64 平台上編譯 arm 的內核映像.
交叉編譯需要目標平台的交叉編譯器. 編譯時主要是 ARCH 和 CROSS_COMPILE 2個變量的設置.

下面舉個交叉編譯 ARM 的例子: 公司用的制作 Cubieboard 板子上的image中的一段編譯內核的代碼

make -C ${CB_KSRC_DIR} O=${CB_KBUILD_DIR} ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- kernel_defconfig
make -C ${CB_KSRC_DIR} O=${CB_KBUILD_DIR} ARCH=arm CROSS_COMPILE=arm-linux-gnueabi- -j4 INSTALL_MOD_PATH=${CB_TARGET_DIR} uImage modules

上述 第一行 是編譯內核源碼. 第二行 是創建 uImage 格式的內核映像以及創建內核模塊
最終在 INSTALL_MOD_PATH 生成的內核模塊可以直接拷貝到 arm機器上使用.

生成內核包

debian 系 linux下生成 內核源碼包的方法

make deb-pkg

安裝內核

make modules_install (安裝內核模塊到 /lib/modules 下)
make install (安裝內核二進制映像, 生成並安裝boot初始化文件系統映像文件)

卸載內核

  1. 刪除/lib/modules/目錄下不需要的內核庫文件
  2. 刪除/usr/src/kernel/目錄下不需要的內核源碼
  3. 刪除/boot目錄下啟動的核心檔案禾內核映像
  4. 更改grub的配置,刪除不需要的內核啟動列表

內核 Makefile 中一些有用的 target

  1. make help : 內核Makefile中的各種 target
  2. make cscope : 生成 cscope 文件
  3. make tags/TAGS : tags可用於vim, TAGS可用於emacs


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM