轉載自: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