Upgrade to Pro — share decks privately, control downloads, hide ads and more …

xv6 initプロセス ことはじめ

Avatar for Toasa Toasa
February 08, 2020

xv6 initプロセス ことはじめ

教育用OS「xv6」のソースコードから、initプロセスの生成と実行を見る。

Avatar for Toasa

Toasa

February 08, 2020
Tweet

Other Decks in Programming

Transcript

  1. xv6

  2. xv6とは? - 教育用OS - Unix v6インスパイア - ANSI Cで書かれた -

    x86上で動く - https://github.com/mit-pdos/xv6-public
  3. 何故xv6? • 学習用途 ◦ ANSI Cで書かれている ◦ 総行数約8500行(.c or .S)

    ▪ ヘッダファイル含めても1万行いかない ◦ 教科書がある https://pdos.csail.mit.edu/6.828/2018/xv6/book-rev11.pdf
  4. catコマンド void cat(int fd) { int n; while((n = read(fd,

    buf, sizeof(buf))) > 0) { if (write(1, buf, n) != n) { printf(1, "cat: write error\n"); exit(); } } if(n < 0){ printf(1, "cat: read error\n"); exit(); } }
  5. proc構造体(一部) struct proc { pde_t* pgdir; char *kstack; enum procstate

    state; int pid; struct proc *parent; struct trapframe *tf; struct context *context; };
  6. proc構造体 struct proc { pde_t* pgdir; char *kstack; enum procstate

    state; int pid; struct proc *parent; struct trapframe *tf; struct context *context; }; context tf parent pid state kstack pgdir high
  7. userinit() void userinit(void) { struct proc *p; p = allocproc();

    if((p->pgdir = setupkvm()) == 0) panic("userinit: out of memory?"); inituvm(p->pgdir, _binary_initcode_start, _binary_initcode_size); ..... }
  8. allocproc static struct proc* allocproc(void) { struct proc *p; for

    (p = ptable.proc; p < &ptable.proc[NPROC]; p++) if(p->state == UNUSED) goto found; return 0; found: ... }
  9. allocproc(つづき) static struct proc* allocproc(void) { ... found: p->state =

    EMBRYO; p->pid = nextpid++; p->kstack = kalloc(); ... }
  10. context tf parent pid = 1 state = EMBRYO kstack

    pgdir 4096B (= 1page) kernel stack
  11. allocproc(つづき) static struct proc* allocproc(void) { sp = p->kstack +

    KSTACKSIZE; // Leave room for trap frame. sp -= sizeof *p->tf; p->tf = (struct trapframe*)sp; kernel stack p->kstack sp
  12. sp allocproc(つづき) static struct proc* allocproc(void) { sp = p->kstack

    + KSTACKSIZE; // Leave room for trap frame. sp -= sizeof *p->tf; p->tf = (struct trapframe*)sp; trap frame p->kstack
  13. sp trapframe分のメモリ確保 static struct proc* allocproc(void) { sp = p->kstack

    + KSTACKSIZE; // Leave room for trap frame. sp -= sizeof *p->tf; p->tf = (struct trapframe*)sp; trap frame p->kstack
  14. allocproc(つづき) static struct proc* allocproc(void) { ... sp -= 4;

    *(uint*)sp = (uint)trapret; sp -= sizeof *p->context; p->context = (struct context*)sp; sp trap frame p->kstack trapret
  15. context分のメモリ確保 static struct proc* allocproc(void) { ... sp -= 4;

    *(uint*)sp = (uint)trapret; sp -= sizeof *p->context; p->context = (struct context*)sp; return p; } kernel stack trap frame trapret context sp
  16. context分のメモリ確保 static struct proc* allocproc(void) { ... sp -= 4;

    *(uint*)sp = (uint)trapret; sp -= sizeof *p->context; p->context = (struct context*)sp; return p; } kernel stack trap frame trapret context sp
  17. allocproc脱出時 context tf parent pid = 1 state = EMBRYO

    kstack pgdir p->kstack kernel stack trap frame trapret context
  18. ふたたび userinit() void userinit(void) { struct proc *p; p =

    allocproc(); if((p->pgdir = setupkvm()) == 0) panic("userinit: out of memory?"); inituvm(p->pgdir, _binary_initcode_start, _binary_initcode_size); ..... }
  19. inituvm void userinit(void) { struct proc *p; p = allocproc();

    if((p->pgdir = setupkvm()) == 0) panic("userinit: out of memory?"); inituvm(p->pgdir, _binary_initcode_start, _binary_initcode_size); ..... }
  20. 下準備完了 kernel stack trapret context 4096B initcode 0 esp eip

    context tf parent pid = 1 state = RUNNABLE kstack pgdir init
  21. scheduler void scheduler(void) { for(;;) { ... for (p =

    ptable.proc; p < &ptable.proc[NPROC]; p++) { if (p->state != RUNNABLE) continue; ... } } }
  22. scheduler void scheduler(void) { for(;;) { ... switchuvm(p); p->state =

    RUNNING; swtch(&(c->scheduler), p->context); switchkvm(); ... } } }
  23. scheduler void scheduler(void) { for(;;) { ... switchuvm(p); p->state =

    RUNNING; swtch(&(c->scheduler), p->context); switchkvm(); ... } } }
  24. scheduler void scheduler(void) { for(;;) { ... switchuvm(p); p->state =

    RUNNING; swtch(&(c->scheduler), p->context); switchkvm(); ... } } }
  25. swtch.S movl 4(%esp), %eax movl 8(%esp), %edx pushl %ebp pushl

    %ebx pushl %esi pushl %edi ... p ->context &(c->scheduler) swtch()の戻り先 edx = esp-> eax =
  26. swtch.S movl 4(%esp), %eax movl 8(%esp), %edx pushl %ebp pushl

    %ebx pushl %esi pushl %edi ... p ->context &(c->scheduler) swtch()の戻り先 ebp ebx edi esi edx = esp-> eax = schedulerの context
  27. swtch.S ... movl %esp, (%eax) movl %edx, %esp popl %edi

    popl %esi popl %ebx popl %ebp ret p ->context &(c->scheduler) swtch()の戻り先 ebp ebx edi esi edx = esp-> eax = 古いコンテキストを 保存
  28. swtch.S ... movl %esp, (%eax) movl %edx, %esp popl %edi

    popl %esi popl %ebx popl %ebp ret p ->context &(c->scheduler) swtch()の戻り先 ebp ebx edi esi edx = esp-> eax = 新しいコンテキストへ スイッチ
  29. swtch.Sのつづき kernel stack trapret eip 4096B initcode 0 esp eip

    esp-> ebp ebx esi edi ... popl %edi popl %esi popl %ebx popl %ebp ret
  30. swtch.Sのつづき kernel stack trapret eip 4096B initcode 0 esp eip

    esp-> ebp ebx esi edi ... popl %edi popl %esi popl %ebx popl %ebp ret
  31. trapret 4096B initcode 0 trapret: popal popl %gs popl %fs

    popl %es popl %ds addl $0x8, %esp iret trape frame edi eax esp-> gs ds trapno err eip esp
  32. trapret 4096B initcode 0 trapret: popal popl %gs popl %fs

    popl %es popl %ds addl $0x8, %esp iret trape frame edi eax esp-> gs ds trapno err eip esp
  33. trapret 4096B initcode 0 trapret: popal popl %gs popl %fs

    popl %es popl %ds addl $0x8, %esp iret trape frame edi eax esp-> gs ds trapno err eip esp
  34. trapret 4096B initcode 0 trapret: popal popl %gs popl %fs

    popl %es popl %ds addl $0x8, %esp iret trape frame edi eax esp-> gs ds trapno err eip esp
  35. 参考文献 • xv6 ◦ https://github.com/mit-pdos/xv6-public • book-rev11.pdf ◦ https://pdos.csail.mit.edu/6.828/2018/xv6/book-rev11.pdf •

    xv6実装の詳解(マルチタスク処理 switching編) ◦ https://qiita.com/knknkn1162/items/0bc9afc3ae304590e16c