Linux Kernel Internals 7.the first CPU calls start kernel(),all others call arch/i386/kernel/smpboot.c:initialize secondary()if ready=1,which just reloads esp/eip and doesn't return. The init/main.c:start kernel()is written in C and does the following: 1.takes a global kernel lock (it is needed so that only one CPU goes through initialisation) 2.performs arch-specific setup (memory layout analysis,copying boot command line again,etc.) nne A es uap 6. required for scheduler tialis ses tim rq s 0 mandline option 10 11.if module s port was compiled into the kernel,initialises dynamical module loading facility mmand line was su pplied initialises profiling buffers 13.kmem cache init(),initialises most of slab allocator 14.enables interrupts 15 calculates bogomins value for this cpu 16.calls meminit()which calculates max mapnr,totalram pages and high memory and prints out the "line 17.kmem cache sizes init(),finishes slab allocator initialisation 18.initialises data structures used by procfs 19.fork init().creates uid cache,initialises max threads based on the amount of memory available and configures RLIMIT NPROC for init_task to be max_threads/2 20.creates various slab caches needed for VFS.VM,buffer cache etc 21.if System V IPC support is compiled in,initialises IPC subsystem.Note,that for System Vshm this includes mounting an internal (in-kernel)instance of shmfs filesystem 22.if quota support is compiled into the kemel,create and initialise a special slab cache for it 23.performs arch-specific"check for bugs"and,whenever possible,activates workaround for processor/bus/etc bugs.Comparing various architectures reveals that"i64 has no bugs"and"a32 foof bug"which is only checked if kernel is compiled for ork aro 24.sets a flag ate that a sch be invok t"next opp ortunity and creates a keme )w it/bin/init,/b all these 25 "in paramete s in loop,this is dle thread with pid=0 d ot here that the in Important thin nel thr ead calls do basic gh the list of fur d h cal odule inito macros and invokes the m The e functions either do ach other or thei ndencies have been manually fixed by the link order in the makefiles This means that d ndin on the osition of change sometimes this is important because you can imagine two subsy ems a and b with b depending on some initialisation done by A.If A is compiled statically and B is a module then B's entry point is guaranteed to be invoked after A prepared all the necessary environment.If A is a module,then B is also necessarily a 1.5 Using LILO as a bootloader 7. the first CPU calls start_kernel(), all others call arch/i386/kernel/smpboot.c:initialize_secondary() if ready=1, which just reloads esp/eip and doesn't return. The init/main.c:start_kernel() is written in C and does the following: 1. takes a global kernel lock (it is needed so that only one CPU goes through initialisation) 2. performs arch−specific setup (memory layout analysis, copying boot command line again, etc.) 3. prints Linux kernel "banner" containing the version, compiler used to build it etc. to the kernel ring buffer for messages. This is taken from the variable linux_banner defined in init/version.c and is the same string as displayed by "cat /proc/version". 4. initialises traps 5. initialises irqs 6. initialises data required for scheduler 7. initialises time keeping data 8. initialises softirq subsystem 9. parses boot commandline options 10. initialises console 11. if module support was compiled into the kernel, initialises dynamical module loading facility 12. if "profile=" command line was supplied initialises profiling buffers 13. kmem_cache_init(), initialises most of slab allocator 14. enables interrupts 15. calculates BogoMips value for this CPU 16. calls mem_init() which calculates max_mapnr, totalram_pages and high_memory and prints out the "Memory: ..." line 17. kmem_cache_sizes_init(), finishes slab allocator initialisation 18. initialises data structures used by procfs 19. fork_init(), creates uid_cache, initialises max_threads based on the amount of memory available and configures RLIMIT_NPROC for init_task to be max_threads/2 20. creates various slab caches needed for VFS, VM, buffer cache etc 21. if System V IPC support is compiled in, initialises IPC subsystem. Note, that for System V shm this includes mounting an internal (in−kernel) instance of shmfs filesystem 22. if quota support is compiled into the kernel, create and initialise a special slab cache for it 23. performs arch−specific "check for bugs" and, whenever possible, activates workaround for processor/bus/etc bugs. Comparing various architectures reveals that "ia64 has no bugs" and "ia32 has quite a few bugs", good example is "f00f bug" which is only checked if kernel is compiled for less than 686 and worked around accordingly 24. sets a flag to indicate that a schedule should be invoked at "next opportunity" and creates a kernel thread init() which execs execute_command if supplied via "init=" boot parameter or tries to exec /sbin/init,/etc/init,/bin/init,/bin/sh in this order and if all these fail, panics with suggestion to use "init=" parameter. 25. goes into the idle loop, this is an idle thread with pid=0 Important thing to note here that the init() kernel thread calls do_basic_setup() which in turn calls do_initcalls() which goes through the list of functions registered by means of __initcall or module_init() macros and invokes them. These functions either do not depend on each other or their dependencies have been manually fixed by the link order in the Makefiles. This means that depending on the position of directories in the trees and the structure of the Makefiles the order initialisation functions are invoked can change. Sometimes, this is important because you can imagine two subsystems A and B with B depending on some initialisation done by A. If A is compiled statically and B is a module then B's entry point is guaranteed to be invoked after A prepared all the necessary environment. If A is a module, then B is also necessarily a Linux Kernel Internals 1.5 Using LILO as a bootloader 8