編譯linux核心

lm_y發表於2017-09-21

一、實驗前的準備:

Vmware + ubuntu10.10 (32位)+ linux-2.6.32.71.tar.xz
安裝虛擬機器教程:http://jingyan.baidu.com/article/90895e0f95a07564ec6b0bc7.html
說明:ubuntu 10.10是我試驗的最後一個,也是最後成功的那個。當然,更推薦ubuntu 10.04,因為這個支援sudo apt-update 少了一些麻煩。 而由於10.10不支援更新,故我另外新下了linux 2.6.32.71 先將這個檔案拖入虛擬機器桌面。

附: ubuntu10.10百度網盤分享:連結:http://pan.baidu.com/s/1bnNr8dD 密碼:ybg3
        linux-2.6.32.71.tar.xz 百度網盤分享:連結:http://pan.baidu.com/s/1c1cOOtq 密碼:epu9

二、解壓核心

1、先開啟安裝好的ubuntu 進入終端 :在桌面按ctrl+alt+T
2、輸入sudo su 獲取root許可權:(會出現一個輸入密碼的一個命令列,在終端輸入密碼時,是不顯示星號的。你只管把密碼輸入回車就行了!用慣了window的小夥伴可能會有些不適應)最後如圖:

3、先把下載好的核心複製到 /usr/src 資料夾中 : 
      終端輸入 cd Desktop(定位到桌面) 回車 ; cp  linux-2.6.32.71.tar.xz  /usr/src 回車
4、解壓核心 依次輸入以下命令回車執行
      cd /usr/src ;
   xz -d linux-2.6.32.71.tar.xz

     tar xvf  linux-2.6.32.71.tar

三、增加系統呼叫

1、

開啟sys.c檔案。

gedit /usr/src/linux-2.6.32.71/kernel/sys.c

2、

在檔案末尾增加系統呼叫。

asmlinkage intsys_mycall(int number)

{

 printk("My Student No. is XXXXX,and My Name is XXXXX*** !");

 return number;

}

注:printk就是系統呼叫輸出一行文字,你可以自定義裡面內容,便於最終檢驗。

3、

 註冊系統呼叫:

gedit /usr/src/linux-2.6.32.71/arch/x86/kernel/syscall_table_32.S

在.long 型別檔案末尾新增:

.longsys_mycall

並且按照順序記住它屬於第幾個系統呼叫,在本機中為337。

4、

gedit /usr/src/linux-2.6.32.71/arch/x86/include/asm/unistd_32.h

在一系列#define __NR_之後新增:

 

# define __NR_mycall 337

在這裡就需要用到之前記住的數字了。


四、編譯核心

ps:深吸一口氣,前面做的只是準備工作!下面才是真正的開始!打好精神,真正的挑戰在下面!
下面的記得一定要一步一步都要做!不要漏掉一步!!!!

進入解壓目錄:

cd /usr/src/linux-2.6.32.71

make mrproper

make clean

make oldconfig

