linux內核編譯與系統調用的添加(適合3.0及以後版本內核)

PRP報告還沒怎麼寫,竟就搞起了奇葩的操作系統,真是夠淡定的。而操作系統又是如此抽象,一個系統調用,每次都要刷一遍ubuntu,每次都要編譯一次內核,每次編譯都是萬分無聊的一兩個小時,還有編譯到最後報錯的,真是讓人受不了;而教材,現在才發現,真的什麼都不是,能不能再錯一點!看着一道道編譯指令在屏幕上一行行淡定的刷過,瞬間就不淡定了,敢情就不能快點……經過了不知多少時間的摸索,經過不下四五次的編譯,經過週六(3月3日)整天的糾結之後,任務終於完成了——雖然,不過屏幕上打出的一行字……(怎麼感覺這麼諷刺)

這次project的完成,離不開decoet的啓發與指導,離不開無數博主的經驗,在此一併感謝、參考過的文章一併至於文後,供大家參考吧!

Part 1 前期的準備

安裝ubuntu 10.10
  ##不同發行版的內核和一些應用上有差別,可根據自己喜好來選擇。Ubuntu 10.10內核版本爲linux-2.6.35-22##
下載linux-3.0.23
  ##http://www.kernel.org提供內核下載。筆者在學習操作系統,故嘗試新的3.0版本安裝##
打開終端,進入linux-3.0.23.tar.bz2所在文件夾,並獲得管理員權限 
  ##筆者將壓縮包置於”~/下載”目錄下,通過sudo su獲得管理員權限,一般多建議不直接獲得管理員權限,此處爲了後面運行方便##

Part2 添加系統調用

1、解壓內核

mv linux-3.0.23.tar.bz2 /usr/src/
  ##將壓縮包移動至”/usr/src”目錄下,此處需要root權限##
cd ../../../usr/src
  ##將工作目錄置於”/usr/src”,當前目錄爲”~/下載”(見上文)##
tar -jxvf linux-3.0.23.tar.bz2
  ##解壓內核文件壓縮包##

2、添加系統調用

cd linux-3.0.23/kernel
  ##將工作目錄置於”/usr/src/linux-3.0.23/kernel”,當前目錄爲”/usr/src/”(見上文)##
gedit sys.c
  ##打開sys.c源文件,添加頭文件 
#include <linux/linkage.h>
在文末添加代碼 
asmlinkage int sys_helloworld(){
printk(KERN_EMERG "hello world!(by cffde,Mar.2012)");
return 1;
}

##

3、修改指針列表

cd ../arch/x86/kernel
  ##將工作目錄置於”/usr/src/linux-3.0.23/arch/x86/kernel”,當前目錄爲” /usr/src/linux-3.0.23/kernel”(見上文)##
gedit syscall_table_32.S
  ##打開syscall_table_32.S文件,在文末添加 
.long sys_helloworld        /*347*/
##
cd ../include/asm
  ##將工作目錄置於”/usr/src/linux-3.0.23/arch/x86/include/asm”,當前目錄爲” /usr/src/linux-3.0.23/arch/x86/kernel”(見上文)##
gedit unistd_32.h
  ##打開unistd_32.h文件,在”#define __NR_**    ***”最末位置添加 
#define __NR_helloworld     347
!!!將下面行中的另一聲明後的值由347改爲348 
##

Part 3 編譯內核

1、編譯前準備

cd ../../../..
  ##將工作目錄置於”/usr/src/linux-3.0.23”,當前目錄爲” /usr/src/linux-3.0.23/arch/x86/include/asm”(見上文)##
sudo apt-get install build-essential kernel-package libncurses5-dev fakeroot

2、編譯

sudo make mrproper
  ##此命令可選。當編譯出錯需要重新編譯或不是第一次編譯,都需要執行該命令清理編譯歷史##
sudo make menuconfig
  ##出現對話框時,可選擇默認配置,即直接exit退出##

個人使用:sudo make bzImage
make -j4
  ##編譯內核命令,-j4用於雙核處理器,即2核*2##

##下面,恭喜你進入漫長的等待過程~隨便找點樂子消遣消遣吧,當然,還是要隨時關注屏幕,萬一報錯了呢……##

Part4 安裝內核

1、安裝內核

make modules_install
make install

2、設置新內核啓動項

apt-get install bootcd-mkinitramfs
mkinitramfs 3.0.23 -o /boot/initrd.img-3.0.23   
update-grub2
reboot

Part 5 檢查系統調用

1、新建檢測程序

#include<stdio.h>

int main()
{
int tmp;
tmp=syscall(347);
printf("\n");
if(tmp==1)
{
printf("系統調用成功!\n");
}
}

