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個小時或一天沒有解決而去放棄。至於這次,不要期望一次就能通過,做好一次次重裝的準備,除非,你足夠的幸運。
當然,我是個菜鳥,遇到的問題可能算不上問題,重要的是享受努力後收穫的喜悅吧。