make bzImage  (這個過程和下面的過程非常非常非常長,親測,建議泡杯茶,或是看個電影,沒有兩個小時不行

make modules

make modules_install


五、拷貝核心

經過了漫長的等待,我們終於到了這一步。
先檢驗一下我們的結果:

 


 首先檢視一下編譯好的核心版本,以便命名 開啟 /lib/modules  裡面應該多了一個純數字不帶"generic"的資料夾,那就是新核心版本號,我們的是2.62.32.71 如下所示:

有了這個就代表前面的沒有什麼錯誤了。

接著,就在終端輸入: 

cp /usr/src/linux-2.6.32.71/arch/i386/boot/bzImage  /boot/vmlinuz-2.6.32.71-mykernel


六、建立initrd檔案

mkinitramfs-o /boot/initrd.img-2.6.32.71


七、更新grub引導表

進行到這一步,也許你感覺到自己差不多了,畢竟都這麼久了,你也許有些困了,有些疲憊,但是,我告訴你,最難最容易出錯的,就在當前這一步!建議你先休息一下,下面需要你投入百分之百的注意力去做,若是出錯,你可是要全部重新開始的!
1.

gedit /boot/grub/grub.cfg


2.
在開啟的檔案中找到類似如下的欄位,並複製並貼上在前面:

但必須在同一個

### BEGIN /etc/grub.d/10_linux ### 

       ……  

### END /etc/grub.d/10_linux ###

裡面

欄位如下:
menuentry 'Ubuntu, with Linux 2.6.35-22-generic' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set 0efd72ba-ba85-470f-8c21-ab68730ca8c9
linux /boot/vmlinuz-2.6.35-22-generic root=UUID=0efd72ba-ba85-470f-8c21-ab68730ca8c9 ro   quiet splash
initrd  /boot/initrd.img-2.6.35-22-generic
}
menuentry 'Ubuntu, with Linux 2.6.35-22-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os {
recordfail
insmod part_msdos
insmod ext2
set root='(hd0,msdos1)'
search --no-floppy --fs-uuid --set 0efd72ba-ba85-470f-8c21-ab68730ca8c9
echo 'Loading Linux 2.6.35-22-generic ...'
linux /boot/vmlinuz-2.6.35-22-generic root=UUID=0efd72ba-ba85-470f-8c21-ab68730ca8c9 ro single 
echo 'Loading initial ramdisk ...'
initrd  /boot/initrd.img-2.6.35-22-generic
}


將貼上後欄位裡面的
 linux    /boot/vmlinuz-2.6.35-22-generic      initrd    /boot/initrd.img-2.6.35-22-generic  改成你的核心檔案地址和initrd 地址:
 linux   /boot/vmlinuz-2.6.32.71-mykernel    initrd    /boot/initrd.img-2.6.32.71

這一步特別無聊但又必須認認真真做,要不然你就前功盡棄,別問我怎麼知道的,我要是牢記這句話,不會到四點才睡覺 ( ╯□╰ )!! 建議全部改完之後,檢查幾遍。筆者以及室友們都在這步出錯,以至於不得不重新開始。全部完成如圖所示:

 紅框是改過之後的,籃框裡面的是你需要複製的內容 可以看到 ,兩者在同一個###BEGIN /etc/**** 裡面 黃色下劃線部分
(圖醜見諒)


八、收尾工作

好了,你若已經檢查完畢上面的一切工作,那麼,掃尾工作就開始了,這時候,也莫要放鬆 一步一步來,喝點開水,長呼口氣,一步一步來,下面的一步一步落實:

cd /boot

cp initrd.img-2.6.32.71 initrd-2.6.32.71.old

depmod–a

update-initramfs-k 2.6.32.71 –c

cd /tmp

gzip-dc /boot/initrd.img-2.6.32.71| cpio –id

touch lib/modules/2.6.32.71/modules.dep

find./ | cpio -H newc -o > /boot/initrd.img-2.6.32.71.new

gzip /boot/initrd.img-2.6.32.71.new

cd /boot

mvinitrd.img-2.6.32.71.new.gz initrd.img-2.6.32.71


九、重啟

終於到了驗證結果的一步了,此時你要剋制一下自己的激動心情,在終端鍵入 reboot 點選回車。慢慢等待一會,若是你重啟成功,那麼恭喜你,你已經要看到勝利的曙光啦!
重新進入終端,獲取許可權,過程前面有講,不再重複。在終端鍵入 uname -a 回車
此時若是看到

linux-2.6.32.71,說明已經成功!

如下:

若是看到這個,你就可以大叫一聲慶祝一下了,你已經成功啦!!!!

十、測試自定義系統呼叫

開啟終端,鍵入gedit,開啟gedit工具,繼續鍵入如下程式碼:

#include<stdio.h>

int main()

{

       syscall(337, 1);

       return 0;

}

儲存為mytest.c

再繼續在終端中鍵入

gcc-o mytest mytest.c(編譯C程式)

之後 ./mytest 。

點選執行編譯出來的程式,此時並不會顯示出效果,在終端中鍵入dmesg –c檢視系統呼叫資訊。

此時,你可以看到



說明之前寫的sys_mycall呼叫成功!
到這一步,算是全部成功啦!!慶祝一下,去裝個逼吧~~~~

相關文章