linux內核編譯

轉載自:https://blog.csdn.net/qq_34247099/article/details/50949720                                           
寫在前面的話:
本人大二,東南大學一個軟工狗,正在修一門名爲《操作系統原理》的坑爹課!前幾天做一個實驗:編譯Linux內核並向其增加一個系統調用。這個實驗實在是太讓人無語了,各種坑!昨天這個時候,我還在苦苦煎熬中。在今天凌晨四點才做好。爲了讓其他人少走一些彎路,鄙人就把自己的經驗以及教訓寫下來。裏面會有一些不足,希望大家多多指教~

廢話不多說,那就開始吧:
一、實驗前的準備:
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 {recordfailinsmod part_msdosinsmod ext2set root='(hd0,msdos1)'search --no-floppy --fs-uuid --set 0efd72ba-ba85-470f-8c21-ab68730ca8c9linux /boot/vmlinuz-2.6.35-22-generic root=UUID=0efd72ba-ba85-470f-8c21-ab68730ca8c9 ro   quiet splashinitrd 
/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 {recordfailinsmod part_msdosinsmod ext2set root='(hd0,msdos1)'search --no-floppy --fs-uuid --set 0efd72ba-ba85-470f-8c21-ab68730ca8c9echo '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調用成功!
到這一步,算是全部成功啦!!慶祝一下,去裝個逼吧~~~~
 
寫在最後的話:

由於筆者是新手,裏面的步驟有些顯得很笨重,希望大手們看到之後多多指教!謝謝!!
另外,做這個實驗一定要有耐心,若是你做的時候一直很小心,每一步都認真做,那麼你一次就可以成功!!別像筆者這樣做了不知多少遍。
最後,祝大家成功!!   有不足,也希望大家指出,謝謝@~@
 
ps:
參考文檔:http://wenku.baidu.com/view/40af3b6727d3240c8447efd8.html?qq-pf-to=pcqq.c2c

第一篇博文,謝謝大家的瀏覽o(^▽^)o
————————————————
版權聲明:本文爲CSDN博主「GloryBossy」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/qq_34247099/article/details/50949720

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章