哈工大操作系统实验--实验三:系统调用,实验记录及实验报告

实验三 系统调用

记录一些学习哈工大操作系统实验的学习笔记和心得

  • Github地址 欢迎star ⭐️⭐️⭐️⭐️⭐️
  • 课程实验楼环境
  • 课程主页
  • 课程视频
  • 课程教材:
    • Linux内核完全注释
    • 操作系统原理、实现与实践

实验内容

  • 需要实现的系统调用函数如下:
int iam(const char * name);                // 将字符串内容保存到内核中
int whoami(char* name, unsigned int size); // 在内核中将iam()保存的信息拷贝到指定的用户地址空间中
  • 测试
./iam zhaojiazhen
./whoami

zhaojiazhen

补充:调用系统调用和调用一个普通的自定义函数在代码上并没有什么区别,但是不同的是,系统调用可能会涉及到内核交互

  • 系统调用函数通过使用call来讲系统调用的号传递到eax中,把参数传给其余寄存器,然后使用int 0x80中断
  • 我们在这里直接实现了sys_whoamisys_iam,然后进行调用相当于直接执行了系统调用代码
  • 传统应用代码,例如printf则是通过头文件中的syscall来访问system_call.s进而调用80中断来,然后调用sys_xxx函数实现的

首先我们需要知道实现一个系统调用需要修改哪些部分(这部分需要重点理解):

  • 在用户空间使用系统调用都是通过库函数或者直接调用sys_call
    • sys_call1
    • sys_call2
    • sys_call3
    • 目前最多只支持三个参数,因为保存参数的寄存器只有三个
  • sys_call则是通过传入参数到int 0x80实现的
  • int 0x80进行系统调用的原理是通过system_call.s实现的
  • system_call.s通过system_call_table实现,进而根据中断号调用系统调用函数
  • 综上所述:
  • 我们需要在unistd.h添加有关__NR_IAM__NR_whoami的系统调用号
  • system_call.s中更新系统调用数量
  • linux/sys.h中添加
    • extern int sys_iam
    • extern int sys_whoami
    • call_table数组中添加相关调用

完成上述修改后,还需要根据教程修改Makefile

  • 修改 OBJS
  • 修改 Dependices

通过教程我们可以发现,用户态和核心态数据交互所需要的函数为:

  • include/asm/segment.h/get_fs_byte
  • include/asm/segment.h/put_fs_byte

接下来就可以开始实现iam() whoami()函数了

  • kernel/下创建who.c
  • 参考代码如下:
  • int sys_iam(const char *name)
    {
        printk("hello, i'm sys_iam\n");
        char tmp[maxSize];
        int i;
        for (i = 0; i < maxSize; i++)
        {
            tmp[i] = get_fs_byte(name + i);
            if (tmp[i] == '\0')
                break; 
        }
        if (i == maxSize)
            return -EINVAL;
        else
        {
            strcpy(msg, tmp); 
            return i;
        }
    }
    
  • int sys_whoami(char *name, unsigned int size)
    {
        printk("hello, i'm sys_whoami\n");
        int msg_size = 0;
        while (msg[msg_size] != '\0')
            msg_size++;
        if (size < msg_size)
            return -EINVAL;
        else
        {
            int i;
            for (i = 0; i < size; i++)
            {
                put_fs_byte(msg[i], name + i);
                if (msg[i] == '\0')
                    break;
            }
            return i;
        }
    }
    

之后编译img镜像,进入linux0.11之后,编译iamwhoami运行如下命令即可

tips:为了防止出现编译或者其余问题,可以考虑先不实现iam以及whoami函数的具体逻辑,先使用printk来进行输出,测试函数是否真正起到了作用。

./iam zhaojiazhen
./whoami
zhaojiazhen

出现上述,证明完成了实验

实验报告

  • 问题1:前文已经做出了解答
  • 问题2:可以参考前文,这里不再赘述

你可能感兴趣的:(哈工大操作系统实验hit-os,驱动开发,linux,c语言)