Courses/Computer Science/CPSC 457.F2013/Lecture Notes/Startup

= 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