荔园在线
荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀
[回到开始]
[上一篇][下一篇]
发信人: zzt (我命由我不由天), 信区: Linux
标 题: Linux 内核解读入门(下)
发信站: BBS 荔园晨风站 (Fri Aug 18 14:47:40 2000), 转信
【 以下文字转载自 zzt 的信箱 】
【 原文由 zzt.bbs@bbs.dot66.net 所发表 】
作者: phila (新新人类真爱一百) 站内: Linux
标题: Linux 内核解读入门(下)
时间: Thu Aug 10 15:31:37 2000
Linux 内核解读入门(下)
(07/26/2000)
(3)源码的修改
① kernel/sys.c中增加系统服务例程如下:
asmlinkage int sys_addtotal(int numdata)
{
int i=0,enddata=0;
while(i<=numdata)
enddata+=i++;
return enddata;
}
该函数有一个 int 型入口参数 numdata , 并返回从 0 到 numdata 的累加值,然而也可以
把系统服务例程放在一个自己定义的文件或其他文件中,只是要在相应文件中作必要的说明
。
②把smlinkage int sys_addtotal( int) 的入口地址加到sys_call_table表中。
arch/i386/kernel/entry.S 中的最后几行源代码修改前为:
... ...
.long SYMBOL_NAME(sys_sendfile)
.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
.rept NR_syscalls-190
.long SYMBOL_NAME(sys_ni_syscall)
.endr
修改后为: ... ...
.long SYMBOL_NAME(sys_sendfile)
.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
/* add by I */
.long SYMBOL_NAME(sys_addtotal)
.rept NR_syscalls-191
.long SYMBOL_NAME(sys_ni_syscall)
.endr
③把增加的 sys_call_table 表项所对应的向量,在include/asm-386/unistd.h 中进行必要
申明,以供用户进程和其他系统进程查询或调用。
增加后的部分 /usr/src/linux/include/asm-386/unistd.h 文件如下:
... ...
#define __NR_sendfile 187
#define __NR_getpmsg 188
#define __NR_putpmsg 189
#define __NR_vfork 190
/* add by I */
#define __NR_addtotal 191
④ 测试程序(test.c)如下:
#include
#include
_syscall1(int,addtotal,int, num)
main()
{
int i,j;
do
printf("Please input a numbern");
while(scanf("%d",&i)==EOF);
if((j=addtotal(i))==-1)
printf("Error occurred in syscall-addtotal();n");
printf("Total from 0 to %d is %d n",i,j);
}
对修改后的新的内核进行编译,并引导它作为新的操作系统,运行几个程序后可以发现一切
正常;在新的系统下对测试程序进行编译(注:由于原内核并未提供此系统调用,所以只有
在编译后的新内核下,此测试程序才可能被编译通过),运行情况如下:
$gcc 杘 test test.c
$./test
Please input a number
36
Total from 0 to 36 is 666
可见,修改成功,而且对相关源码的进一步分析可知,在此版本的内核中,从/usr/src/lin
ux/arch/i386/kernel/entry.S 文件中对 sys_call_table 表的设置可以看出,有好几个系
统调用的服务例程都是定义在 /usr/src/linux/kernel/sys.c 中的同一个函数:
asmlinkage int sys_ni_syscall(void)
{
return -ENOSYS;
}
例如第188项和第189项就是如此:
... ...
.long SYMBOL_NAME(sys_sendfile)
.long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
.long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
.long SYMBOL_NAME(sys_vfork) /* 190 */
... ...
而这两项在文件 /usr/src/linux/include/asm-386/unistd.h 中却申明如下:
... ...
#define __NR_sendfile 187
#define __NR_getpmsg 188 /* some people actually want streams */
#define __NR_putpmsg 189 /* some people actually want streams */
#define __NR_vfork 190
由此可见,在此版本的内核源代码中,由于asmlinkage int sys_ni_syscall(void) 函数并不
进行任何操作,所以包括 getpmsg, putpmsg 在内的好几个系统调用都是不进行任何操作的
,即有待扩充的空调用; 但它们却仍然占用着sys_call_table表项,估计这是设计者们为
了方便扩充系统调用而安排的,所以只需增加相应服务例程(如增加服务例程getmsg或put
pmsg),就可以达到增加系统调用的作用。
3.结束语
当然对于庞大复杂的 Linux而言,一篇文章远远不够,而且与系统调用相关的代码也只是内
核中极其微小的一部分,重要的是方法,掌握好的分析方法,所以上述分析只是起个引导作用
,而真正的分析还有待读者自己的努力。
摘自:软件工程师
--
爱到心破碎,也别去怪谁,只因为相遇太美,就算流干泪,伤到底,心成灰,也无所谓。
我破茧成蝶,愿和你双飞,最怕你会一去不回,虽然爱过我,给过我,想过我,就是安慰。
我向你飞,雨温柔地追,想你的拥抱把我包围。
我向你飞,多远都不累,虽然旅途中,有过痛和累。
我向你追,风温柔地吹,只要你无怨我也无悔。
爱是那么美,我心陶醉,被爱的感觉。
--
※ Origin: 笑 书 亭 <bbs.dot66.net>
◆ From: 202.107.204.9
--
※ 转载:·BBS 荔园晨风站 bbs.szu.edu.cn·[FROM: 192.168.1.11]
[回到开始]
[上一篇][下一篇]
荔园在线首页 友情链接:深圳大学 深大招生 荔园晨风BBS S-Term软件 网络书店