操作系统实验(2:系统调用)

实验目的

1.建立对操作系统接口的深入认识
2.掌握系统调用的基本过程
3.能完成系统调用的全面控制

实验内容

在Linux 0.11上添加两个系统调用,并编写两个简单的应用程序测试该系统调用。实验过程分两步。

第一步是在Linux 0.11上增加一个系统调用whoami(),原型如下:
int whoami(void);

该系统调用的功能是将用户的名字(例如:Li Zhijun)打印到屏幕上。用户的名字字符串写在内核源代码中。然后在Linux 0.11下编写一个测试程序whoami,它调用whoami()获得自己的名字,并在标准输出设备(通常就是屏幕上)打印字符串“I am XXX.”。返回值是任意非负数。

第二步在Linux 0.11上再添加一个系统调用iam(),其接口是:
int iam(const char * name);

完成的功能是将用户程序中传入的字符串参数name的内容拷贝到核心态数据段中。要求name的长度不能超过20个字符。可以假设在核心态数据段中有一个全局变量:char myname[21],iam将用户态数据name拷贝到核心态数据myname中。返回值是拷贝的字符数。如果name的字符个数超出了myname的存储能力,则返回“-EINVAL”。

然后修改的上面的whoami(),新的原型为:
int whoami(char* name, unsigned int size);

它不再向屏幕输出任何内容,而是拷贝myname到name中,同时确保不会对name越界访存(name的大小由size说明)。返回值是拷贝的字符数。如果size小于需要的空间,则返回“-EINVAL”。

然后再实现一个测试程序iam。最终要求的结果是:
$ iam lizhijun
$ whoami
$ I am lizhijun

以上截取至实验指导书。

实验步骤

实验步骤参考了简书上寒夏凉秋的文章。链接如下:
https://www.jianshu.com/p/5786cd42b152
(侵删)

1.修改sys.h

进入linux-0.11/include/linux目录,打开sys.h文件,在全局变量和中断函数表中添加iam()和whoami()两个函数。
在这里插入图片描述

2.修改system_call.s

由于新增了两个中断函数,所以需要修改中断函数的个数。进入linux-0.11/kernel目录,打开system_call.s,修改nr_system_calls为74。
在这里插入图片描述

3.增加系统调用号

由于unistd.h不能直接修改,我们要把虚拟硬盘挂载在oslab/hdc目录下,在终端输入命令:
sudo ./mount-hdc

然后进入hdc/usr/include目录,打开unistd.h,在系统调用的定义中增加两行:
#define __NR_iam 72
#define __NR_whoami 73
在这里插入图片描述
4.实现内核函数
进入linux-0.11/kernel目录,新建who.c,实现sys_iam()和syswhoami(),代码如下:

#include <string.h>
#include <errno.h>
#include <asm/segment.h>

char msg[24];

int sys_iam(const char * name)
{
    char tep[26];
    int i = 0;
    for(; i < 26; i++)
    {
        tep[i] = get_fs_byte(name+i);
        if(tep[i] == '\0')  break;
    }

    if (i > 23) return -(EINVAL);

    strcpy(msg, tep);
    return i;
}

int sys_whoami(char * name, unsigned int size)
{
    int len = 0;
    for (;msg[len] != '\0'; len++);
    
    if (len > size) 
    {
        return -(EINVAL);
    }
    
    int i = 0;
    for(i = 0; i < size; i++)
    {
        put_fs_byte(msg[i], name+i);
        if(msg[i] == '\0') break;
    }
    return i;
}

5.修改Makefile文件

进入linux-0.11/kernel目录,打开Makefile,

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

另外将:

### 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 \

改为:

### 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 \

在这里插入图片描述
在这里插入图片描述
修改完后编译所有文件生成新的image文件。

6.编写测试文件

新建iam.c,代码如下:

#define __LIBRARY__
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
_syscall1(int,iam,const char*,name)

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

新建whoami.c,代码如下:

#define __LIBRARY__
#include <unistd.h>
#include <errno.h>
#include <stdio.h>

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

int main(int argc, char ** argv)
{
    char t[30];
    whoami(t, 30);
    printf("%s\n", t);
    return 0;
}

将这两个文件复制到hdc/usr/root目录下。

7.运行系统

在终端上切换目录为oslab,输入./run打开bochs从而运行linux,在bochs中输入以下命令编译iam.c和whoami.c:
gcc -o iam iam.c
gcc -o whoami whoami.c

然后输入以下命令测试:
./iam handsomeboy
./whoami

输出了handsomeboy,实验完成。
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值