• 为xv6添加一个系统调用


    1. Overview

    要为xv6添加一个系统调用,需要修改以下5个文件:

    • syscall.h
    • syscall.c
    • sysproc.c
    • usys.S
    • user.h

    由于Unix v6发行于1975年,下面我们以添加一个返回整数1975的系统调用作为示范来说明如何为xv6添加一个系统调用。

    2. syscall.h

    打开syscall.h,在相应位置添加下面这一行:

    #define SYS_getyear 22
    

    添加后整个文件的内容如下:

    // System call numbers
    #define SYS_fork    1
    #define SYS_exit    2
    #define SYS_wait    3
    #define SYS_pipe    4
    #define SYS_read    5
    #define SYS_kill    6
    #define SYS_exec    7
    #define SYS_fstat   8
    #define SYS_chdir   9
    #define SYS_dup    10
    #define SYS_getpid 11
    #define SYS_sbrk   12
    #define SYS_sleep  13
    #define SYS_uptime 14
    #define SYS_open   15
    #define SYS_write  16
    #define SYS_mknod  17
    #define SYS_unlink 18
    #define SYS_link   19
    #define SYS_mkdir  20
    #define SYS_close  21
    #define SYS_getyear 22
    

    由此可见,我们添加的getyear是第22号系统调用。

    3. syscall.c

    syscall.c中添加一个指向该系统调用的函数指针:

    [SYS_getyear] sys_getyear
    

    添加后上行后,系统调用的函数指针数组为:

    static int (*syscalls[])(void) = {
    [SYS_fork]    sys_fork,
    [SYS_exit]    sys_exit,
    [SYS_wait]    sys_wait,
    [SYS_pipe]    sys_pipe,
    [SYS_read]    sys_read,
    [SYS_kill]    sys_kill,
    [SYS_exec]    sys_exec,
    [SYS_fstat]   sys_fstat,
    [SYS_chdir]   sys_chdir,
    [SYS_dup]     sys_dup,
    [SYS_getpid]  sys_getpid,
    [SYS_sbrk]    sys_sbrk,
    [SYS_sleep]   sys_sleep,
    [SYS_uptime]  sys_uptime,
    [SYS_open]    sys_open,
    [SYS_write]   sys_write,
    [SYS_mknod]   sys_mknod,
    [SYS_unlink]  sys_unlink,
    [SYS_link]    sys_link,
    [SYS_mkdir]   sys_mkdir,
    [SYS_close]   sys_close,
    [SYS_getyear] sys_getyear // SYS_getyear == 22
    };
    

    可见当用户程序调用22号系统调用时,会调用sys_getyear这个指针所指向的函数。

    因此我们需要自己实现这个函数,在此之前先在syscall.c中添加该函数的原型:

    extern int sys_getyear(void);
    

    4. sysproc.c

    sysproc.c中添加该调用的实现:

    int
    sys_getyear(void)
    {
    	return 1975;
    }
    

    可见,该系统调用返回了Unix v6的发布日期1975。

    5. usys.S

    usys.S中添加下面这一行:

    SYSCALL(getyear)
    

    添加后的内容:

    #include "syscall.h"
    #include "traps.h"
    
    #define SYSCALL(name) \
      .globl name; \
      name: \
        movl $SYS_ ## name, %eax; \
        int $T_SYSCALL; \
        ret
    
    SYSCALL(fork)
    SYSCALL(exit)
    SYSCALL(wait)
    SYSCALL(pipe)
    SYSCALL(read)
    SYSCALL(write)
    SYSCALL(close)
    SYSCALL(kill)
    SYSCALL(exec)
    SYSCALL(open)
    SYSCALL(mknod)
    SYSCALL(unlink)
    SYSCALL(fstat)
    SYSCALL(link)
    SYSCALL(mkdir)
    SYSCALL(chdir)
    SYSCALL(dup)
    SYSCALL(getpid)
    SYSCALL(sbrk)
    SYSCALL(sleep)
    SYSCALL(uptime)
    SYSCALL(getyear)
    

    6. user.h

    为了能够让用户程序访问到getyear系统调用,我们需要在user.h中声明该调用:

    int getyear(void);
    

    添加后的系统调用声明:

    // system calls
    int fork(void);
    int exit(void) __attribute__((noreturn));
    int wait(void);
    int pipe(int*);
    int write(int, const void*, int);
    int read(int, void*, int);
    int close(int);
    int kill(int);
    int exec(char*, char**);
    int open(const char*, int);
    int mknod(const char*, short, short);
    int unlink(const char*);
    int fstat(int fd, struct stat*);
    int link(const char*, const char*);
    int mkdir(const char*);
    int chdir(const char*);
    int dup(int);
    int getpid(void);
    char* sbrk(int);
    int sleep(int);
    int uptime(void);
    int getyear(void); 
    

    7. 测试getyear

    完成上述步骤,一个系统调用就已经创建好了,现在来编写一个用户程序来测试以下该系统调用。

    创建一个用户程序:getyear.c

    #include "types.h"
    #include "stat.h"
    #include "user.h"
    
    int
    main(void)
    {
            printf(1, "Note: Unix v6 was released in year %d\n", getyear());
            exit();
    }
    

    Makefile中的UPROGS中添加_getyear:

    UPROGS=\
            _cat\
            _echo\
            _forktest\
            _getyear\
            _grep\
            _hello\
            _init\
            _kill\
            _ln\
            _ls\
            _mkdir\
            _rm\
            _sh\
            _stressfs\
            _usertests\
            _wc\
            _zombie\
    

    现在启动xv6,运行getyear程序:

    Booting from Hard Disk..xv6...
    cpu1: starting 1
    cpu0: starting 0
    sb: size 1000 nblocks 941 ninodes 200 nlog 30 logstart 2 inodestart 32 bmap start 58
    init: starting sh
    $ getyear
    Note: Unix v6 was released in year 1975
    

    命令行里顺利地显示出了预期的Unix v6的发布日期。

  • 相关阅读:
    1、SASS / SCSS 总结简介
    Chrome 中的 JavaScript 断点设置和调试技巧
    《Javascript 设计模式》-读书笔记
    CSS基线之道
    高性能 CSS3 动画
    《编写高质量代码》web前端开发修炼之道-读书笔记
    《Effective JavaScript》编写高质量的Javascript代码的68个有效方法-读书笔记
    Sea.js-模块化开发框架
    JSLine和JSHint代码质量检查工具和uglifyjs压缩JS的
    在Windows平台上安装Node.js及NPM模块管理
  • 原文地址:https://www.cnblogs.com/jmhwsrr/p/15847509.html
Copyright © 2020-2023  润新知