Courses/Computer Science/CPSC 457.F2013/Lecture Notes/Startup
From wiki.ucalgary.ca
< Courses | Computer Science | CPSC 457.F2013 | Lecture Notes
System Startup
In this session, we will examine how an operating system actually starts up and transitions from a simple sequential loading program to a concurrent system of processes.
Besides highlighting the relationship between system code and the hardware/architecture, it provides an initial introduction to the topic of concurrency.
Focus Question
How does an OS create the environment and conditions on the hardware necessary to support the concurrent execution of multiple processes?
Agenda
- Test 1 Comments.
- HW2 questions.
- Boot.
- OS startup slides
- OS startup code (see call chain list below)
Notes and References
- http://lxr.cpsc.ucalgary.ca/lxr/#linux/Documentation/x86/boot.txt
- man dmesg (dmesg is the log of all startup activity)
The call chain involved here is interesting for several reasons:
- It shows you how deep some kernel call chains are (reflecting the design pattern of doing a little bit of work and deferring the next little bit of work to someone else)
- It demonstrates how closely the startup code is related to the underlying machine
- It is an exact reflection of going from sequential assembly code to a concurrent system by "manually" setting up kernel data structures, initializing subsystems, asking the scheduler to start, and creating a new kernel thread (via do_fork()) that eventually calls sys_execve() to load in the "first" user level process: /sbin/init.
Fascinating stuff.
2.6.32 (off the CPSC mirror of LXR)
- http://lxr.cpsc.ucalgary.ca/#linux+v2.6.32/arch/x86/boot/header.S#L301
- http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/arch/x86/boot/main.c#L125
- goto_protected_mode: http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/arch/x86/boot/pm.c#L104
- http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/arch/x86/boot/compressed/head_32.S#L33
- http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/arch/x86/kernel/head_32.S#L76
- http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/arch/x86/kernel/head_32.S#L608
- i386_start_kernel: http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/arch/x86/kernel/head32.c#L17
- start_kernel: http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/init/main.c#L536
- rest_init: http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/init/main.c#L442
- diversion: creating a kernel thread, which calls do_fork: http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/arch/x86/kernel/process_32.c#L210
- what kernel thread was created? kernel_init: http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/init/main.c#L846
- kernel_init finishes by calling init_post: http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/init/main.c#L802
- init_post uses run_init_process to invoke /sbin/init: http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/init/main.c#L793
- which calls http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/arch/x86/kernel/sys_i386_32.c#L241
- which is the exeve(2) implementation! http://lxr.cpsc.ucalgary.ca/#linux+v2.6.30/arch/x86/kernel/process_32.c#L451
2.6.27.41 (off the LXR site)
- http://lxr.linux.no/#linux+v2.6.27.41/arch/x86/boot/header.S#L297 (real mode startup assembly code)
- http://lxr.linux.no/#linux+v2.6.27.41/arch/x86/boot/main.c (jumped to from startup assembly code)
- http://lxr.linux.no/#linux+v2.6.27.41/arch/x86/boot/pm.c (transfer to protected mode)
- http://lxr.linux.no/#linux+v2.6.27.41/arch/x86/boot/compressed/head_32.S#L35 (startup_32, version 1)
- http://lxr.linux.no/#linux+v2.6.27.41/arch/x86/kernel/head_32.S#L85 (startup_32, uncompressed version)
- http://lxr.linux.no/#linux+v2.6.27.41/arch/x86/kernel/head_32.S#L604 (startup_32 control flow eventually gets here, after executing idt setup); this location is a call to the x86-specific start_kernel routine:
- http://lxr.linux.no/#linux+v2.6.27.41/arch/x86/kernel/head32.c#L16 (which calls start_kernel() at line 40)
- http://lxr.linux.no/#linux+v2.6.27.41/init/main.c#L539, which at line 691 calls rest_init():
- http://lxr.linux.no/#linux+v2.6.27.41/init/main.c#L460. rest_init() then creates a kernel thread via a call to kernel_thread():
- http://lxr.linux.no/#linux+v2.6.27.41/arch/x86/kernel/process_32.c#L233, which winds up asking do_fork():
- http://lxr.linux.no/#linux+v2.6.27.41/kernel/fork.c#L1314 to do the work, which brings us back to the topic of process creation.
- This call to kernel_thread is supplied an argument that points to the function kernel_init():
- http://lxr.linux.no/#linux+v2.6.27.41/init/main.c#L836. kernel_init() then finishes by calling init_post() at:
- http://lxr.linux.no/#linux+v2.6.27.41/init/main.c#L795, which attempts to invoke /sbin/init via run_init_process():
- http://lxr.linux.no/#linux+v2.6.27.41/init/main.c#L786, which asks kernel_execve():
- http://lxr.linux.no/#linux+v2.6.27.41/arch/x86/kernel/sys_i386_32.c#L239 to create a new, in-kernel task, which calls sys_execve() from within the kernel:
- http://lxr.linux.no/#linux+v2.6.27.41/arch/x86/kernel/process_32.c#L670, which brings us full circle to loading a process image.
Scribe notes
- s1
- s2
- s3
Readings
- "It Can Be Done" (Multics anecdote; writing correct code with a pencil)
- MOS: 10.3.5: "Booting Linux"
- An Ode to Real Mode Setup Code