Courses/Computer Science/CPSC 457.W2013/Lecture Notes/Startup
From wiki.ucalgary.ca
< Courses | Computer Science | CPSC 457.W2013 | 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 a good segue to 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
- Boot.
- OS startup slides
- OS startup code (see call chain list below)
Notes and References
- http://lxr.linux.no/#linux+v2.6.27.41/Documentation/x86/i386/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.
- 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.
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