原文地址:http://hi.baidu.com/icc_fuzhou/blog/item/f27869864ded2f3966096ed6.html
一、內(nèi)核編譯
1、準(zhǔn)備工作
(1)整理出系統(tǒng)需要支持的硬件、文件系統(tǒng)類型以及網(wǎng)絡(luò)協(xié)議等內(nèi)容。
(2)建議用命令uname –r 查看一下系統(tǒng)的版本號(hào),如果你的系統(tǒng)版本與將要編譯的內(nèi)核版本一致,建議將/lib/modules下的內(nèi)容備份,否則將來的make modules_install 步驟產(chǎn)生的文件會(huì)覆蓋這個(gè)路徑下的內(nèi)容。
(3)下載并解壓linux內(nèi)核,建議從http://www.kernel.org/pub/linux/kernel/下載內(nèi)核,因?yàn)榘惭b系統(tǒng)時(shí)所安裝的源代碼默認(rèn)情況下支持很多設(shè)備,這樣給內(nèi)核裁減增加了難度。以下假設(shè)你已經(jīng)下載了內(nèi)核的為linux-x-y-z.tar.gz。一般都將linux內(nèi)核源代碼放在/usr/src下,這里仍然遵守這個(gè)習(xí)慣,如果你的這個(gè)路徑下已經(jīng)存在這個(gè)版本的內(nèi)核,建議將已有的改個(gè)名稱。
2、開始編譯
(1)make mrproper
確保源代碼目錄下沒有不正確的.o文件和文件依賴關(guān)系,執(zhí)行該命令后,內(nèi)核選項(xiàng)會(huì)回到默認(rèn)的狀態(tài)下。如果你是下載的內(nèi)核源碼,而且是第一次編譯,就沒有必要執(zhí)行這一步操作
(2)make menuconfig
以文本菜單方式選擇內(nèi)核選項(xiàng)(與它功能相同的命令還有make config;makexconfig;makeoldconfig),不同版本的內(nèi)核,選項(xiàng)可能會(huì)有一些差異。這一步是內(nèi)核編譯的關(guān)鍵,根據(jù)需要支持的硬件、文件系統(tǒng)和協(xié)議等內(nèi)容,選擇不同的選項(xiàng)。配置選項(xiàng)時(shí),有三種選擇方式,它們代表的含義如下:
Y-將該功能編譯進(jìn)內(nèi)核
N-不添加功能
M-將該功能編譯成模塊,在需要時(shí)動(dòng)態(tài)加載到內(nèi)核
選擇的原則是與內(nèi)核關(guān)心緊密而且經(jīng)常使用的部分功能代碼直接編譯到內(nèi)核中;將與內(nèi)核系較遠(yuǎn)且不經(jīng)常使用的部分功能代碼編譯成為可加載模塊,有利于減小內(nèi)核的長度,減小內(nèi)核消耗的內(nèi)存,簡化該功能相應(yīng)的環(huán)境改變時(shí)對(duì)內(nèi)核的影響;不需要的功能就不要選。
我們使用空格鍵進(jìn)行選取。根據(jù)選項(xiàng)的不同,按下空格鍵的結(jié)果也有所不同:選項(xiàng)后有”―――>”符號(hào)的,進(jìn)入下一級(jí)菜單;選項(xiàng)前有中括號(hào)的,則在空和"*"之間切換;選項(xiàng)前有尖括號(hào)的,在空、"*"和"M"之間切換;選項(xiàng)前有圓括號(hào)的,需要在所提供的幾個(gè)選項(xiàng)中選擇一項(xiàng),或者需要輸入數(shù)值等符號(hào)。咦,什么?要我詳細(xì)介紹具體該怎么選擇這些選項(xiàng)?大汗!這可是個(gè)大問題,需要根據(jù)不同的需求進(jìn)行選擇,比如需要支持USB鍵盤、鼠標(biāo)或/和存儲(chǔ)器,支持多CPU,支持網(wǎng)卡,串口,支持TCP協(xié)議,ext2文件系統(tǒng),nfs文件系統(tǒng)等等。后面我將就內(nèi)核選項(xiàng)做詳細(xì)的介紹。
(3)make dep
根據(jù)上一步所選擇的選項(xiàng),建立文件的依賴關(guān)系。
(4)make clean
清理一些不必要的文件,如果你在上次編譯的基礎(chǔ)上,刪去了一些選項(xiàng),建議你執(zhí)行這一步操作,否則,就沒有必要了。
(5)make bzImage
生成內(nèi)核壓縮文件。如果你確認(rèn)你的內(nèi)核在640K以下,你可以用makezImage來代替 makebzImage。這一步相當(dāng)費(fèi)時(shí),你可以在命令后加上&,讓其在后臺(tái)執(zhí)行,或者重定向到/dev/null中,這樣你就什么也看不見屏幕上閃過不停的字符啦。編譯出的內(nèi)核在 ./arch/i386/boot/ 下,文件名為bzImage
(6)copy "/usr/src/linux/arch/i386/boot/bzImage /boot/vmlinuz-x.y.z
(7)make modules
編譯可加載模塊(即內(nèi)核選項(xiàng)中選擇為M的選項(xiàng)),編譯時(shí)間跟M選項(xiàng)的數(shù)量有關(guān)。
(8)make modules_install
將編譯好的modules拷貝到/lib/modules下,這就是為什么在“準(zhǔn)備工作”的第三步提醒你備份的原因了。
(9)cp /usr/src/linux/System.map /boot/ System-x.y.z.map
3、修改啟動(dòng)配置文件
現(xiàn)在大多數(shù)使用的都是grub啟動(dòng),需要修改/boot/grub/grub.conf,添加相應(yīng)的啟動(dòng)信息,添加內(nèi)容的最簡單格式如下:
title 顯示在啟動(dòng)菜單上的名稱
root 根文件系統(tǒng)掛載分區(qū)
kernel 壓縮過的內(nèi)核文件名
initrd 根文件系統(tǒng)文件名
如:
title My new kernel
root (hd0,2)
kernel /boot/vmlinuz-x.y.z
initrd /boot/initrd-x.y.z.img
二、根文件系統(tǒng)定制
1、 創(chuàng)建一個(gè)全新的根文件系統(tǒng)
你可以用mkinitrd來創(chuàng)建,這里介紹另外一種方式,用dd命令:
# mkdir -p /mnt/initrd
創(chuàng)建一個(gè)設(shè)備點(diǎn),用于臨時(shí)掛載根文件系統(tǒng)。
# cd /tmp
在tmp下創(chuàng)建根文件系統(tǒng)
# dd if=/dev/zero of=/tmp/initrd bs=512 count=40960
創(chuàng)建一個(gè)名為initrd的根文件系統(tǒng),系統(tǒng)每個(gè)塊的大小為512字節(jié),共40960塊。
# mke2fs -F -m 0 initrd
格式化根文件系統(tǒng),其中-F表示強(qiáng)制執(zhí)行;-m 0表示不為系統(tǒng)預(yù)留空間。
# mount -o loop /tmp/initrd /mnt/initrd
掛載根文件系統(tǒng),記住這里要使用-o loop選項(xiàng),否則掛載會(huì)失敗。
# cd /mnt/initrd
2、 創(chuàng)建基本的目錄結(jié)構(gòu)
# mkdir dev proc etc etc/rc.d sbin bin lib mnt tmp var usr
# chmod 755 dev etc etc/rc.d sbin bin lib mnt tmp var usr
# chmod 555 proc
3、 添加設(shè)備
你可以使用mknod創(chuàng)建,也可以從現(xiàn)有的系統(tǒng)中拷貝過來,拷貝的時(shí)候一定要注意,最好使用-dfR,這樣有兩個(gè)好處:
1、拷貝路徑下的所有文件,如果有文件夾,則嵌套拷貝整個(gè)文件夾下的內(nèi)容;
2、保持文件(設(shè)備)的屬性不變。這里采用mknod創(chuàng)建的方式,以下設(shè)備是必須的console、kmem、mem、null、ram0、tty等。
建立一般終端機(jī)設(shè)備
# mknod tty c 5 0
# mkdir console c 5 1
# chmod 666 tty console
建立 VGA Display 虛擬終端機(jī)設(shè)備
# mknod tty1 c 4 0
# chmod 666 tty0
建立 RAM disk 設(shè)備
# mknod ram0 b 1 0
# chmod 600 ram0
建立 null 設(shè)備
# mknod null c 1 3
# chmod 666 null
4、創(chuàng)建配置文件
到這里我們就有了一個(gè)初步的小型根文件系統(tǒng),但是還需要配置一些有關(guān)的 shell script來完善它。在etc下創(chuàng)建最基本的配置文件fstab、inittab、rc.d/rc.sysinit,其中每個(gè)配置文件中至少應(yīng)該包含以下對(duì)應(yīng)的內(nèi)容:
fstab應(yīng)包括:
/proc /proc proc defaults 0 0
inittab應(yīng)包括:
::sysinit:/etc/rc.d/rc.sysinit
::sysinit:/bin/sh(注意,這里如果用getty或minigetty代替sh,那么shell就會(huì)等待用戶登錄,而不會(huì)直接進(jìn)入shell。)
rc.d/rc.sysinit應(yīng)包括:
/bin/mount –a
5、 添加bin、sbin、usr/bin、usr/sbin下的可執(zhí)行文件
系統(tǒng)至少應(yīng)該包含工具sh, ls, cp, mv,init。我們可以將/bin /sbin /usr/bin /usr/sbin下的對(duì)應(yīng)工具拷貝過來,拷貝的時(shí)候采用:
#cp –dfR
系統(tǒng)中的可執(zhí)行文件一般都比較大,在內(nèi)存或磁盤空間緊張的情況下不適合,我們可以用BusyBox來解決這個(gè)問題。BusyBox 包含了七十多種 Linux上標(biāo)準(zhǔn)的工具程序,僅需要幾百k磁盤空間,在嵌入式系統(tǒng)上常用到它。下載了BusyBox的源代碼包后可以按照如下的步驟操作:
DOSTATIC=true然后修改 BusyBox 中的 init.c,設(shè)定系統(tǒng)要執(zhí)行的第一個(gè)程序?yàn)?
/etc/rc.d/rc.sysinit
#define INIT_SRCIPT "/etc/rc.d/rc.sysinit"
開始編譯BusyBox
#make
#make install
到這一步我們就得到了可執(zhí)行命令busybox將busybox 復(fù)制到/mnt/initrd/bin目錄下
# cp busybox /mnt/initrd/bin
然后創(chuàng)建常用命令的link,具體的工作原理請(qǐng)參閱busybox的官方說明。我們可以使用 ./busybox --help 來查看busybox中都有哪些工具。常用的工具及busybox的用法如下:
# ln -s busybox ls
# ln -s busybox cp
# ln -s busybox mount
# ln -s busybox umount
# ln -s busybox more
# ln -s busybox ps
# ln -s busybox sh
現(xiàn)在我們就有了所需的常用命令
6、 添加庫到lib下
該目錄中包含有你的啟動(dòng)盤啟動(dòng)過程中所需要的共享函數(shù)庫,如果缺少必須的函數(shù)庫,系統(tǒng)會(huì)停止啟動(dòng)或出現(xiàn)一大堆錯(cuò)誤信息,所以一定要注意。幾乎所有的程序都需要libc庫,列一下目錄/lib中的libc:
ls -l /lib/libc*
-rwxr-xr-x 1 root root 4016683 Apr 16 18:48 libc-2.1.1.so*
lrwxrwxrwx 1 root root 13 Apr 10 12:25 libc.so.6 -> libc-2.1.1.so*
libc.so.6的6表示版本號(hào),它指向的文件才是你真正需要的。
查看/bin /sbin /usr/bin /sur/sbin下每一個(gè)程序使用的函數(shù)庫,用命令ldd,
如:
ldd /sbin/mke2fs
libext2fs.so.2 => /lib/libext2fs.so.2 (0x40014000)
libcom_err.so.2 => /lib/libcom_err.so.2 (0x40026000)
libuuid.so.1 => /lib/libuuid.so.1 (0x40028000)
libc.so.6 => /lib/libc.so.6 (0x4002c000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
輸出右邊的庫都是必須的,有的可能是鏈接文件。
在/lib目錄下你還必須有函數(shù)庫裝載器,這個(gè)裝載器或是ld.so (對(duì) a.out 庫) 或是ld-linux.so (對(duì) ELF 庫)。新版本的ldd一般會(huì)告訴你所需庫的裝載器。
7、 加載模塊
如果你有一個(gè)模塊化的內(nèi)核,你還得考慮需要加載的模塊,它們都位于/lib/modules 下
cp –dfR /lib/modules/x.y.z /mnt/initrd/lib/modules
8、 打包
# cd /tmp
# umount /mnt/initrd
# gzip -9 initrd
最終產(chǎn)生的文件initrd.gz就是壓縮過的根文件系統(tǒng)
9、 修改已經(jīng)存在的根文件系統(tǒng)
# gunzip initrd.zip
# mount -o loop /tmp/initrd /mnt/initrd
# 用戶修改根文件系統(tǒng)
# umount /mnt/initrd
# gzip -9 initrd
聯(lián)系客服