荔园在线

荔园之美,在春之萌芽,在夏之绽放,在秋之收获,在冬之沉淀

[回到开始] [上一篇][下一篇]


发信人: 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软件 网络书店