1 / 25

main()

제 26 강 : main(). main(). main() (1550) initialize core (1568), clist, blist, … set up process #0 (1589) Special type -- no a.out, just ppda (1589) make ppda at the end of a.out. main, icode. (1613) buffer cache (1616) root directory (1627) newproc()

vic
Download Presentation

main()

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 제26강 : main() main()

  2. main() (1550) • initialize core (1568), clist, blist, … • set up process #0 (1589) • Special type -- no a.out, just ppda • (1589) make ppda at the end of a.out main, icode

  3. (1613) buffer cache (1616) root directory (1627) newproc() So let’s go to newproc() (1826) (7-5) main calls newproc

  4. newproc() 1826 (7-5-1) 1841 mpid global var -- PID 1846 find empty slot in proc[] 1848 p & rpp - for child (currently being born) 1859 up & rip - for current process (parent) parent Parent Child Child

  5. parent • copy entire proc[] except for PID • (open file reference count)++ : • “f_” is fields within struct file • 1894 a1 - address of parent’s image • 1896 a2– address of available space Parent Child Child

  6. user a.out user kernelstack sched • 1915 while (n--) copyseg(a1++, a2++) • copy swappable image(including ppda) • now child is ready • But child, is waiting in the ready queue • Child will be waken up by swtch() later • and return with value 1 (see 2247 in swtch()). • return(0) parent returns with 0. • A close look at Child • - a.out • - struct user • - kernel stack • - struct proc[ ] copied parent’s image

  7. Where child has to be different • (7-5-1-b) • 1. Address of proc[] (1891)  u (child) • 1848 p & rpp - for child • 1859 up & rip - for current process • 1891 struct user point to child temporarily • 1917 restore it back to parent’s • 2. Address of image (1913)  proc[child] • 1894 a1 - address of parent’s image • 1896 a2– address of child (free space) • 3. Save SP/EP (1889)  u (child) • this savu() is not for parent himself • parent is not giving up CPU here • so parent does not need u.u_rsav here • let savu() use u.u_rsav for child • CPU (SP|EP)  u.u_rsav • When child wakes up in the future • child loads SP/EP from u.u_rsav (retu()) • child pops kernel stack using SP/EP • child returns from newproc() to main() kernel stack  SP newproc 1627  EP main user user u.u_rsav (2528) this is kenel malloc(), not user library. this is size of (a.out + struct user)

  8. Summary newproc() allocate & copy proc[ ] for child Image(PNEW)  Image(PPARENT) copy a.out & copy struct user PNEW is now in ready state parent Parent Child Child

  9. user a.out user kernelstack Summary newproc() allocate & copy proc[ ] for child Image(PNEW)  Image(PPARENT) copy (a.out + user + kernel stack) PNEW is now in ready state sched Including p.p.d.a.

  10. main calls newproc OK, back to main() 1627, 1st call to newproc() returned zero, While in newproc(), we created process #1 by making proc[PNEW] copying Image(PNEW)  Image(PPARENT) Process #1 is now ready (waiting to run) Caller (parent) returns from newproc() with value zero, skips (1628-1636) sched() (1940) sched()sleep() sleep()  swtch()  context switch

  11. 1627 1550 main() 1826 newproc() 1637 1940 sched() You are Here 1968 2066 sleep() 2084 2178 swtch()

  12. swtch(1) wakeup setrun Current process retires Process #0 runs

  13. Selected process arises swtch(2) Pop stack for return address

  14. 2178: swtch() 2189: savu(u.u_rsav); 2191: /* Switch to scheduler's stack */ 2193: retu(proc[0].p_addr); 2201: /* Search for highest-priority runnable process */ 2203: i = NPROC; 2204: do { 2205: rp++; 2208: if(rp->p_stat==SRUN && (rp->p_flag&SLOAD)!=0) { 2209: if(rp->p_pri < n) { 2210: p = rp; 2211: n = rp->p_pri; 2212: } 2213: } 2214: } while(--i); 2215: /* 2228: retu(rp->p_addr); 2229: sureg(); 2247: return(1);

  15. a.out PAR PDR CPU R0 R1 | S P E P user kernel stack kernel retu(proc[j]) 1. kernel’s 7th PAR points to new ppda 2. load CPU SP EP from new struct user a.out a.out user user kernel stack kernel stack p_addr p_addr p_addr proc[i] proc[j] proc[k] kernel struct proc[NPROC]

  16. retu(proc[k]) 1. kernel’s 7th PAR points to new ppda 2. load CPU SP EP from new struct user a.out a.out PAR PDR a.out CPU R0 R1 | S P E P user user user kernel stack kernel stack kernel stack kernel p_addr p_addr p_addr proc[i] proc[j] proc[k] kernel struct proc[NPROC]

  17. a.out PAR PDR CPU R0 R1 | S P E P user kernel stack kernel a.out PAR PDR CPU R0 R1 | S P E P user kernel stack kernel a.out PAR PDR CPU R0 R1 | S P E P user kernel stack kernel swtch () { retu(proc[0]) retu(rp); return } saveu(u) prepare to block caller 2193 proc #0 runs on CPU 2228 proc rp runs on CPU

  18. Summary – swtch() 2189 savu(u) prepare to preempt CPU 2193 retu(proc[0]) CPU scheduler runs on CPU 2228 retu(proc[rp]) new process runs on CPU 2247 return(1) new process returns from swtch() • Pcaller wants to sleep • and calls swtch() • savu (u)  prepare to • preempt CPU from Pcaller Pcaller P P P P Pscheduler 2. retu (proc[0])  gives CPU to scheduler (process #0) 3. scheduler selects the highest priority job retu (proc[new_process]) gives CPU to new job Phigh_pri

  19. swtch() (2178) (8-2-2-t) • 2189 caller retires savu(u.u_rsav) • 2193 CPU scheduler (proc #0) wakes up • retu(proc[0].p_addr) • 2209 search proc table (maximum priority) • new proc is picked (2223 rp=p) • 2228 CPU given to new process • retu(rp->p_addr) • sureg() • set CPU user mapping registers (1739) • set user mode (memory mapping) registers • 2247 new process executes 2247 • return(1) -- pops return address from • kernel mode stack • return to where?) • returns to main() 1627 user k-stack  SP newproc() 1627  EP main() user Selected process arises swtch(2) Pop stack for return address kernel mode stack of the new process (copied from P0)

  20. Where child has to be different • (7-5-1-b) • 1. Address of proc[] (1891)  u (child) • 1848 p & rpp - for child • 1859 up & rip - for current process • 1891 struct user point to child temporarily • 1917 restore it back to parent’s • 2. Address of image (1913)  proc[child] • 1894 a1 - address of parent’s image • 1896 a2– address of child (free space) • 3. Save SP/EP (1889)  u (child) • this savu() is not for parent himself • parent is not giving up CPU here • so parent does not need u.u_rsav here • let savu() use u.u_rsav for child • CPU (SP|EP)  u.u_rsav • When child wakes up in the future • child loads SP/EP from u.u_rsav (retu()) • child pops kernel stack using SP/EP • child returns from newproc() to main() kernel stack  SP newproc 1627  EP main user user u.u_rsav (2528) this is kenel malloc(), not user library. this is size of (a.out + struct user)

  21. main, icode

  22. Booting • main() • make proc[0] – just ppda, no a,out • newproc • make proc[1] – by copying proc[0] • return from newproc with zero • if (newproc()) test fails • skip if () then { } • sched()  sleep()  swtch() • swtch() • retu(proc[0])  selects proc[1] • retu(proc[1]) • return(1) ---Now proc[1] is running -- • 1627 if (newproc()) test -- TRUE • into  if () then { } • expand user space for P1’s a.out • copy icode[] from kernel to P1’s user space • return from kernel mode to user code • execute icode[] in user space • “ main() - - - exec(init) system call • P1 reenters kernel • exec() system call • read from disk • load init (user a,out) into memory • jump to user code (init) • ---Now proc[1] is /etc/init code • init process creates shell per tty • init gives CPU to shell (via swtch()) main calls newproc

  23. ASM: Between Kernel & User • copyout(N, Mu, Mk) subyte(Mu, D) suword(Mu, D) • copyin(N, Mu, Mk) fubyte(Mu) fuword(Mu) N bytechar word • Mu, Mk: memory address fetch, set • N: count IPC, I/O • D:data set user a.out kernel a.out C: Between I/O buffer & User fetch • iomove() passc() cpass() • N byte char (K->U) char (K<-U) C functions (eventually call assembler functions above) struct user is used here for parameter values u_base: address to do I/O in user a.out u_count: byte count Sys Call Used for I/O IPC

  24. fubyte subyte

More Related