实验3-系统调用

一、实验目的

建立对系统调用接口的深入认识;

掌握系统调用的基本过程;

能完成系统调用的全面控制;

为后续实验做准备。

二、实验步骤

1.修改unistd.h 图片描述 其中新增代码为

2.修改include/linux/sys.h 进入/home/shiyanlou/oslab/linux-0.11/中修改,有两个点需要修改:
1)仿照前面各个系统调用的写法,添加如下代码

extern int sys_iam();
extern int sys_whoami();

2)在sys_call_table中新加两个系统调用:

sys_iam,sys_whoami()

3.修改system_call.s 把nr_system_call的值从72改成74,因为我们加了两个系统调用

4.修改Makefile Makefile 在代码树中有很多,分别负责不同模块的编译工作。我们要修改的是 kernel/Makefile。需要修改两处。

(1)第一处

OBJS = sched.o system_call.o traps.o asm.o fork.o
panic.o printk.o vsprintf.o sys.o exit.o
signal.o mktime.o 改为:

OBJS = sched.o system_call.o traps.o asm.o fork.o
panic.o printk.o vsprintf.o sys.o exit.o
signal.o mktime.o who.o 添加了 who.o。

(2)第二处
Dependencies:

exit.s exit.o: exit.c …/include/errno.h …/include/signal.h
…/include/sys/types.h …/include/sys/wait.h …/include/linux/sched.h
…/include/linux/head.h …/include/linux/fs.h …/include/linux/mm.h
…/include/linux/kernel.h …/include/linux/tty.h …/include/termios.h
…/include/asm/segment.h 改为:
Dependencies:

who.s who.o: who.c …/include/linux/kernel.h …/include/unistd.h exit.s exit.o: exit.c …/include/errno.h …/include/signal.h
…/include/sys/types.h …/include/sys/wait.h …/include/linux/sched.h
…/include/linux/head.h …/include/linux/fs.h …/include/linux/mm.h
…/include/linux/kernel.h …/include/linux/tty.h …/include/termios.h
…/include/asm/segment.h

5.编写3个.c文件

1)who.c

#define LIBRARY
#include<unistd.h>
#include <errno.h>
#include<asm/segment.h>
#include<linux/kernel.h>
char tmp[64] = {0};
int sys_iam(char * name){
int k = 0;
while(get_fs_byte(name+k)!=’\0’)
k++;
if (k>23){
return -EINVAL;
}
else{
int i = 0;
while((tmp[i]=get_fs_byte(name+i))!=’\0’)
i++;
return k;
}
}

int sys_whoami(char * name, unsigned int size){
int i = 0;
while(tmp[i]!=’\0’){
i++;
}
if (size<i){

    return -EINVAL;
}
i = 0;
while(tmp[i]!='\0'){
    put_fs_byte(tmp[i],name+i);
    i++;
}

return i;

}

然后是两个测试程序

2)iam.c

#define LIBRARY
#include <unistd.h>

_syscall1(int,iam,char*,name)

int main(int argc,char * argv[])
{
iam(argv[1]);
return 0;
}

3)whoami.c

#define LIBRARY
#include <unistd.h>
#include<stdio.h>

_syscall2(int,whoami,char*,name,unsigned int,size)

char arr[24];

int main()
{
whoami(arr,24);
printf("%s",arr);
return 0;
}

6.挂载Linux,并在/usr/include/unistd.h文件中添加两个宏定义:

#define __NR_iam 72
#define __NR_whoami 73

三、实验结果

1.运行testlab2.c,得分为50% 图片描述

2.运行testlab2.sh,得分30% 图片描述
四.两个问答题:

1.从 Linux 0.11 现在的机制看,它的系统调用最多能传递几个参数?你能想出办法来扩大这个限制吗?

查看linux-0.11/include/unistd.h,可看到最多只能传递3个参数;

扩大限制的方法:

i)定义一个结构体,这个结构体里面可以有很多参数,然后把结构体的入口地址当作参数进行传递

ii)用ebx,edx,ecx循环传值

iii)再加几个寄存器,比如edi,esi,ebp等

2.用文字简要描述向 Linux 0.11 添加一个系统调用 foo() 的步骤.

主要分成三个部分

1)修改Linux内核文件

2)在kernel文件夹下实现系统调用,并执行make all指令把新的系统调用加入到内核中

3)挂载Linux,并修改/usr/include/unistd.h

下面是详细的步骤

1)修改Linux内核文件

a.修改linux-0.11/include/unistd.h,增加如下代码:

#define __NR_foo 72

b.修改linux-0.11/include/linux/sys.h

添加代码:

extern int sys_foo();

并在sys_call_table表中新增一个系统调用

sys_foo

c.修改linux-0.11/kernel/system_call.s中的nr_system_calls,使其增加1

d.修改linux-0.11/kernel/Makefile,在OBJS中添加foo.o,并添加生成foo.s和foo.o的依赖规则

2)在kernel文件夹下通过foo.c实现sys_foo()

3)在Ubuntu中挂载Linux系统,进入/usr/include/unistd.h中添加__NR_foo的宏定义
五、实验收获

了解了系统调用的详细过程,了解了数据在用户和内核之间传送的方法

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值