• Lab: system calls


    实验链接

    https://pdos.csail.mit.edu/6.S081/2020/labs/syscall.html


    System call tracing

    代码更改

    1. Makefile

      	$U/_trace\
      
      • 1
    2. user/user.h

      int trace(int);
      
      • 1
    3. user/usys.pl

      entry("trace");
      
      • 1
    4. kernel/syscall.h

      #define SYS_trace  22
      
      • 1
    5. kernel/sysproc.c

      uint64
      sys_trace(void)
      {
          int mask;
      
          if(argint(0, &mask) < 0)
              return -1;
      
          myproc()->mask = mask;
      
          return 0;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
    6. kernerl/syscall.c

      void
      syscall(void)
      {
        int num;
        struct proc *p = myproc();
      
        int total = NELEM(syscalls);
      
      
        num = p->trapframe->a7;
        if(num > 0 && num < total && syscalls[num]) {
          p->trapframe->a0 = syscalls[num]();
        } else {
          printf("%d %s: unknown sys call %d\n",
                  p->pid, p->name, num);
          p->trapframe->a0 = -1;
        }
      
        int mask = p->mask;
        int flag[32];
        for (int i = 1; i < 31; i++) {
          flag[i] = ((mask >> i) & 0x01);
        }
        if (flag[num]) {
            printf("%d: syscall %s -> %d\n", p->pid, syscall_id_2_name[num], p->trapframe->a0);
        }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23
      • 24
      • 25
      • 26
      • 27
    7. kernel/proc.c 在fork()函数,release()函数被调用之前,添加如下内容。

      
      np->mask = p->mask;
      
      • 1
      • 2
    8. kernel/proc.h(该文件proc结构体的最后一行,添加如下字段)

        int mask;
      
      • 1

    Sysinfo

    代码更改

    1. Makefile

      	$U/_sysinfotest\
      
      • 1
    2. user/user.h

      struct sysinfo;
      int sysinfo(struct sysinfo *);
      
      • 1
      • 2
    3. user/usys.pl

      entry("sysinfo");
      
      • 1
    4. kernel/syscall.h

      #define SYS_sysinfo 23
      
      • 1
    5. defs.h

      // proc.c
      uint64          getnfreeproc(void);
      
      // kalloc.c
      uint64          knfreemem();
      
      • 1
      • 2
      • 3
      • 4
      • 5
    6. sysproc.c

      uint64
      sys_sysinfo(void)
      {
          uint64 dist; // user pointer to struct stat
          if(argaddr(0, &dist) < 0)
              return -1;
      
          struct sysinfo info;
          info.freemem = knfreemem();
          info.nproc = getnfreeproc();
      
          struct proc *p = myproc();
          if(copyout(p->pagetable, dist, (char *)&info, sizeof(info)) < 0) {
              return -1;
          }
      
          return 0;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
    7. kalloc.c

      uint64
      knfreemem()
      {
          int page_cnt = 0;
      
          acquire(&kmem.lock);
          struct run *r;
          r = kmem.freelist;
          while (r) {
              page_cnt++;
              r = r->next;
          }
          release(&kmem.lock);
      
          return page_cnt * PGSIZE;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    8. proc.c

      uint64
      getnfreeproc(void)
      {
          int cnt = 0;
      
          struct proc *p;
          for(p = proc; p < &proc[NPROC]; p++) {
              acquire(&p->lock);
              if(p->state != UNUSED) {
                  cnt++;
              }
              release(&p->lock);
          }
      
          return cnt;
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16

    知识补充

    C数组赋值

    在看源码的过程中,文件kerner/syscall.c文件中,发现如下形式的代码。因为是第一次看这种写法的代码,因此这里记录一下。请看下面代码中syscalls数组,该数组的每个元素为一个函数指针(该函数形参为void,返回值为uint64)。但是每个元素在定义的时候,可以指定其顺序,例如,函数sys_fork指定下标为1(SYS_fork是一个宏变量,值为1,通过[SYS_fork]这种形式,将函数sys_fork的下标设为1),

    
    static uint64 (*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,
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    下面笔者自己写了一些测试。

    #include
    
    void sum(void) {
            printf("sum\n");
    }
    void sub(void) {
            printf("sub\n");
    }
    void div(void) {
            printf("div\n");
    }
    
    int test_func() {
            void (*func[])(void) = {
                    [1] sum,
                    [3] sub,
                    [2] div,
            };
    
            for (int i = 1; i <= 3; i++) {
                    func[i](); // result: sum, div, sub
            }
            printf("func size: %d\n", sizeof(func)/(sizeof((func)[0]))); // func size: 4
            // func[0](); // segmentfault
            // func[4](); // segmentfault
    
            return 0;
    }
    
    int test_array() {
            int a[] = {
                    [1] 1,
                    [3] 3,
                    [2] 2,
                    [8] 8,
            };
    
            for (int i = 1; i <= 3; i++) {
                    printf("%d\n", a[i]); // result: 1, 2, 3
            }
            printf("array size: %d\n", sizeof(a)/sizeof((a)[0])); // array size: 9
            return 0;
    }
    
    int main() {
            test_func();
            test_array();
            return 0;
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    extern关键字

    1. Use the extern keyword! Extends function’s visibility to all files in the program.

    github

    https://github.com/aerfalwl/mit-xv6-labs-2020.git

  • 相关阅读:
    多线程打印
    4.力扣c++刷题-->删除有序数组中的重复项 II
    vue自定义组件实现v-model双向数据绑定
    【强化学习】09——价值和策略近似逼近方法
    高教社杯数模竞赛特辑论文篇-2023年C题:基于历史数据的蔬菜类商品定价与补货决策模型(附获奖论文及R语言和Python代码实现)(下)
    如何使用IP归属地查询API加强网络安全
    X11 Xlib截屏问题及深入分析二 —— 源码实现1
    知识蒸馏原理与PVKD论文阅读
    6.2 构建并评价聚类模型
    [iOS开发]-暑期二-3GShare-协议传值的多方面运用
  • 原文地址:https://blog.csdn.net/u014110320/article/details/125911405