{"id":1293,"date":"2012-02-21T07:52:52","date_gmt":"2012-02-20T13:52:52","guid":{"rendered":"http:\/\/peta.okechan.net\/blog\/?p=1293"},"modified":"2012-03-14T11:22:02","modified_gmt":"2012-03-14T02:22:02","slug":"xv6%e3%82%bd%e3%83%bc%e3%82%b9%e3%82%b3%e3%83%bc%e3%83%89%e3%83%aa%e3%83%bc%e3%83%87%e3%82%a3%e3%83%b3%e3%82%b0-%e3%81%9d%e3%81%ae16","status":"publish","type":"post","link":"https:\/\/peta.okechan.net\/blog\/archives\/1293","title":{"rendered":"[xv6 #16] Chapter 1 &#8211; The first process &#8211; Code: Running a process"},"content":{"rendered":"<p>\u30c6\u30ad\u30b9\u30c8\u306e25\u301c27\u30da\u30fc\u30b8<\/p>\n<h3>\u672c\u6587<\/h3>\n<p>\u6700\u521d\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u72b6\u614b\u304c\u6e96\u5099\u3067\u304d\u305f\u3089\u3001\u5b9f\u884c\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3002<br \/>\nmain\u95a2\u6570\u304cuserinit\u95a2\u6570\u3092\u547c\u3093\u3060\u5f8c\u3001\u30d7\u30ed\u30bb\u30b9\u3092\u958b\u59cb\u3059\u308b\u305f\u3081\u306bmpmain\u95a2\u6570\u306fshceduler\u95a2\u6570\u3092\u547c\u3076\u3002<br \/>\nscheduler\u306f\u3001p-&gt;state\u304cRUNNABLE\u306b\u30bb\u30c3\u30c8\u3055\u308c\u305f\u30d7\u30ed\u30bb\u30b9\u3092\u63a2\u3059\u3002<br \/>\n\u3057\u304b\u3057\u3053\u306e\u6642\u70b9\u3067\u306f\u4e00\u3064\u306e\u30d7\u30ed\u30bb\u30b9\u3060\u3051\u304c\u898b\u3064\u304b\u308b\u3002<br \/>\n\u305d\u308c\u306finitproc\u3067\u3042\u308b\u3002<br \/>\n\uff08initproc\u306f\u524d\u56deuserinit\u306e\u4e2d\u3067\u51fa\u3066\u304d\u307e\u3057\u305f\u3002\u5143\u306fproc.c\u306b\u5b9a\u7fa9\u3055\u308c\u3066\u308bstatic\u5909\u6570\uff08proc\u69cb\u9020\u4f53\uff09\u3067\u3059\u3002\uff09<br \/>\ncpu\u3054\u3068\u306e\u5909\u6570proc\u3078\u3001\u898b\u3064\u304b\u3063\u305f\u30d7\u30ed\u30bb\u30b9\u3092\u30bb\u30c3\u30c8\u3057\u3001\u5bfe\u8c61\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30da\u30fc\u30b8\u30c6\u30fc\u30d6\u30eb\u3092\u4f7f\u3046\u3053\u3068\u3092\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u306b\u4f1d\u3048\u308b\u305f\u3081\u306bswitchuvm\u95a2\u6570\u3092\u547c\u3076\u3002<br \/>\nswitchkvm\u95a2\u6570\u306f\u3001\u30ab\u30fc\u30cd\u30eb\u306e\u30b3\u30fc\u30c9\u3068\u30c7\u30fc\u30bf\u306e\u305f\u3081\u306e\u540c\u4e00\u306e\u30de\u30c3\u30d4\u30f3\u30b0\u3092\u5168\u3066\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30da\u30fc\u30b8\u30c6\u30fc\u30d6\u30eb\u306b\u6301\u305f\u305b\u308b\u3088\u3046\u306b\u3059\u308b\u306e\u3067\u3001\u30ab\u30fc\u30cd\u30eb\u3092\u5b9f\u884c\u4e2d\u306b\u30da\u30fc\u30b8\u30c6\u30fc\u30d6\u30eb\u3092\u5207\u308a\u66ff\u3048\u308b\u4e8b\u304c\u51fa\u6765\u308b\u3002<br \/>\nswitchuvm\u95a2\u6570\u3082\u307e\u305f\u3001\u65b0\u3057\u3044\u30bf\u30b9\u30af\u72b6\u614b\u30bb\u30b0\u30e1\u30f3\u30c8\uff08task state segment\uff09SEG_TSS\u3092\u751f\u6210\u3059\u308b\u3002<br \/>\n\u305d\u308c\u306f\u3001%ss\u3078SEG_KDATA&lt;&lt;3\u3092\u3001%esp\u3078(uint)proc-&gt;kstack+KSTACKSIZE\uff08\u305d\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30bf\u30c3\u30af\u306e\u4e00\u756a\u4e0a\uff09\u3092\u30bb\u30c3\u30c8\u3059\u308b\u3053\u3068\u306b\u3088\u3063\u3066\u30ab\u30fc\u30cd\u30eb\u30e2\u30fc\u30c9\u3078\u306e\u79fb\u884c\u306b\u3088\u308b\u5272\u308a\u8fbc\u307f\u3092\u5236\u5fa1\u3059\u308b\u305f\u3081\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u3068\u5bfe\u8a71\u3059\u308b\u3002<br \/>\n\u30bf\u30b9\u30af\u72b6\u614b\u30bb\u30b0\u30e1\u30f3\u30c8\u306b\u3064\u3044\u3066\u306f\u7b2c2\u7ae0\u3067\u307e\u305f\u8aac\u660e\u3059\u308b\u3002<\/p>\n<p>main.c\u306empmain\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/ Common CPU setup code.\nstatic void\nmpmain(void)\n{\n  cprintf(&quot;cpu%d: starting\\n&quot;, cpu-&gt;id);\n  idtinit();       \/\/ load idt register\n  xchg(&amp;cpu-&gt;started, 1); \/\/ tell startothers() we&#039;re up\n  scheduler();     \/\/ start running processes\n}<\/pre>\n<p>proc.c\u306escheduler\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/PAGEBREAK: 42\n\/\/ Per-CPU process scheduler.\n\/\/ Each CPU calls scheduler() after setting itself up.\n\/\/ Scheduler never returns.  It loops, doing:\n\/\/  - choose a process to run\n\/\/  - swtch to start running that process\n\/\/  - eventually that process transfers control\n\/\/      via swtch back to the scheduler.\nvoid\nscheduler(void)\n{\n  struct proc *p;\n\n  for(;;){\n    \/\/ Enable interrupts on this processor.\n    sti();\n\n    \/\/ Loop over process table looking for process to run.\n    acquire(&amp;ptable.lock);\n    for(p = ptable.proc; p &lt; &amp;ptable.proc&amp;#91;NPROC&amp;#93;; p++){\n      if(p-&gt;state != RUNNABLE)\n        continue;\n\n      \/\/ Switch to chosen process.  It is the process&#039;s job\n      \/\/ to release ptable.lock and then reacquire it\n      \/\/ before jumping back to us.\n      proc = p;\n      switchuvm(p);\n      p-&gt;state = RUNNING;\n      swtch(&amp;cpu-&gt;scheduler, proc-&gt;context);\n      switchkvm();\n\n      \/\/ Process is done running for now.\n      \/\/ It should have changed its p-&gt;state before coming back.\n      proc = 0;\n    }\n    release(&amp;ptable.lock);\n\n  }\n}\n<\/pre>\n<p>vm.c\u306eswitchuvm\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/ Switch TSS and h\/w page table to correspond to process p.\nvoid\nswitchuvm(struct proc *p)\n{\n  pushcli();\n  cpu-&gt;gdt&#x5B;SEG_TSS] = SEG16(STS_T32A, &amp;cpu-&gt;ts, sizeof(cpu-&gt;ts)-1, 0);\n  cpu-&gt;gdt&#x5B;SEG_TSS].s = 0;\n  cpu-&gt;ts.ss0 = SEG_KDATA &lt;&lt; 3;\n  cpu-&gt;ts.esp0 = (uint)proc-&gt;kstack + KSTACKSIZE;\n  ltr(SEG_TSS &lt;&lt; 3);\n  if(p-&gt;pgdir == 0)\n    panic(&quot;switchuvm: no pgdir&quot;);\n  lcr3(v2p(p-&gt;pgdir));  \/\/ switch to new address space\n  popcli();\n}<\/pre>\n<p>\u305d\u3057\u305f\u3089scheduler\u306fp-&gt;state\u3092RUNNING\u306b\u30bb\u30c3\u30c8\u3057\u3001\u5207\u66ff\u5148\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30ec\u30c3\u30c9\u3078\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u30b9\u30a4\u30c3\u30c1\u3055\u305b\u308b\u305f\u3081\u306bswtch\u3092\u547c\u3076\u3002<br \/>\n\uff08switch\u3058\u3083\u306a\u304f\u3066swtch\u306a\u306e\u3067\u6ce8\u610f\u3002\u4ee5\u524dswitch\u3063\u3066\u66f8\u3044\u3066\u308b\u90e8\u5206\u304c\u3042\u3063\u305f\u304b\u3082\u3002C\u306e\u4e88\u7d04\u8a9e\u3068\u88ab\u3089\u306a\u3044\u3088\u3046\u306b\u3059\u308b\u305f\u3081\u3067\u3059\u304b\u306d\uff09<br \/>\nswtch\u306f\u73fe\u5728\u306e\u30ec\u30b8\u30b9\u30bf\u3092\u4fdd\u5b58\u3057\u3001\u5bfe\u8c61\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30ec\u30c3\u30c9\u306e\u4fdd\u5b58\u3055\u308c\u305f\u30ec\u30b8\u30b9\u30bf\uff08proc-&gt;context\uff09\u3092x86\u306e\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u306e\u30ec\u30b8\u30b9\u30bf\u306b\u30ed\u30fc\u30c9\u3059\u308b\u3002<br \/>\n\u305d\u308c\u306f\u3001\u30b9\u30bf\u30c3\u30af\u30dd\u30a4\u30f3\u30bf\u3068\u547d\u4ee4\u30dd\u30a4\u30f3\u30bf\u3092\u542b\u3080\u3002<br \/>\n\u73fe\u5728\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306f\u3001\u30d7\u30ed\u30bb\u30b9\u3067\u306f\u306a\u304f\u3001CPU\u3054\u3068\u306e\u7279\u5225\u306a\u30b9\u30b1\u30b8\u30e5\u30fc\u30e9\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3067\u3042\u308b\u306e\u3067\u3001scheduler\u306f\u3069\u3053\u304b\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30ec\u30c3\u30c9\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306e\u4e2d\u3067\u306f\u306a\u304f\u3001CPU\u3054\u3068\u306e\u30b9\u30c8\u30ec\u30fc\u30b8\uff08cpu-&gt;scheduler\uff09\u306e\u4e2d\u306b\u73fe\u5728\u306e\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u30ec\u30b8\u30b9\u30bf\u3092\u4fdd\u5b58\u3059\u308b\u3088\u3046swtch\u306b\u4f1d\u3048\u308b\u3002<br \/>\n\u7b2c4\u7ae0\u3067\u306e\u305d\u306e\u5207\u66ff\u306b\u3064\u3044\u3066\u306e\u3088\u308a\u8a73\u7d30\u306a\u8aac\u660e\u3092\u884c\u3046\u3002<br \/>\n\u6700\u5f8c\u306eret\u547d\u4ee4\uff08swtch\u306e\u6700\u5f8c\uff09\u306f\u30b9\u30bf\u30c3\u30af\u304b\u3089\u65b0\u3057\u3044%eip\u3092\u53d6\u308a\u51fa\u3057\u3001\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u30b9\u30a4\u30c3\u30c1\u3092\u5b8c\u4e86\u3055\u305b\u308b\u3002<br \/>\n\u305d\u3046\u3084\u3063\u3066\u3001\u30d7\u30ed\u30bb\u30c3\u30b5\u306f\u3001\u30d7\u30ed\u30bb\u30b9p\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30ec\u30c3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u3044\u308b\u72b6\u614b\u306b\u306a\u308b\u3002<\/p>\n<p>swtch.S<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\"># Context switch\n#\n#   void swtch(struct context **old, struct context *new);\n# \n# Save current register context in old\n# and then load register context from new.\n\n.globl swtch\nswtch:\n  movl 4(%esp), %eax\n  movl 8(%esp), %edx\n\n  # Save old callee-save registers\n  pushl %ebp\n  pushl %ebx\n  pushl %esi\n  pushl %edi\n\n  # Switch stacks\n  movl %esp, (%eax)\n  movl %edx, %esp\n\n  # Load new callee-save registers\n  popl %edi\n  popl %esi\n  popl %ebx\n  popl %ebp\n  ret<\/pre>\n<p>allocproc\u306finitproc\u306ep-&gt;context-&gt;eip\u3092forkret\u306b\u8a2d\u5b9a\u3059\u308b\u306e\u3067\u3001ret\u306fforkret\u304b\u3089\u518d\u958b\u3059\u308b\u3002<br \/>\nforkret\u306fptable.lock\u3092\u89e3\u653e\u3059\u308b\u3002\uff08\u8a73\u3057\u304f\u306f\u7b2c3\u7ae0\uff09<br \/>\n\u6700\u521d\u306e\u547c\u3073\u51fa\u3057\u3067\u306f\uff08\u3053\u308c\u304c\u305d\u308c\u3060\u304c\uff09\u3001forkret\u95a2\u6570\u306f\u3001main\u95a2\u6570\u304b\u3089\u306f\u5b9f\u884c\u51fa\u6765\u306a\u3044\u521d\u671f\u5316\u51e6\u7406\u3092\u5b9f\u884c\u3059\u308b\u3002<br \/>\n\u306a\u305cmain\u95a2\u6570\u304b\u3089\u5b9f\u884c\u3067\u304d\u306a\u3044\u304b\u3068\u3044\u3046\u3068\u3001\u305d\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30bf\u30c3\u30af\u3068\u3068\u3082\u306b\u901a\u5e38\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3067\u5b9f\u884c\u3055\u308c\u306a\u3051\u308c\u3070\u306a\u3089\u306a\u3044\u304b\u3089\u3067\u3042\u308b\u3002<br \/>\n\u305d\u3057\u3066\u3001forkret\u304b\u3089\u8fd4\u308b\u3002<br \/>\nallocproc\u306f\u30b9\u30bf\u30c3\u30af\u4e0a\u3067p-&gt;context\u306e\u5f8c\u306b\u914d\u7f6e\u3057\u305f\u306e\u3067\u3001\u53d6\u308a\u51fa\u3055\u308c\u305f\u5f8c\u306ftrapret\u304c\u30c8\u30c3\u30d7\u306b\u306a\u308b\u3002<br \/>\n\u305d\u308c\u3067trapret\u306f%esp\u3078p-&gt;tf\u3092\u8a2d\u5b9a\u3057\u3064\u3064\u5b9f\u884c\u3092\u958b\u59cb\u3059\u308b\u3002<br \/>\ntrapret\u306f\u3001\u30ab\u30fc\u30cd\u30eb\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3068\u5171\u306bswtch\u304c\u3057\u305f\u3088\u3046\u306b\u3001\u30c8\u30e9\u30c3\u30d7\u30d5\u30ec\u30fc\u30e0\u3092\u767b\u3063\u3066\u3044\u304f\u305f\u3081\u306bpop\u547d\u4ee4\u3092\u4f7f\u3046\u3002<br \/>\n\uff08\u8b0e\uff09<br \/>\n\u305d\u3057\u3066\u3001popal\u547d\u4ee4\u306f\u3001\u666e\u901a\u306e\u30ec\u30b8\u30b9\u30bf\u3092\u5fa9\u5143\u3057\u3001popl\u547d\u4ee4\u3067%gs, %fs, %es, %ds\u3092\u5fa9\u5143\u3059\u308b\u3002<br \/>\ntrapno\u3068errcode\u306e\u4e8c\u3064\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u98db\u3070\u3059\u305f\u3081\u306baddl\u3092\u4f7f\u3063\u3066\u308b\u3002<br \/>\n\u6700\u5f8c\u306b\u3001iret\u547d\u4ee4\u3067\u3001\u30b9\u30bf\u30c3\u30af\u304b\u3089%cs, %eip, %flags\u3092\u53d6\u308a\u9664\u304f\u3002<br \/>\n\u30c8\u30e9\u30c3\u30d7\u30d5\u30ec\u30fc\u30e0\u306e\u5185\u5bb9\u306f\u3001CPU\u306b\u8ee2\u9001\u3055\u308c\u305f\u3002<br \/>\n\u3060\u304b\u3089\u30d7\u30ed\u30bb\u30c3\u30b5\u306f\u30c8\u30e9\u30c3\u30d7\u30d5\u30ec\u30fc\u30e0\u3067\u6307\u5b9a\u3055\u308c\u305f%eip\u304b\u3089\u7d9a\u884c\u3059\u308b\u3002<br \/>\ninitproc\u306b\u3064\u3044\u3066\u306f\u3001\u3053\u308c\u306f\u4eee\u60f3\u30a2\u30c9\u30ec\u30b90\u3001initcode.S\u306e\u6700\u521d\u306e\u547d\u4ee4\u3092\u610f\u5473\u3059\u308b\u3002<br \/>\n\uff08initcode.S\u306f\u4ee5\u524d\u51fa\u3066\u304d\u307e\u3057\u305f\u306d\u3002\uff09<\/p>\n<p>proc.c\u306eallocproc\u95a2\u6570\uff08\u524d\u56de\u3082\u8f09\u305b\u3066\u307e\u3059\uff09<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/PAGEBREAK: 32\n\/\/ Look in the process table for an UNUSED proc.\n\/\/ If found, change state to EMBRYO and initialize\n\/\/ state required to run in the kernel.\n\/\/ Otherwise return 0.\nstatic struct proc*\nallocproc(void)\n{\n  struct proc *p;\n  char *sp;\n\n  acquire(&amp;ptable.lock);\n  for(p = ptable.proc; p &lt; &amp;ptable.proc&amp;#91;NPROC&amp;#93;; p++)\n    if(p-&gt;state == UNUSED)\n      goto found;\n  release(&amp;ptable.lock);\n  return 0;\n\nfound:\n  p-&gt;state = EMBRYO;\n  p-&gt;pid = nextpid++;\n  release(&amp;ptable.lock);\n\n  \/\/ Allocate kernel stack.\n  if((p-&gt;kstack = kalloc()) == 0){\n    p-&gt;state = UNUSED;\n    return 0;\n  }\n  sp = p-&gt;kstack + KSTACKSIZE;\n  \n  \/\/ Leave room for trap frame.\n  sp -= sizeof *p-&gt;tf;\n  p-&gt;tf = (struct trapframe*)sp;\n  \n  \/\/ Set up new context to start executing at forkret,\n  \/\/ which returns to trapret.\n  sp -= 4;\n  *(uint*)sp = (uint)trapret;\n\n  sp -= sizeof *p-&gt;context;\n  p-&gt;context = (struct context*)sp;\n  memset(p-&gt;context, 0, sizeof *p-&gt;context);\n  p-&gt;context-&gt;eip = (uint)forkret;\n\n  return p;\n}\n<\/pre>\n<p>proc.c\u306eforkret\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/ A fork child's very first scheduling by scheduler()\n\/\/ will swtch here.  \"Return\" to user space.\nvoid\nforkret(void)\n{\n  static int first = 1;\n  \/\/ Still holding ptable.lock from scheduler.\n  release(&ptable.lock);\n\n  if (first) {\n    \/\/ Some initialization functions must be run in the context\n    \/\/ of a regular process (e.g., they call sleep), and thus cannot \n    \/\/ be run from main().\n    first = 0;\n    initlog();\n  }\n  \n  \/\/ Return to \"caller\", actually trapret (see allocproc).\n}<\/pre>\n<p>trapasm.S\u306etrapret<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">  # Return falls through to trapret...\n.globl trapret\ntrapret:\n  popal\n  popl %gs\n  popl %fs\n  popl %es\n  popl %ds\n  addl $0x8, %esp  # trapno and errcode\n  iret<\/pre>\n<p>\u3053\u306e\u70b9\u3067\u306f\u3001%eip\u306f\u30bc\u30ed\u3092\u4fdd\u6301\u3057\u3001%esp\u306f4096\u3092\u4fdd\u6301\u3059\u308b\u3002<br \/>\n\u305d\u308c\u3089\u306f\u3001\u30d7\u30ed\u30bb\u30b9\u306e\u30a2\u30c9\u30ec\u30b9\u7a7a\u9593\u306b\u304a\u3051\u308b\u4eee\u60f3\u30a2\u30c9\u30ec\u30b9\u3067\u3042\u308b\u3002<br \/>\n\u30d7\u30ed\u30bb\u30c3\u30b5\u306e\u30da\u30fc\u30b8\u30f3\u30b0\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u306f\u3001\u305d\u308c\u3089\u3092\u7269\u7406\u30a2\u30c9\u30ec\u30b9\u306b\u7ffb\u8a33\u3059\u308b\u3002<br \/>\nallocuvm\u95a2\u6570\u306f\u3001\u3053\u306e\u30d7\u30ed\u30bb\u30b9\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u7269\u7406\u30e1\u30e2\u30ea\u3092\u6307\u3059\u305f\u3081\u306e\u4eee\u60f3\u30a2\u30c9\u30ec\u30b9\u30bc\u30ed\u306e\u30da\u30fc\u30b8\u306ePTE\u3092\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3057\u3001\u305d\u306ePTE\u3092\u305d\u306e\u30d7\u30ed\u30bb\u30b9\u304c\u4f7f\u3048\u308b\u3088\u3046\u306bPTE_U\u3067\u30de\u30fc\u30af\u3059\u308b\u3002<br \/>\nPTE_U\u304c\u30bb\u30c3\u30c8\u3055\u308c\u305fPTE\u306f\u305d\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30da\u30fc\u30b8\u30c6\u30fc\u30d6\u30eb\u3067\u306f\u4ed6\u306b\u306f\u5b58\u5728\u3057\u306a\u3044\u3002<br \/>\nuserinit\u304c\u3001\u30d7\u30ed\u30bb\u30b9\u306e\u30e6\u30fc\u30b6\u30b3\u30fc\u30c9\u3092CPL=3\u3067\u5b9f\u884c\u3059\u308b\u305f\u3081\u306b%cs\u306e\u4e0b\u4f4d\u30d3\u30c3\u30c8\u3092\u8a2d\u5b9a\u3059\u308b\u3068\u3044\u3046\u4e8b\u5b9f\u306f\u3001\u30e6\u30fc\u30b6\u30b3\u30fc\u30c9\u304c\u3001PTE_U\u304c\u30bb\u30c3\u30c8\u3055\u308c\u305fPTE\u3060\u3051\u3092\u4f7f\u3048\u3066\u3001\u305d\u3057\u3066%cr3\u306e\u3088\u3046\u306a\u6a5f\u5bc6\u6271\u3044\u306e\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u30ec\u30b8\u30b9\u30bf\u3092\u5909\u66f4\u51fa\u6765\u306a\u3044\u3068\u3044\u3046\u4e8b\u306b\u306a\u308b\u3002<br \/>\n\uff08CPL: Current Privilege level \u73fe\u5728\u306e\u7279\u6a29\u30ec\u30d9\u30eb\u306e\u4e8b\u304b\u3068\uff09<br \/>\n\u306a\u306e\u3067\u3001\u30d7\u30ed\u30bb\u30b9\u306f\u81ea\u5206\u81ea\u8eab\u306e\u30e1\u30e2\u30ea\u3092\u4f7f\u3046\u3053\u3068\u3092\u5f37\u5236\u3055\u308c\u308b\u3002<\/p>\n<p>proc.c\u306euserinit\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/PAGEBREAK: 32\n\/\/ Set up first user process.\nvoid\nuserinit(void)\n{\n  struct proc *p;\n  extern char _binary_initcode_start&#x5B;], _binary_initcode_size&#x5B;];\n  \n  p = allocproc();\n  initproc = p;\n  if((p-&gt;pgdir = setupkvm(kalloc)) == 0)\n    panic(&quot;userinit: out of memory?&quot;);\n  inituvm(p-&gt;pgdir, _binary_initcode_start, (int)_binary_initcode_size);\n  p-&gt;sz = PGSIZE;\n  memset(p-&gt;tf, 0, sizeof(*p-&gt;tf));\n  p-&gt;tf-&gt;cs = (SEG_UCODE &lt;&lt; 3) | DPL_USER;\n  p-&gt;tf-&gt;ds = (SEG_UDATA &lt;&lt; 3) | DPL_USER;\n  p-&gt;tf-&gt;es = p-&gt;tf-&gt;ds;\n  p-&gt;tf-&gt;ss = p-&gt;tf-&gt;ds;\n  p-&gt;tf-&gt;eflags = FL_IF;\n  p-&gt;tf-&gt;esp = PGSIZE;\n  p-&gt;tf-&gt;eip = 0;  \/\/ beginning of initcode.S\n\n  safestrcpy(p-&gt;name, &quot;initcode&quot;, sizeof(p-&gt;name));\n  p-&gt;cwd = namei(&quot;\/&quot;);\n\n  p-&gt;state = RUNNABLE;\n}<\/pre>\n<p>initcode.S\u306f\u3001$argv, $init, $0\u306e3\u3064\u306e\u5024\u3092\u30b9\u30bf\u30c3\u30af\u306b\u30d7\u30c3\u30b7\u30e5\u3059\u308b\u3053\u3068\u304b\u3089\u306f\u3058\u3081\u3001%eax\u306bSYS_exec\u3092\u30bb\u30c3\u30c8\u3057\u3001int T_SYSCALL\u3092\u5b9f\u884c\u3059\u308b\u3002<br \/>\n\u305d\u308c\u306f\u3001exec\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u3092\u5b9f\u884c\u3059\u308b\u305f\u3081\u306b\u30ab\u30fc\u30cd\u30eb\u306b\u4f1d\u3048\u308b\u3002<br \/>\n\u3082\u3057\u3059\u3079\u3066\u3046\u307e\u304f\u884c\u3063\u305f\u3089\u3001exec\u306f\u6c7a\u3057\u3066\u623b\u3089\u306a\u3044\u3002<br \/>\n$init\u3068\u3044\u3046\u540d\u524d\u304c\u4ed8\u3051\u3089\u308c\u305f\u30d7\u30ed\u30b0\u30e9\u30e0\u306e\u5b9f\u884c\u3092\u958b\u59cb\u3059\u308b\u3002<br \/>\n$init\u306f\u3001&#8221;\/init&#8221;\u3068\u3044\u3046NUL\u7d42\u7aef\u6587\u5b57\u5217\u3078\u306e\u30dd\u30a4\u30f3\u30bf\u3067\u3042\u308b\u3002<br \/>\n\u3082\u3057exec\u304c\u5931\u6557\u3057\u623b\u3063\u3066\u304d\u305f\u3068\u304d\u306f\u3001\u78ba\u5b9f\u306b\u623b\u3089\u306a\u3044\u3088\u3046\u306b\u3059\u308b\u305f\u3081\u306binitcode\u306fexit\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u3092\u547c\u3073\u3064\u3065\u3051\u308b\u3002<\/p>\n<p>initcode.S<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\"># Initial process execs \/init.\n\n#include \"syscall.h\"\n#include \"traps.h\"\n\n\n# exec(init, argv)\n.globl start\nstart:\n  pushl $argv\n  pushl $init\n  pushl $0  \/\/ where caller pc would be\n  movl $SYS_exec, %eax\n  int $T_SYSCALL\n\n# for(;;) exit();\nexit:\n  movl $SYS_exit, %eax\n  int $T_SYSCALL\n  jmp exit\n\n# char init&#x5B;] = \"\/init&#92;&#48;\";\ninit:\n  .string \"\/init&#92;&#48;\"\n\n# char *argv&#x5B;] = { init, 0 };\n.p2align 2\nargv:\n  .long init\n  .long 0<\/pre>\n<p>exec\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u3078\u306e\u5f15\u6570\u306f\u3001$init\u3068$argv\u3067\u3042\u308b\u3002<br \/>\n\u6700\u5f8c\u306e$0\u306f\u3001\u3053\u306e\u624b\u66f8\u304d\u306e\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u3092\u901a\u5e38\u306e\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u306b\u898b\u305b\u304b\u3051\u308b\u305f\u3081\u306b\u3042\u308b\u3002<br \/>\n\u305d\u306e\u8fba\u306e\u8a73\u3057\u3044\u3053\u3068\u306f\u7b2c2\u7ae0\u3067\u3002<br \/>\n\u524d\u306e\u901a\u308a\u3001\u3053\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u306f\u3001\u6700\u521d\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u7279\u5225\u306a\u3084\u308a\u65b9\uff08\u305d\u306e\u5834\u5408\u3001\u305d\u308c\u304c\u6700\u521d\u306e\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u3067\u3042\u308b\uff09\u306f\u907f\u3051\u3066\u3044\u308b\u3002<br \/>\n\u305d\u306e\u4ee3\u308f\u308a\u3001\u57fa\u672c\u7684\u306a\u64cd\u4f5c\u306e\u305f\u3081\u306bxv6\u304c\u63d0\u4f9b\u3059\u3079\u304d\u30b3\u30fc\u30c9\u3092\u518d\u5229\u7528\u3059\u308b\u3002<\/p>\n<h3>\u611f\u60f3<\/h3>\n<p>\u3053\u308c\u3067\u3084\u3063\u3068\u6700\u521d\u306e\u30d7\u30ed\u30bb\u30b9initcode\u304c\u5b9f\u884c\u3067\u304d\u305f\u3063\u3066\u3068\u3053\u308d\u3067\u3059\u304b\u306d\u3002<\/p>\n<p>mpmain\u306f\u8ad6\u7406CPU\u3054\u3068\u306b\u5b9f\u884c\u3055\u308c\u308b\u307f\u305f\u3044\u306a\u306e\u3067\u3001\u30b9\u30b1\u30b8\u30e5\u30fc\u30e9\u3082\u8ad6\u7406CPU\u3054\u3068\u306b\u5b9f\u884c\u3055\u308c\u308b\u307f\u305f\u3044\u3067\u3059\u306d\u3002<br \/>\n\u30de\u30eb\u30c1\u30d7\u30ed\u30bb\u30c3\u30b5\u95a2\u9023\u306e\u8a71\u306f\u5f8c\u3067\u51fa\u3066\u304f\u308b\u3093\u3067\u3057\u3087\u3046\u3002<\/p>\n<p>\u6b63\u76f4\u534a\u5206\u3082\u7406\u89e3\u3067\u304d\u3066\u306a\u3044\u611f\u3058\u3067\u3059\u3002<br \/>\n\u7406\u89e3\u3057\u3066\u3044\u308b\u3064\u3082\u308a\u306e\u90e8\u5206\u306b\u95a2\u3057\u3066\u3082\u81ea\u4fe1\u306f\u306a\u3044\u3067\u3059\u3002<br \/>\n\u305f\u3060\u307e\u3060\u6700\u521d\u306e\u30d7\u30ed\u30bb\u30b9\u304c\u8d77\u52d5\u3059\u308b\u307e\u3067\u306b\u3064\u3044\u3066\u306e\u7ae0\u306a\u306e\u3067\u3001\u305d\u308c\u4ee5\u5916\u306e\u90e8\u5206\u304c\u307e\u3060\u6982\u8981\u30ec\u30d9\u30eb\u306e\u8aac\u660e\u306b\u3068\u3069\u307e\u3063\u3066\u308b\u3068\u3044\u3046\u306e\u3082\u3042\u308b\u304b\u3068\u601d\u3044\u307e\u3059\u3002<br \/>\n\u3068\u308a\u3042\u3048\u305a\u3053\u306e\u307e\u307e\u8aad\u307f\u7d9a\u3051\u3066\u5168\u4f53\u304c\u898b\u3048\u308b\u3088\u3046\u306b\u306a\u308c\u3070\u7406\u89e3\u304c\u6df1\u307e\u308b\u306f\u305a\u3060\u3068\u601d\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u30c6\u30ad\u30b9\u30c8\u306e25\u301c27\u30da\u30fc\u30b8<\/p>\n<h3>\u672c\u6587<\/h3>\n<p>\u6700\u521d\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u72b6\u614b\u304c\u6e96\u5099\u3067\u304d\u305f\u3089\u3001\u5b9f\u884c\u3059\u308b\u3053\u3068\u304c\u3067\u304d\u308b\u3002<br \/>\nmain\u95a2\u6570\u304cuserinit\u95a2\u6570\u3092\u547c\u3093\u3060\u5f8c\u3001\u30d7\u30ed\u30bb\u30b9\u3092\u958b\u59cb\u3059\u308b\u305f\u3081\u306bmpmain\u95a2\u6570\u306fshceduler\u95a2\u6570\u3092\u547c\u3076\u3002<br \/>\nscheduler\u306f\u3001p-&gt;state\u304cRUNNABLE\u306b\u30bb\u30c3\u30c8\u3055\u308c\u305f\u30d7\u30ed\u30bb\u30b9\u3092\u63a2\u3059\u3002<br \/>\n\u3057\u304b\u3057\u3053\u306e\u6642\u70b9\u3067\u306f\u4e00\u3064\u306e\u30d7\u30ed\u30bb\u30b9\u3060\u3051\u304c\u898b\u3064\u304b\u308b\u3002<br \/>\n\u305d\u308c\u306finitproc\u3067\u3042\u308b\u3002<br \/>\n\uff08initproc\u306f\u524d\u56deuserinit\u306e\u4e2d\u3067\u51fa\u3066\u304d\u307e\u3057\u305f\u3002\u5143\u306fproc.c\u306b\u5b9a\u7fa9\u3055\u308c\u3066\u308bstatic\u5909\u6570\uff08proc\u69cb\u9020\u4f53\uff09\u3067\u3059\u3002\uff09<br \/>\ncpu\u3054\u3068\u306e\u5909\u6570proc\u3078\u3001\u898b\u3064\u304b\u3063\u305f\u30d7\u30ed\u30bb\u30b9\u3092\u30bb\u30c3\u30c8\u3057\u3001\u5bfe\u8c61\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30da\u30fc\u30b8\u30c6\u30fc\u30d6\u30eb\u3092\u4f7f\u3046\u3053\u3068\u3092\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u306b\u4f1d\u3048\u308b\u305f\u3081\u306bswitchuvm\u95a2\u6570\u3092\u547c\u3076\u3002<br \/>\nswitchkvm\u95a2\u6570\u306f\u3001\u30ab\u30fc\u30cd\u30eb\u306e\u30b3\u30fc\u30c9\u3068\u30c7\u30fc\u30bf\u306e\u305f\u3081\u306e\u540c\u4e00\u306e\u30de\u30c3\u30d4\u30f3\u30b0\u3092\u5168\u3066\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30da\u30fc\u30b8\u30c6\u30fc\u30d6\u30eb\u306b\u6301\u305f\u305b\u308b\u3088\u3046\u306b\u3059\u308b\u306e\u3067\u3001\u30ab\u30fc\u30cd\u30eb\u3092\u5b9f\u884c\u4e2d\u306b\u30da\u30fc\u30b8\u30c6\u30fc\u30d6\u30eb\u3092\u5207\u308a\u66ff\u3048\u308b\u4e8b\u304c\u51fa\u6765\u308b\u3002<br \/>\nswitchuvm\u95a2\u6570\u3082\u307e\u305f\u3001\u65b0\u3057\u3044\u30bf\u30b9\u30af\u72b6\u614b\u30bb\u30b0\u30e1\u30f3\u30c8\uff08task state segment\uff09SEG_TSS\u3092\u751f\u6210\u3059\u308b\u3002<br \/>\n\u305d\u308c\u306f\u3001%ss\u3078SEG_KDATA&lt;&lt;3\u3092\u3001%esp\u3078(uint)proc-&gt;kstack+KSTACKSIZE\uff08\u305d\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30bf\u30c3\u30af\u306e\u4e00\u756a\u4e0a\uff09\u3092\u30bb\u30c3\u30c8\u3059\u308b\u3053\u3068\u306b\u3088\u3063\u3066\u30ab\u30fc\u30cd\u30eb\u30e2\u30fc\u30c9\u3078\u306e\u79fb\u884c\u306b\u3088\u308b\u5272\u308a\u8fbc\u307f\u3092\u5236\u5fa1\u3059\u308b\u305f\u3081\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u3068\u5bfe\u8a71\u3059\u308b\u3002<br \/>\n\u30bf\u30b9\u30af\u72b6\u614b\u30bb\u30b0\u30e1\u30f3\u30c8\u306b\u3064\u3044\u3066\u306f\u7b2c2\u7ae0\u3067\u307e\u305f\u8aac\u660e\u3059\u308b\u3002<\/p>\n<p>main.c\u306empmain\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/ Common CPU setup code.\nstatic void\nmpmain(void)\n{\n  cprintf(&quot;cpu%d: starting\\n&quot;, cpu-&gt;id);\n  idtinit();       \/\/ load idt register\n  xchg(&amp;cpu-&gt;started, 1); \/\/ tell startothers() we&#039;re up\n  scheduler();     \/\/ start running processes\n}<\/pre>\n<p>proc.c\u306escheduler\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/PAGEBREAK: 42\n\/\/ Per-CPU process scheduler.\n\/\/ Each CPU calls scheduler() after setting itself up.\n\/\/ Scheduler never returns.  It loops, doing:\n\/\/  - choose a process to run\n\/\/  - swtch to start running that process\n\/\/  - eventually that process transfers control\n\/\/      via swtch back to the scheduler.\nvoid\nscheduler(void)\n{\n  struct proc *p;\n\n  for(;;){\n    \/\/ Enable interrupts on this processor.\n    sti();\n\n    \/\/ Loop over process table looking for process to run.\n    acquire(&amp;ptable.lock);\n    for(p = ptable.proc; p &lt; &amp;ptable.proc&amp;#91;NPROC&amp;#93;; p++){\n      if(p-&gt;state != RUNNABLE)\n        continue;\n\n      \/\/ Switch to chosen process.  It is the process&#039;s job\n      \/\/ to release ptable.lock and then reacquire it\n      \/\/ before jumping back to us.\n      proc = p;\n      switchuvm(p);\n      p-&gt;state = RUNNING;\n      swtch(&amp;cpu-&gt;scheduler, proc-&gt;context);\n      switchkvm();\n\n      \/\/ Process is done running for now.\n      \/\/ It should have changed its p-&gt;state before coming back.\n      proc = 0;\n    }\n    release(&amp;ptable.lock);\n\n  }\n}\n<\/pre>\n<p>vm.c\u306eswitchuvm\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/ Switch TSS and h\/w page table to correspond to process p.\nvoid\nswitchuvm(struct proc *p)\n{\n  pushcli();\n  cpu-&gt;gdt&#x5B;SEG_TSS] = SEG16(STS_T32A, &amp;cpu-&gt;ts, sizeof(cpu-&gt;ts)-1, 0);\n  cpu-&gt;gdt&#x5B;SEG_TSS].s = 0;\n  cpu-&gt;ts.ss0 = SEG_KDATA &lt;&lt; 3;\n  cpu-&gt;ts.esp0 = (uint)proc-&gt;kstack + KSTACKSIZE;\n  ltr(SEG_TSS &lt;&lt; 3);\n  if(p-&gt;pgdir == 0)\n    panic(&quot;switchuvm: no pgdir&quot;);\n  lcr3(v2p(p-&gt;pgdir));  \/\/ switch to new address space\n  popcli();\n}<\/pre>\n<p>\u305d\u3057\u305f\u3089scheduler\u306fp-&gt;state\u3092RUNNING\u306b\u30bb\u30c3\u30c8\u3057\u3001\u5207\u66ff\u5148\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30ec\u30c3\u30c9\u3078\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u30b9\u30a4\u30c3\u30c1\u3055\u305b\u308b\u305f\u3081\u306bswtch\u3092\u547c\u3076\u3002<br \/>\n\uff08switch\u3058\u3083\u306a\u304f\u3066swtch\u306a\u306e\u3067\u6ce8\u610f\u3002\u4ee5\u524dswitch\u3063\u3066\u66f8\u3044\u3066\u308b\u90e8\u5206\u304c\u3042\u3063\u305f\u304b\u3082\u3002C\u306e\u4e88\u7d04\u8a9e\u3068\u88ab\u3089\u306a\u3044\u3088\u3046\u306b\u3059\u308b\u305f\u3081\u3067\u3059\u304b\u306d\uff09<br \/>\nswtch\u306f\u73fe\u5728\u306e\u30ec\u30b8\u30b9\u30bf\u3092\u4fdd\u5b58\u3057\u3001\u5bfe\u8c61\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30ec\u30c3\u30c9\u306e\u4fdd\u5b58\u3055\u308c\u305f\u30ec\u30b8\u30b9\u30bf\uff08proc-&gt;context\uff09\u3092x86\u306e\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u306e\u30ec\u30b8\u30b9\u30bf\u306b\u30ed\u30fc\u30c9\u3059\u308b\u3002<br \/>\n\u305d\u308c\u306f\u3001\u30b9\u30bf\u30c3\u30af\u30dd\u30a4\u30f3\u30bf\u3068\u547d\u4ee4\u30dd\u30a4\u30f3\u30bf\u3092\u542b\u3080\u3002<br \/>\n\u73fe\u5728\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306f\u3001\u30d7\u30ed\u30bb\u30b9\u3067\u306f\u306a\u304f\u3001CPU\u3054\u3068\u306e\u7279\u5225\u306a\u30b9\u30b1\u30b8\u30e5\u30fc\u30e9\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3067\u3042\u308b\u306e\u3067\u3001scheduler\u306f\u3069\u3053\u304b\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30ec\u30c3\u30c9\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u306e\u4e2d\u3067\u306f\u306a\u304f\u3001CPU\u3054\u3068\u306e\u30b9\u30c8\u30ec\u30fc\u30b8\uff08cpu-&gt;scheduler\uff09\u306e\u4e2d\u306b\u73fe\u5728\u306e\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u30ec\u30b8\u30b9\u30bf\u3092\u4fdd\u5b58\u3059\u308b\u3088\u3046swtch\u306b\u4f1d\u3048\u308b\u3002<br \/>\n\u7b2c4\u7ae0\u3067\u306e\u305d\u306e\u5207\u66ff\u306b\u3064\u3044\u3066\u306e\u3088\u308a\u8a73\u7d30\u306a\u8aac\u660e\u3092\u884c\u3046\u3002<br \/>\n\u6700\u5f8c\u306eret\u547d\u4ee4\uff08swtch\u306e\u6700\u5f8c\uff09\u306f\u30b9\u30bf\u30c3\u30af\u304b\u3089\u65b0\u3057\u3044%eip\u3092\u53d6\u308a\u51fa\u3057\u3001\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u30b9\u30a4\u30c3\u30c1\u3092\u5b8c\u4e86\u3055\u305b\u308b\u3002<br \/>\n\u305d\u3046\u3084\u3063\u3066\u3001\u30d7\u30ed\u30bb\u30c3\u30b5\u306f\u3001\u30d7\u30ed\u30bb\u30b9p\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30ec\u30c3\u30c9\u3092\u5b9f\u884c\u3057\u3066\u3044\u308b\u72b6\u614b\u306b\u306a\u308b\u3002<\/p>\n<p>swtch.S<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\"># Context switch\n#\n#   void swtch(struct context **old, struct context *new);\n# \n# Save current register context in old\n# and then load register context from new.\n\n.globl swtch\nswtch:\n  movl 4(%esp), %eax\n  movl 8(%esp), %edx\n\n  # Save old callee-save registers\n  pushl %ebp\n  pushl %ebx\n  pushl %esi\n  pushl %edi\n\n  # Switch stacks\n  movl %esp, (%eax)\n  movl %edx, %esp\n\n  # Load new callee-save registers\n  popl %edi\n  popl %esi\n  popl %ebx\n  popl %ebp\n  ret<\/pre>\n<p>allocproc\u306finitproc\u306ep-&gt;context-&gt;eip\u3092forkret\u306b\u8a2d\u5b9a\u3059\u308b\u306e\u3067\u3001ret\u306fforkret\u304b\u3089\u518d\u958b\u3059\u308b\u3002<br \/>\nforkret\u306fptable.lock\u3092\u89e3\u653e\u3059\u308b\u3002\uff08\u8a73\u3057\u304f\u306f\u7b2c3\u7ae0\uff09<br \/>\n\u6700\u521d\u306e\u547c\u3073\u51fa\u3057\u3067\u306f\uff08\u3053\u308c\u304c\u305d\u308c\u3060\u304c\uff09\u3001forkret\u95a2\u6570\u306f\u3001main\u95a2\u6570\u304b\u3089\u306f\u5b9f\u884c\u51fa\u6765\u306a\u3044\u521d\u671f\u5316\u51e6\u7406\u3092\u5b9f\u884c\u3059\u308b\u3002<br \/>\n\u306a\u305cmain\u95a2\u6570\u304b\u3089\u5b9f\u884c\u3067\u304d\u306a\u3044\u304b\u3068\u3044\u3046\u3068\u3001\u305d\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30ab\u30fc\u30cd\u30eb\u30b9\u30bf\u30c3\u30af\u3068\u3068\u3082\u306b\u901a\u5e38\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3067\u5b9f\u884c\u3055\u308c\u306a\u3051\u308c\u3070\u306a\u3089\u306a\u3044\u304b\u3089\u3067\u3042\u308b\u3002<br \/>\n\u305d\u3057\u3066\u3001forkret\u304b\u3089\u8fd4\u308b\u3002<br \/>\nallocproc\u306f\u30b9\u30bf\u30c3\u30af\u4e0a\u3067p-&gt;context\u306e\u5f8c\u306b\u914d\u7f6e\u3057\u305f\u306e\u3067\u3001\u53d6\u308a\u51fa\u3055\u308c\u305f\u5f8c\u306ftrapret\u304c\u30c8\u30c3\u30d7\u306b\u306a\u308b\u3002<br \/>\n\u305d\u308c\u3067trapret\u306f%esp\u3078p-&gt;tf\u3092\u8a2d\u5b9a\u3057\u3064\u3064\u5b9f\u884c\u3092\u958b\u59cb\u3059\u308b\u3002<br \/>\ntrapret\u306f\u3001\u30ab\u30fc\u30cd\u30eb\u30b3\u30f3\u30c6\u30ad\u30b9\u30c8\u3068\u5171\u306bswtch\u304c\u3057\u305f\u3088\u3046\u306b\u3001\u30c8\u30e9\u30c3\u30d7\u30d5\u30ec\u30fc\u30e0\u3092\u767b\u3063\u3066\u3044\u304f\u305f\u3081\u306bpop\u547d\u4ee4\u3092\u4f7f\u3046\u3002<br \/>\n\uff08\u8b0e\uff09<br \/>\n\u305d\u3057\u3066\u3001popal\u547d\u4ee4\u306f\u3001\u666e\u901a\u306e\u30ec\u30b8\u30b9\u30bf\u3092\u5fa9\u5143\u3057\u3001popl\u547d\u4ee4\u3067%gs, %fs, %es, %ds\u3092\u5fa9\u5143\u3059\u308b\u3002<br \/>\ntrapno\u3068errcode\u306e\u4e8c\u3064\u306e\u30d5\u30a3\u30fc\u30eb\u30c9\u3092\u98db\u3070\u3059\u305f\u3081\u306baddl\u3092\u4f7f\u3063\u3066\u308b\u3002<br \/>\n\u6700\u5f8c\u306b\u3001iret\u547d\u4ee4\u3067\u3001\u30b9\u30bf\u30c3\u30af\u304b\u3089%cs, %eip, %flags\u3092\u53d6\u308a\u9664\u304f\u3002<br \/>\n\u30c8\u30e9\u30c3\u30d7\u30d5\u30ec\u30fc\u30e0\u306e\u5185\u5bb9\u306f\u3001CPU\u306b\u8ee2\u9001\u3055\u308c\u305f\u3002<br \/>\n\u3060\u304b\u3089\u30d7\u30ed\u30bb\u30c3\u30b5\u306f\u30c8\u30e9\u30c3\u30d7\u30d5\u30ec\u30fc\u30e0\u3067\u6307\u5b9a\u3055\u308c\u305f%eip\u304b\u3089\u7d9a\u884c\u3059\u308b\u3002<br \/>\ninitproc\u306b\u3064\u3044\u3066\u306f\u3001\u3053\u308c\u306f\u4eee\u60f3\u30a2\u30c9\u30ec\u30b90\u3001initcode.S\u306e\u6700\u521d\u306e\u547d\u4ee4\u3092\u610f\u5473\u3059\u308b\u3002<br \/>\n\uff08initcode.S\u306f\u4ee5\u524d\u51fa\u3066\u304d\u307e\u3057\u305f\u306d\u3002\uff09<\/p>\n<p>proc.c\u306eallocproc\u95a2\u6570\uff08\u524d\u56de\u3082\u8f09\u305b\u3066\u307e\u3059\uff09<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/PAGEBREAK: 32\n\/\/ Look in the process table for an UNUSED proc.\n\/\/ If found, change state to EMBRYO and initialize\n\/\/ state required to run in the kernel.\n\/\/ Otherwise return 0.\nstatic struct proc*\nallocproc(void)\n{\n  struct proc *p;\n  char *sp;\n\n  acquire(&amp;ptable.lock);\n  for(p = ptable.proc; p &lt; &amp;ptable.proc&amp;#91;NPROC&amp;#93;; p++)\n    if(p-&gt;state == UNUSED)\n      goto found;\n  release(&amp;ptable.lock);\n  return 0;\n\nfound:\n  p-&gt;state = EMBRYO;\n  p-&gt;pid = nextpid++;\n  release(&amp;ptable.lock);\n\n  \/\/ Allocate kernel stack.\n  if((p-&gt;kstack = kalloc()) == 0){\n    p-&gt;state = UNUSED;\n    return 0;\n  }\n  sp = p-&gt;kstack + KSTACKSIZE;\n  \n  \/\/ Leave room for trap frame.\n  sp -= sizeof *p-&gt;tf;\n  p-&gt;tf = (struct trapframe*)sp;\n  \n  \/\/ Set up new context to start executing at forkret,\n  \/\/ which returns to trapret.\n  sp -= 4;\n  *(uint*)sp = (uint)trapret;\n\n  sp -= sizeof *p-&gt;context;\n  p-&gt;context = (struct context*)sp;\n  memset(p-&gt;context, 0, sizeof *p-&gt;context);\n  p-&gt;context-&gt;eip = (uint)forkret;\n\n  return p;\n}\n<\/pre>\n<p>proc.c\u306eforkret\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/ A fork child's very first scheduling by scheduler()\n\/\/ will swtch here.  \"Return\" to user space.\nvoid\nforkret(void)\n{\n  static int first = 1;\n  \/\/ Still holding ptable.lock from scheduler.\n  release(&ptable.lock);\n\n  if (first) {\n    \/\/ Some initialization functions must be run in the context\n    \/\/ of a regular process (e.g., they call sleep), and thus cannot \n    \/\/ be run from main().\n    first = 0;\n    initlog();\n  }\n  \n  \/\/ Return to \"caller\", actually trapret (see allocproc).\n}<\/pre>\n<p>trapasm.S\u306etrapret<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\">  # Return falls through to trapret...\n.globl trapret\ntrapret:\n  popal\n  popl %gs\n  popl %fs\n  popl %es\n  popl %ds\n  addl $0x8, %esp  # trapno and errcode\n  iret<\/pre>\n<p>\u3053\u306e\u70b9\u3067\u306f\u3001%eip\u306f\u30bc\u30ed\u3092\u4fdd\u6301\u3057\u3001%esp\u306f4096\u3092\u4fdd\u6301\u3059\u308b\u3002<br \/>\n\u305d\u308c\u3089\u306f\u3001\u30d7\u30ed\u30bb\u30b9\u306e\u30a2\u30c9\u30ec\u30b9\u7a7a\u9593\u306b\u304a\u3051\u308b\u4eee\u60f3\u30a2\u30c9\u30ec\u30b9\u3067\u3042\u308b\u3002<br \/>\n\u30d7\u30ed\u30bb\u30c3\u30b5\u306e\u30da\u30fc\u30b8\u30f3\u30b0\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u306f\u3001\u305d\u308c\u3089\u3092\u7269\u7406\u30a2\u30c9\u30ec\u30b9\u306b\u7ffb\u8a33\u3059\u308b\u3002<br \/>\nallocuvm\u95a2\u6570\u306f\u3001\u3053\u306e\u30d7\u30ed\u30bb\u30b9\u306b\u5272\u308a\u5f53\u3066\u3089\u308c\u305f\u7269\u7406\u30e1\u30e2\u30ea\u3092\u6307\u3059\u305f\u3081\u306e\u4eee\u60f3\u30a2\u30c9\u30ec\u30b9\u30bc\u30ed\u306e\u30da\u30fc\u30b8\u306ePTE\u3092\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u3057\u3001\u305d\u306ePTE\u3092\u305d\u306e\u30d7\u30ed\u30bb\u30b9\u304c\u4f7f\u3048\u308b\u3088\u3046\u306bPTE_U\u3067\u30de\u30fc\u30af\u3059\u308b\u3002<br \/>\nPTE_U\u304c\u30bb\u30c3\u30c8\u3055\u308c\u305fPTE\u306f\u305d\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u30da\u30fc\u30b8\u30c6\u30fc\u30d6\u30eb\u3067\u306f\u4ed6\u306b\u306f\u5b58\u5728\u3057\u306a\u3044\u3002<br \/>\nuserinit\u304c\u3001\u30d7\u30ed\u30bb\u30b9\u306e\u30e6\u30fc\u30b6\u30b3\u30fc\u30c9\u3092CPL=3\u3067\u5b9f\u884c\u3059\u308b\u305f\u3081\u306b%cs\u306e\u4e0b\u4f4d\u30d3\u30c3\u30c8\u3092\u8a2d\u5b9a\u3059\u308b\u3068\u3044\u3046\u4e8b\u5b9f\u306f\u3001\u30e6\u30fc\u30b6\u30b3\u30fc\u30c9\u304c\u3001PTE_U\u304c\u30bb\u30c3\u30c8\u3055\u308c\u305fPTE\u3060\u3051\u3092\u4f7f\u3048\u3066\u3001\u305d\u3057\u3066%cr3\u306e\u3088\u3046\u306a\u6a5f\u5bc6\u6271\u3044\u306e\u30cf\u30fc\u30c9\u30a6\u30a7\u30a2\u30ec\u30b8\u30b9\u30bf\u3092\u5909\u66f4\u51fa\u6765\u306a\u3044\u3068\u3044\u3046\u4e8b\u306b\u306a\u308b\u3002<br \/>\n\uff08CPL: Current Privilege level \u73fe\u5728\u306e\u7279\u6a29\u30ec\u30d9\u30eb\u306e\u4e8b\u304b\u3068\uff09<br \/>\n\u306a\u306e\u3067\u3001\u30d7\u30ed\u30bb\u30b9\u306f\u81ea\u5206\u81ea\u8eab\u306e\u30e1\u30e2\u30ea\u3092\u4f7f\u3046\u3053\u3068\u3092\u5f37\u5236\u3055\u308c\u308b\u3002<\/p>\n<p>proc.c\u306euserinit\u95a2\u6570<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/PAGEBREAK: 32\n\/\/ Set up first user process.\nvoid\nuserinit(void)\n{\n  struct proc *p;\n  extern char _binary_initcode_start&#x5B;], _binary_initcode_size&#x5B;];\n  \n  p = allocproc();\n  initproc = p;\n  if((p-&gt;pgdir = setupkvm(kalloc)) == 0)\n    panic(&quot;userinit: out of memory?&quot;);\n  inituvm(p-&gt;pgdir, _binary_initcode_start, (int)_binary_initcode_size);\n  p-&gt;sz = PGSIZE;\n  memset(p-&gt;tf, 0, sizeof(*p-&gt;tf));\n  p-&gt;tf-&gt;cs = (SEG_UCODE &lt;&lt; 3) | DPL_USER;\n  p-&gt;tf-&gt;ds = (SEG_UDATA &lt;&lt; 3) | DPL_USER;\n  p-&gt;tf-&gt;es = p-&gt;tf-&gt;ds;\n  p-&gt;tf-&gt;ss = p-&gt;tf-&gt;ds;\n  p-&gt;tf-&gt;eflags = FL_IF;\n  p-&gt;tf-&gt;esp = PGSIZE;\n  p-&gt;tf-&gt;eip = 0;  \/\/ beginning of initcode.S\n\n  safestrcpy(p-&gt;name, &quot;initcode&quot;, sizeof(p-&gt;name));\n  p-&gt;cwd = namei(&quot;\/&quot;);\n\n  p-&gt;state = RUNNABLE;\n}<\/pre>\n<p>initcode.S\u306f\u3001$argv, $init, $0\u306e3\u3064\u306e\u5024\u3092\u30b9\u30bf\u30c3\u30af\u306b\u30d7\u30c3\u30b7\u30e5\u3059\u308b\u3053\u3068\u304b\u3089\u306f\u3058\u3081\u3001%eax\u306bSYS_exec\u3092\u30bb\u30c3\u30c8\u3057\u3001int T_SYSCALL\u3092\u5b9f\u884c\u3059\u308b\u3002<br \/>\n\u305d\u308c\u306f\u3001exec\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u3092\u5b9f\u884c\u3059\u308b\u305f\u3081\u306b\u30ab\u30fc\u30cd\u30eb\u306b\u4f1d\u3048\u308b\u3002<br \/>\n\u3082\u3057\u3059\u3079\u3066\u3046\u307e\u304f\u884c\u3063\u305f\u3089\u3001exec\u306f\u6c7a\u3057\u3066\u623b\u3089\u306a\u3044\u3002<br \/>\n$init\u3068\u3044\u3046\u540d\u524d\u304c\u4ed8\u3051\u3089\u308c\u305f\u30d7\u30ed\u30b0\u30e9\u30e0\u306e\u5b9f\u884c\u3092\u958b\u59cb\u3059\u308b\u3002<br \/>\n$init\u306f\u3001&#8221;\/init&#8221;\u3068\u3044\u3046NUL\u7d42\u7aef\u6587\u5b57\u5217\u3078\u306e\u30dd\u30a4\u30f3\u30bf\u3067\u3042\u308b\u3002<br \/>\n\u3082\u3057exec\u304c\u5931\u6557\u3057\u623b\u3063\u3066\u304d\u305f\u3068\u304d\u306f\u3001\u78ba\u5b9f\u306b\u623b\u3089\u306a\u3044\u3088\u3046\u306b\u3059\u308b\u305f\u3081\u306binitcode\u306fexit\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u3092\u547c\u3073\u3064\u3065\u3051\u308b\u3002<\/p>\n<p>initcode.S<\/p>\n<pre class=\"brush: plain; title: ; notranslate\" title=\"\"># Initial process execs \/init.\n\n#include \"syscall.h\"\n#include \"traps.h\"\n\n\n# exec(init, argv)\n.globl start\nstart:\n  pushl $argv\n  pushl $init\n  pushl $0  \/\/ where caller pc would be\n  movl $SYS_exec, %eax\n  int $T_SYSCALL\n\n# for(;;) exit();\nexit:\n  movl $SYS_exit, %eax\n  int $T_SYSCALL\n  jmp exit\n\n# char init&#x5B;] = \"\/init&#92;&#48;\";\ninit:\n  .string \"\/init&#92;&#48;\"\n\n# char *argv&#x5B;] = { init, 0 };\n.p2align 2\nargv:\n  .long init\n  .long 0<\/pre>\n<p>exec\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u3078\u306e\u5f15\u6570\u306f\u3001$init\u3068$argv\u3067\u3042\u308b\u3002<br \/>\n\u6700\u5f8c\u306e$0\u306f\u3001\u3053\u306e\u624b\u66f8\u304d\u306e\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u3092\u901a\u5e38\u306e\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u306b\u898b\u305b\u304b\u3051\u308b\u305f\u3081\u306b\u3042\u308b\u3002<br \/>\n\u305d\u306e\u8fba\u306e\u8a73\u3057\u3044\u3053\u3068\u306f\u7b2c2\u7ae0\u3067\u3002<br \/>\n\u524d\u306e\u901a\u308a\u3001\u3053\u306e\u30bb\u30c3\u30c8\u30a2\u30c3\u30d7\u306f\u3001\u6700\u521d\u306e\u30d7\u30ed\u30bb\u30b9\u306e\u7279\u5225\u306a\u3084\u308a\u65b9\uff08\u305d\u306e\u5834\u5408\u3001\u305d\u308c\u304c\u6700\u521d\u306e\u30b7\u30b9\u30c6\u30e0\u30b3\u30fc\u30eb\u3067\u3042\u308b\uff09\u306f\u907f\u3051\u3066\u3044\u308b\u3002<br \/>\n\u305d\u306e\u4ee3\u308f\u308a\u3001\u57fa\u672c\u7684\u306a\u64cd\u4f5c\u306e\u305f\u3081\u306bxv6\u304c\u63d0\u4f9b\u3059\u3079\u304d\u30b3\u30fc\u30c9\u3092\u518d\u5229\u7528\u3059\u308b\u3002<\/p>\n<h3>\u611f\u60f3<\/h3>\n<p>\u3053\u308c\u3067\u3084\u3063\u3068\u6700\u521d\u306e\u30d7\u30ed\u30bb\u30b9initcode\u304c\u5b9f\u884c\u3067\u304d\u305f\u3063\u3066\u3068\u3053\u308d\u3067\u3059\u304b\u306d\u3002<\/p>\n<p>mpmain\u306f\u8ad6\u7406CPU\u3054\u3068\u306b\u5b9f\u884c\u3055\u308c\u308b\u307f\u305f\u3044\u306a\u306e\u3067\u3001\u30b9\u30b1\u30b8\u30e5\u30fc\u30e9\u3082\u8ad6\u7406CPU\u3054\u3068\u306b\u5b9f\u884c\u3055\u308c\u308b\u307f\u305f\u3044\u3067\u3059\u306d\u3002<br \/>\n\u30de\u30eb\u30c1\u30d7\u30ed\u30bb\u30c3\u30b5\u95a2\u9023\u306e\u8a71\u306f\u5f8c\u3067\u51fa\u3066\u304f\u308b\u3093\u3067\u3057\u3087\u3046\u3002<\/p>\n<p>\u6b63\u76f4\u534a\u5206\u3082\u7406\u89e3\u3067\u304d\u3066\u306a\u3044\u611f\u3058\u3067\u3059\u3002<br \/>\n\u7406\u89e3\u3057\u3066\u3044\u308b\u3064\u3082\u308a\u306e\u90e8\u5206\u306b\u95a2\u3057\u3066\u3082\u81ea\u4fe1\u306f\u306a\u3044\u3067\u3059\u3002<br \/>\n\u305f\u3060\u307e\u3060\u6700\u521d\u306e\u30d7\u30ed\u30bb\u30b9\u304c\u8d77\u52d5\u3059\u308b\u307e\u3067\u306b\u3064\u3044\u3066\u306e\u7ae0\u306a\u306e\u3067\u3001\u305d\u308c\u4ee5\u5916\u306e\u90e8\u5206\u304c\u307e\u3060\u6982\u8981\u30ec\u30d9\u30eb\u306e\u8aac\u660e\u306b\u3068\u3069\u307e\u3063\u3066\u308b\u3068\u3044\u3046\u306e\u3082\u3042\u308b\u304b\u3068\u601d\u3044\u307e\u3059\u3002<br \/>\n\u3068\u308a\u3042\u3048\u305a\u3053\u306e\u307e\u307e\u8aad\u307f\u7d9a\u3051\u3066\u5168\u4f53\u304c\u898b\u3048\u308b\u3088\u3046\u306b\u306a\u308c\u3070\u7406\u89e3\u304c\u6df1\u307e\u308b\u306f\u305a\u3060\u3068\u601d\u3063\u3066\u3044\u307e\u3059\u3002<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[32],"tags":[405],"class_list":["post-1293","post","type-post","status-publish","format-standard","hentry","category-tech","tag-xv6"],"_links":{"self":[{"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/posts\/1293","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/comments?post=1293"}],"version-history":[{"count":0,"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/posts\/1293\/revisions"}],"wp:attachment":[{"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/media?parent=1293"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/categories?post=1293"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/peta.okechan.net\/blog\/wp-json\/wp\/v2\/tags?post=1293"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}