2、檢測程序編譯與執行

gcc t.c
ll t.c a.out
./a.out
dmesg –c

3、執行結果

...
...
[   28.025069] EXT4-fs (loop0): re-mounted. Opts: errors=remount-ro,commit=0
[   37.884360] keyboard: can't emulate rawmode for keycode 240
[   37.884371] keyboard: can't emulate rawmode for keycode 240
[   37.884377] hp_wmi: Unknown key code - 0x20000
[  754.454039] hello world!(by cffde,Mar.2012)

Part 6 問題與解決方案

問題一:

root@ubuntu:/usr/src/linux-source-2.6.35# make menuconfig
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/basic/docproc
  HOSTCC  scripts/basic/hash
  HOSTCC  scripts/kconfig/conf.o
scripts/kconfig/conf.c: In function ‘conf_askvalue’:
scripts/kconfig/conf.c:105: warning: ignoring return value of ‘fgets’, declared with attribute warn_unused_result
scripts/kconfig/conf.c: In function ‘conf_choice’:
scripts/kconfig/conf.c:307: warning: ignoring return value of ‘fgets’, declared with attribute warn_unused_result
  HOSTCC  scripts/kconfig/kxgettext.o
 *** Unable to find the ncurses libraries or the
 *** required header files.
 *** 'make menuconfig' requires the ncurses libraries.
 *** 
 *** Install ncurses (ncurses-devel) and try again.
 *** 
make[1]: *** [scripts/kconfig/dochecklxdialog] 錯誤 1
make: *** [menuconfig] 錯誤 2

問題一解決方案:

apt-get install build-essential kernel-package libncurses5-dev fakeroot

問題二:

內核編譯通過測試程序無法執行 

問題二解決方案

在unistd_32.h後添加237號位置後,未將後面的syscall由237改爲238     

問題三:

內核安裝除了直接從網上下載合適版本外,還可以通過ubuntu自動下載,相關命令: 
apt-get install linux-source
它會自動下載到”/usr/src”目錄下,接下來的步驟與上述相同。但通過這種方法編譯時會報錯: 
ld: /ubuntu/omnibook/sections.lds: No such file: No such file or directory
make[2]: *** [ubuntu/omnibook/omnibook.o] Error 1
make[1]: *** [ubuntu/omnibook] Error 2
make: *** [ubuntu] Error 2

問題三解決方案:

進入”/usr/src/linux-source-2.6.35/ubuntu/omnibook”目錄 
輸入命令 
gedit Makefile 
找到下面兩行
#EXTRA_LDFLAGS +=  $(src)/sections.lds
EXTRA_LDFLAGS += $(PWD)/ubuntu/omnibook/sections.lds 
調換一下‘#’的位置,如下                 
EXTRA_LDFLAGS +=  $(src)/sections.lds
#EXTRA_LDFLAGS += $(PWD)/ubuntu/omnibook/sections.lds 

參考文獻

http://www.linuxidc.com/Linux/2011-04/34079.htm

http://blog.csdn.net/zyxlinux888/article/details/6593647

http://archive.cnblogs.com/a/1728347/

http://tsong.yunxi.net/2011/11/ubuntu-1010-linux-30-rc4.html

http://blog.csdn.net/gexueyuan/article/details/6923938

http://www.cnblogs.com/kenjones/archive/2011/03/09/1978611.html

http://tracera.blog.51cto.com/2876016/641291

http://blog.csdn.net/catamout/article/details/5380562

後記

雖然早就接觸linux,從ubuntu 10.04一直追到ubuntu 11.10,但不過是嚐嚐鮮罷了,這次的project纔算得上真正的入門。這次的project遠比想象中的麻煩,教材中的舊版本無法指定準確目錄,內核需要自己下載編譯,還有各種瑣碎卻致命的bug;最無奈的便是長達一兩個小時的編譯時間,弄得一天的效率都很低。網上的資料查了一篇又一篇,終於最終完成了新內核的編譯和系統調用的實現。

一直做下來,感受最深的是,對於什麼事情,必定及早做,問題遠比想象中的多。也不要指望自己牛逼的技術能保證一次通過,因爲一個小小的錯誤就可能將之前所有的努力付之一炬。做的過程中,可能會遇到很多困難,一次次的失敗可能使自己想到放棄,但多數情況下只需再堅持一點點,我們要確保所有的可能都嘗試過了,而不是因爲是3個小時或一天沒有解決而去放棄。至於這次,不要期望一次就能通過,做好一次次重裝的準備,除非,你足夠的幸運。

當然,我是個菜鳥,遇到的問題可能算不上問題,重要的是享受努力後收穫的喜悅吧。

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