view slides/2018/20180403/slide.md @ 23:c0ec001d8a28

update
author Takahiro SHIMIZU <anatofuz@cr.ie.u-ryukyu.ac.jp>
date Thu, 05 Apr 2018 11:34:39 +0900
parents slides/20180403/slide.md@7143a82401fa
children
line wrap: on
line source

title: 近況報告
author: Takahiro Shimizu
profile:
lang: Japanese

# 今週の進捗

- xv6をcloneして読み始めました
    - [Xv6, a simple Unix-like teaching operating system](https://pdos.csail.mit.edu/6.828/2017/xv6.html)
- 教科書もありました
    - [xv6 a simple, Unix-like teaching operating system](https://pdos.csail.mit.edu/6.828/2017/xv6/book-rev10.pdf)
- 木金で読み会をやる予定です

# systemcall

- `user.h` `usys.S`でそれぞれ定義されていました

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

# printf

- printfは `%d, %x, %p, %s.` のみをサポートしています
- コンパイラ構成論で書いたような素朴な実装でした
- print時の進数は `printint` の引数で分けているようです

```c
void
printf(int fd, char *fmt, ...)
{
  char *s;
  int c, i, state;
  uint *ap;

  state = 0;
  ap = (uint*)(void*)&fmt + 1;
  for(i = 0; fmt[i]; i++){
    c = fmt[i] & 0xff;
    if(state == 0){
      if(c == '%'){
        state = '%';
      } else {
        putc(fd, c);
      }
    } else if(state == '%'){
      if(c == 'd'){
        printint(fd, *ap, 10, 1);
        ap++;
      } else if(c == 'x' || c == 'p'){
        printint(fd, *ap, 16, 0);
        ap++;
      } else if(c == 's'){
        s = (char*)*ap;
        ap++;
        if(s == 0)
          s = "(null)";
        while(*s != 0){
          putc(fd, *s);
          s++;
        }
      } else if(c == 'c'){
        putc(fd, *ap);
        ap++;
      } else if(c == '%'){
        putc(fd, c);
      } else {
        // Unknown % sequence.  Print it to draw attention.
        putc(fd, '%');
        putc(fd, c);
      }
      state = 0;
    }
  }
}
```

# sysemcallを呼ぶ前

- まだ処理が追いきれていません。

```
static void
printint(int fd, int xx, int base, int sgn)
{
  static char digits[] = "0123456789ABCDEF";
  char buf[16];
  int i, neg;
  uint x;

  neg = 0;
  if(sgn && xx < 0){
    neg = 1;
    x = -xx;
  } else {
    x = xx;
  }

  i = 0;
  do{
    buf[i++] = digits[x % base];
  }while((x /= base) != 0);
  if(neg)
    buf[i++] = '-';

  while(--i >= 0)
    putc(fd, buf[i]);
} 
```

# putc

- 素朴にwriteを読んでいる

```
static void
putc(int fd, char c)
{
      write(fd, &c, 1);
}

```

# sh

- main関数
- まずforkが入る
- cd以外はparseしてrunする世界観のようです

```C
int
main(void)
{
  static char buf[100];
  int fd;

  // Ensure that three file descriptors are open.
  while((fd = open("console", O_RDWR)) >= 0){
    if(fd >= 3){
      close(fd);
      break;
    }
  }

  // Read and run input commands.
  while(getcmd(buf, sizeof(buf)) >= 0){
    if(buf[0] == 'c' && buf[1] == 'd' && buf[2] == ' '){
      // Chdir must be called by the parent, not the child.
      buf[strlen(buf)-1] = 0;  // chop \n
      if(chdir(buf+3) < 0)
        printf(2, "cannot cd %s\n", buf+3);
      continue;
    }
    if(fork1() == 0)
      runcmd(parsecmd(buf));
    wait();
  }
  exit();
}
```