Qin Dingtao "Linux kernel Analysis" MOOC course http://mooc.study.163.com/course/USTC-1000029000
First, the purpose and requirements of the experiment:
Booting from Start_kernel to init process using GDB trace debug kernel
Detailed analysis of the process initiated from Start_kernel to Init process and the combination of experiments to write a signed blog, and in the blog post "real name (and the name of the final application certificate must be consistent) + Original works reproduced please specify the source +" Linux kernel Analysis "MOOC Course/http mooc.study.163.com/course/ustc-1000029000 ", the specific requirements of the blog content are as follows:
Topic self-proposed, the content revolves around the Linux kernel boot process, namely starts from Start_kernel to the INIT process;
You need to use an experiment in your blog
The execution of the Start_kernel function needs to be carefully analyzed in the blog content
The summary section needs to clarify its understanding of the "Linux system startup process", especially how the idle process, process 1th is coming.
3) Please submit the blog post URL to the NetEase cloud classroom MOOC Platform Linux kernel Analysis Mooc course, edited into a link can be directly clicked open.
Second, the experimental steps (including the experimental Building):
1. Login to the experimental building virtual machine
Open the shell terminal and execute the following command:
CD linuxkernel/
Qemu-kernel LINUX-3.18.6/ARCH/X86/BOOT/BZIMAGE-INITRD rootfs.img
(The system supports three commands: Help, Version, quit)
2. using GDB to trace the debug kernel
Execute the following command:
CD linuxkernel/
Qemu-kernel LINUX-3.18.6/ARCH/X86/BOOT/BZIMAGE-INITRD Rootfs.img-s-S
Notes on the-s and-s options:
-S freeze CPU at startup (using ' C ' to start execution) freezes the CPU at system startup and continues with the C key
-S shorthand for-gdb tcp::1234 open remote debugging port, TCP protocol 1234 is used by default, and if you do not want to use port 1234, you can use-gdb tcp:xxxx instead of-s option
Open another shell terminal and execute the following command
Gdb
(gdb) file linux-3. 6/vmlinux # Loading symbol table before Targe remote in GDB interface
(GDB) Target remote:1234 # Establish a connection between GDB and Gdbserver, press C to keep Linux on qemu running
(GDB)break Start_kernel # breakpoints can be set before target remote or after
(Do not know why the file directory was not found.) )
Three, the Start_kernel function execution Process analysis:
asmlinkage void __init start_kernel (void)
{
char * command_line;
extern struct Kernel_param __start___param[], __stop___param[];
/*
* Interrupts is still disabled. Do necessary setups and then
* Enable them
*/
Lock_kernel (); If the kernel is configured to support preemption, then the preemption is forbidden here, and the init_thread_info.preempt_count of the No. 0 process is added 1, and if it is configured to not support preemption, then the kernel global optional lock kernel_flag locked.
page_address_init ();The 10 version of ARM section does not support high-end memory-related code, empty functions.
PRINTK (linux_banner);Prints the contents of the Linux_banner to the log_buf buffer.
Setup_arch (&command_line);The function prototype sets up the system according to the processor, hardware platform specific model in ARCH/ARM/KERNEL/SETUP.C. Parse Linux system command line, set the memory description structure of process No. 0 (swapper process) init_mm, initialize system memory management, count and register various resources of system, and initialize other projects.
Setup_per_cpu_areas ();Request space for the PER_CPU variable for each processor in the system. /*
* Mark the Boot CPU "online" so, it can call console drivers in
* PRINTK () and can access its PER-CPU storage.
*/
Smp_prepare_boot_cpu (); /*
* Set up the scheduler prior starting any interrupts (such as the
* Timer interrupt). Full topology setup happens at Smp_init ()
* Time-but Meanwhile we still have a functioning scheduler.
*/
sched_init ();Initializes a running process queue for each processor, setting the system initialization process to process No. 0.
build_all_zonelists ();Establishes the System memory page area (zone) linked list.
Page_alloc_init ();
PRINTK ("Kernel command line:%s\n", saved_command_line);
Parse_early_param ();Parse early format kernel parameters.
Parse_args ("Booting kernel", command_line, __start___param,
__stop___param-__start___param,
&unknown_bootoption); resolves the new format kernel parameters.
sort_main_extable ();The struct EXCEPTION_TABLE_ENTRY global structure variables placed in the * (__ex_table) area between __start__ex_table and __stop__ex_table are sorted from small to large by the value of the INSN member variable. An instruction that is about to cause a fault in the pages is ordered from the binary code value of its instruction to the largest.
trap_init ();Put it on the. The system at Lcvectors 8 unexpected ingress jump commands moved to the high-end interrupt vector 0xffff0000, and then the various unexpected initial processing codes from __stubs_start to __stubs_end were moved to 0xffff0200. Refreshes the instruction cache at the 0xffff0000 1-page range, setting Domain_user access to domain_client permissions by Domain_manager permissions.
rcu_init ();Initializes the current CPU's read, copy, update data structure (struct rcu_data) global variables per_cpu_rcu_data and per_cpu_rcu_bh_data.
Init_irq ();Initialization of the maximum number of possible interrupts supported in the system description structure struct IRQDESC variable array Irq_desc[nr_irqs], each structural variable Irq_desc[n] is initialized to a pre-defined bad interrupt description structure variable BAD_IRQ_DESC, And initializes the interrupt to the table header member structure variable pend.
pidhash_init ();Set the shift value of the number of hash lists in each PID hash table in the system global variable Pidhash_shift, set Pidhash_shift to Min (12), respectively, for each hash table of continuous hash list header structure space for memory, Pass the requested memory virtual base address to Pid_hash[n] (n=0~3), and set the first member pointer in each hash table header structure struct hlist_head to null
init_timers ();Initializes the current out-of-processor time vector basic struct tvec_t_base_s global variable per_cpu_tvec_bases, initializing Per_cpu_tvec_bases's spin lock member variable lock.
softirq_init ();Set the system small task software interrupt behavior function describes the structure variable SOFTIRQ_VEC[TASKLET_SOFTIRQ (=6)], the action function pointer of Softirq_vec[6] is directed to the Tasklet_action () function, The parameter pointer is set to NULL.
time_init ();Check that the system timer describes whether the struct Sys_timer global variable system_timer is empty, if it is to point to the Dummy_gettimeoffset () function. /*
* HACK alert! This is early. We ' re enabling the console before
* we ' ve done PCI setups etc, and console_init () must is aware of
* this. But we did want output early, in case something goes wrong.
*/
console_init ();Initializes the console structure of the system and calls the PRINTK () function after the function executes to print system information in Log_buf that meets the print level requirements to the console.
if (Panic_later)
Panic (Panic_later, Panic_param);
profile_init ();The system anatomy is initialized, and the system analysis is used for system call.
local_irq_enable ();The current system State Register of the processor CPSR the 7th bit to 0, enabling IRQ interrupts.
#ifdef CONFIG_BLK_DEV_INITRD
if (Initrd_start &&!INITRD_BELOW_START_OK &&
Initrd_start < MIN_LOW_PFN << Page_shift) {
PRINTK (Kern_crit "INITRD overwritten (0X%08LX < 0X%08LX)-"
"Disabling it.\n", INITRD_START,MIN_LOW_PFN << page_shift);
Initrd_start = 0;
}
#endif
Vfs_caches_init_early ();
mem_init ();After the function is finished, it is no longer possible to request memory with functions such as Alloc_bootmem (), Alloc_bootmem_low (), alloc_bootmem_pages (), etc., and cannot apply for large chunks of contiguous physical memory.
kmem_cache_init ();Performing cache memory management is slab allocator related initialization.
Numa_policy_init ();
if (late_time_init)
Late_time_init ();
Calibrate_delay ();The bogmips value of the computer system, which is the number of instructions executed per second by the processor.
Pidmap_init ();
Pgtable_cache_init ();
prio_tree_init ();Initializes each member of the unsigned Long Global array Index_bits_to_maxindex[bits_per_long], sets each member Index_bits_to_maxindex[n] to 1, and the last Index_bits_to_ MAXINDEX[BITS_PER_LONG-1] set to ~0ul.
anon_vma_init ();The function calls the Kmem_cache_create () function to create a cache memory description structure kmem_cache_t variable for the anonymous virtual memory area linked list structure struct ANON_VMA, which is named "ANON_VMA" for the variable. The constructor pointer of its object points to the void Anon_vma_ctor (void *data,kmem_cache_t *cachep,unsigned long flags) function, and the destructor pointer is empty, creating the kmem_cache_ The address of the T structure variable is passed to the global pointer Anon_vma_chachep.
#ifdef config_x86
if (efi_enabled)
Efi_enter_virtual_mode ();
#endif
Fork_init (num_physpages);The execution process creates the related initialization.
Proc_caches_init ();
buffer_init ();Call Kmem_cache_create ("Buffer_head", sizeof (struct buffer_head), 0, Slab_panic, Init_buffer_head, NULL) The Buffer_head function creates a cache memory description structure kmem_cache_t variable for the buffer description struct struct.
unnamed_dev_init ();Call and return the Idr_init (&UNNAMED_DEV_IDR) function.
security_init ();Print "Security architecture v1.0.0 is initialized". If you do not define the system dummy security operation function Group structure global variable dummy_security_ops, print error message, return I/O error.
Vfs_caches_init (num_physpages);
Radix_tree_init ();
signals_init ();Call Kmem_cache_create ("Sigqueue", sizeof (struct sigqueue), __alignof__ (struct sigqueue), slab_panic, NULL, NULL) The function creates a cache memory description structure for the signal queue structure struct sigqueue kmem_cache_t variable, called "Sigqueue", does not require its object to be aligned to the processor hardware cache line size, does not define its object's construction and destructor, The address of the KMEM_CACHE_T structure variable that created the number is passed to the global pointer Sigqueue_cachep.
/* ROOTFS populating might need page-writeback * *
page_writeback_init ();The sum of the total number of additional memory pages in the general (NORMAL) memory page area of all memory nodes in the statistics system is passed to Buffer_pages.
#ifdef CONFIG_PROC_FS
proc_root_init ();This is called only if the system supports the PROC file system, which is configured with the CONFIG_PROC_FS option.
#endif
Check_bugs (); Acpi_early_init (); /* before lapic and SMP init */* Do the rest non-__init ' Ed, we ' re now alive */
rest_init ();The function creates the init () kernel process, which is the 1th process, and then the system boot process, which is the NO. 0 process idle.
}
Iv. Summary of the experiment:
When the computer is powered on, the BIOS code is called to execute, and then begins to call the execution of the Linux kernel initialization code in the platform-related assembly code
After execution, it jumps to the Start_kernel () function and starts the real kernel initialization, where Init_task creates the No. 0 process, the final idle process,
The Rest_init () function then created the init process, process 1th, and the Kthreadd process, the 2nd process, and the system began to formally work externally.
Analysis of startup process of Linux kernel