天天看点

操作系统实验之系统调用

1。今天整理了一下实验报告

在unistd.h中可以看到现在Linux 0.11 支持3个参数的传递。添加参数的方法大概有3条
           1.可以采用ESI,EDI,EBP,ESP这几个寄存器传递参数。
           2.可以采用《Linux 0.11注释》中提到的系统调用门的办法。
           3.可以开辟一块用户态的空间,允许内核态访问,传递参数时,只需传递此空间的首地址指针即可。
           

2。具体实现思路如下:

1)在include/unistd.h中添加系统调用的功能号

操作系统实验之系统调用

2)并且相应的在include/linux/sys.h中声明新的系统调用处理函数以及添加系统调用处理程序指针数组表中该项的索引值

操作系统实验之系统调用

3)修改system_call.s中系统调用总数。

操作系统实验之系统调用

4)在内核中编写系统调用处理函数,放在kernel下面(who.c)。

#define  __LIBRARY__
#include <unistd.h>
#include <errno.h>
#include <asm/segment.h>

//实现将用户空间的字符串拷贝到内核空间中
//建立变量存储
char tmp[]={}  
int sys_iam(const char * name)
{
   int i = ;
   //字符串长度不能超过32,放回拷贝的字符串的个数,
   //如果超过32,返回-1,同时将errno置为EINVAL
   while(get_fs_byte(name+i) != '\0')
    {
       i++;
    }
   if(i > )
    {
       return -EINVAL;
    }
    i = ;
    //包括字符串结束符
    while((tmp[i] = get_fs_byte(name+i))!= '\0')
    {
        i++;
    }
    return i;  //返回实际拷贝的字符串个数
}

//获取sys_iam在内核中存储的字符串
//长度不能超过32
int sys_whoami(char * name,unsigned int size)
{
   int i =;
   while(tmp[i++] != '\0');
   if(size < i)
    {
        //name的空间小于字符串的长度,返回-1
        return -;
    }
   i = ;
   //拷贝到用户空间
   while(tmp[i] != '\0')
    {
       put_fs_byte(temp[i],(name + i));
       i++;
    }
    return i;
}
           

4)在make file中添加新系统调用所在文件的编译、链接规则(依赖关系)。

操作系统实验之系统调用
操作系统实验之系统调用

5)在应用程序中提供接口,调用系统调用。

① ami:

#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[])
{

    if(argc>){
    if(iam(argv[])<){
        printf("SystemCall Exception!\n");
        return -;
    }
    }
    else{
    printf("Input Exception!\n");
    return -;
    }       
    return ;
}
           

② whoami:

#define __LIBRARY__  //一定要加,不然的话_syscall2不能识别
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdio.h>
//系统调用
_syscall2(int,whoami,char*,name,unsigned int,size)

int main()
{
    int counter;
    char buff[]={};

    counter=whoami(buff,);
    if(counter < )
    {
       printf("SystemCall Exception!");
       return -;
        }
    else{
        printf("%s\n",buff);
        }
    return ;
}
           

2。实现结果

操作系统实验之系统调用

3。实验过程中出现的问题总结:

1)关于linux0.11和ubuntu之间文件共享的问题

按照实验手册上面所示,不能显示,我的解决:

先挂载,加需要添加的文件或者新建文件到 /hdc/usr/root/目录下面就行了,修改完成之后,卸载,运行linux0.11,在linux0.11中/home/root/目录下面ls就能显示出来

2)提示_NR_ami 没有找到问题

我们在前面所示,我们需要虚拟机中的unistd.h才行,具体的路径是:

/hdc/usr/include/unistd.h 就可以了

继续阅读