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”(见上文)##
apt-get install build-essential kernel-package libncurses5-dev fakeroot
2、编译
make mrproper
##此命令可选。当编译出错需要重新编译或不是第一次编译,都需要执行该命令清理编译历史##
make menuconfig
##出现对话框时,可选择默认配置,即直接exit退出##
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个小时或一天没有解决而去放弃。至于这次,不要期望一次就能通过,做好一次次重装的准备,除非,你足够的幸运。
当然,我是个菜鸟,遇到的问题可能算不上问题,重要的是享受努力后收获的喜悦吧。