哈工大操作系统实验二:系统调用的实现

实验链接


前言

做实验前一定要先拍个快照!!

在这里插入图片描述

操作系统实验环境的搭建请看如下链接(Ubuntu系统)

Linux0.11环境搭建





提示:以下是本篇文章正文内容,下面案例可供参考

一、实验内容

在这里插入图片描述
在这里插入图片描述



二.基础知识

具体请查看此文章
在这里插入图片描述
在这里插入图片描述

三、实验步骤

参考的文章

注:因为实验一已经修改过启动文件。但此次实验需要完整的启动文件,所以需要新的linux0.11环境。(在做实验一之前拍过一个快照所以我们只需要回复快照就行)

步骤一:打开unistd.h文件(在linux-0.11/include目录下)
在第132和133行添加如下代码

#define __NR_whoami  72
#define __NR_iam 73

在这里插入图片描述



步骤二:打开system_call.s文件(在linux-0.11/kernel目录下)
将61行的72改成74,因为现在总的系统调用有74个多了两个我们自己添加的系统调用

在这里插入图片描述



步骤三:进入sys.h文件(在linux-0.11/include/linux/目录下)

在第73行和第74行添加两句话

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

并在第89行把两个系统调用名添加到最后
在这里插入图片描述



步骤四:在路径:linux-0.11/kernel目录下创建who.c文件并添加如下代码

在这里插入图片描述
代码来源处

#define __LIBRARY__			
#include <unistd.h>		
#include <errno.h>		/* 要求设置错误为EINVAL */
#include <asm/segment.h>	/* 使用put_fs_byte和get_fs_byte */
 
 
char temp[64]={0};		/* 存储sys_iam获取的字符串	*/
 
int sys_iam(const char* name)
{
   int i=0;			/* 用户空间数据name长度	*/
   while(get_fs_byte(name+i)!='\0') i++;	
   if(i>23) return -EINVAL;
   printk("%d\n",i);
   
   i=0;			/* 获取name至temp  */
   while((temp[i]=get_fs_byte(name+i))!='\0'){
	i++;
   }   
    return i;
}
 
int sys_whoami(char* name,unsigned int size)
{
    int i=0;			/* 内核空间数据temp长度 */
    while (temp[i]!='\0') i++;
    if (size<i) return -1;
    
    i=0;			/* 获取temp至name  */
    while(temp[i]!='\0'){	
	put_fs_byte(temp[i],(name+i));
	i++;
    }
    return i;
}


在这里插入图片描述



步骤六: 修改linux-0.11/kernel下的makefile文件
在这里插入图片描述

进入makefile文件,按A键进行编辑,编辑完后按ESC退出编辑模式
按完ESC后再按shift+:,然后输入wq!保存退出

改动如下:
①:在OBJS最后添加 who.o
②:再到### Dependencies:下添加这句话:
who.s who.o: who.c …/include/linux/kernel.h …/include/unistd.h

在这里插入图片描述

在这里插入图片描述



步骤七:在此路径下打开终端,输入代码:make
在这里插入图片描述
他会出现一点错误,但无伤大雅。
而且会生成一些.o文件,如下图

在这里插入图片描述



步骤八:在oslab目录下创建whoami.c和iam.c两个测试文件
文件内容如下

代码来源处

/ /  iam.c
/* iam.c  */
#define __LIBRARY__        
#include "unistd.h" 
_syscall1(int, iam, const char*, name); 
int main(int argc, char** argv){
    int wlen = 0;
    if(argc < 1){
        printf("not enougth argument\n");
        return -2;
    }
    wlen = iam(argv[1]);
    return wlen;
}

/ / whoami.c
/* whoami.c */
#define __LIBRARY__        
#include "unistd.h" 
_syscall2(int, whoami,char*,name,unsigned int,size);    

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

在这里插入图片描述



步骤九:挂载到hdc目录中

我们添加到linux-0.11中的系统调用只能在bochs虚拟机中运行,不能在终端上运行

在oslab目录下打开终端,输入以下命令

sudo ./mount-hdc

可以看到hdc目录下明显多了许多内容
在这里插入图片描述



步骤十:在步骤九的终端下输入以下命令

cp  /home/你自己的用户名/oslab/linux-0.11/include/unistd.h  /home/你自己的用户名/oslab/hdc/usr/include/unistd.h
cp  /home/你自己的用户名/oslab/linux-0.11/include/linux/sys.h  /home/你自己的用户名/oslab/hdc/usr/include/linux/sys.h
cp /home/你自己的用户名/oslab/iam.c  hdc/usr/root
cp /home/你自己的用户名/oslab/whoami.c  hdc/usr/root

在这里插入图片描述



步骤十一:验证结果

进入目录oslab/linux-0.11,打开终端,输入以下命令进入bochs虚拟机

make all
../run

在这里插入图片描述
在bochs下输入一下代码

gcc -o iam iam.c
gcc -o whoami whoami.c
./iam  后面加一段字符串,你想写什么就写什么
./whoami 

在这里插入图片描述

完结

  • 19
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
fork是一个系统调用,用于创建一个新的进程。在哈尔滨工业大学的操作系统课程中,学生学习到了fork系统调用的使用和原理。 在操作系统中,每个进程都具有一个唯一的进程ID(PID)和一组资源。当调用fork时,当前进程会被复制,创建一个新的子进程。子进程和父进程具有相同的代码、数据和环境变量等。但是,子进程有自己的独立的内存空间。 fork调用返回两次,一次在父进程中返回子进程的PID,一次在子进程中返回0。这样,父进程可以根据返回的PID来判断fork是否成功,并根据需要进行相应的处理。 fork系统调用被广泛应用于多进程编程中。通过利用fork,可以实现并发执行,提高系统的资源利用率和效率。在操作系统课程中,学生通常学习如何使用fork创建子进程,并使用进程间通信机制进行进程间的数据交换和同步。 通过学习fork系统调用,学生可以了解进程的创建和管理,理解进程的概念和特点,并掌握进程间通信和同步的方法。此外,fork也是其他一些高级系统调用(如exec)的基础,对于学生进一步研究和学习操作系统提供了良好的基础。 总之,哈尔滨工业大学操作系统课程中的fork系统调用是学生学习并发编程和进程管理的重要内容,通过掌握这个系统调用,可以为学生提供丰富的编程经验和操作系统理论基础。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值