Start_kernel code analysis

Source: Internet
Author: User

Head-common.S
--- Specific actions
--- Jump to init/Main. c
--- B start_kernel
// For more information about start_kernel, see Linux kernel. Chapter 8
Main. c
Asmlinkage void _ init start_kernel (void)
{
Char * command_line;
Extern struct kernel_param _ start ___ Param [], _ Stop ___ Param [];
// To set the SMP process ID. Of course, the Code currently displayed is empty.
Smp_setup_processor_id ();
/*
* Need to run as early as possible, to initialize
* Lockdep hash:
*/
// Lockdep is a debugging module of the Linux kernel. It is used to check the kernel mutex mechanism, especially the potential deadlock problem of the spin lock.
// Because the spin lock is waiting in the query mode and does not release the processor, it is easier to deadlock than the general mutex mechanism,
// Therefore, lockdep is introduced to check possible deadlocks in the following situations (lockdep will be described in detail in this article, which is just a simple list ):
//
// The same process recursively locks the same lock;
//
// · A lock is performed when the upper half of the interrupt (or the lower half of the interrupt) is enabled,
// The lock operation has been performed in the interrupt (or the lower half of the interrupt. In this way, the lock may attempt to lock the same processor due to interruption;
//
// · The dependency graph is generated into a closed loop after locking, which is a typical deadlock phenomenon.
Lockdep_init ();
Debug_objects_early_init ();
/*
* Set up the initial canary ASAP:
*/
// Initialize stack_canary stack 3
// Stack_canary is a stack with protection against Stack Overflow attacks.
// When the user space program enters the kernel space through int 0x80, the CPU automatically completes a stack switch,
// Switch from the user space stack to the kernel space stack.
// All system calls that occur before the exit of the Process use the same Kernel stack.
// The Kernel stack size is generally 4096/8192,
// Kernel stack helps you understand:
//
// Memory low-address memory high-address
// | <------------------------------- ESP |
// + ------------------------------------- 4096 ------------------------------- +
// | 72 | 4 | x <4016 | 4 |
// + ------------------ + ----------------- + ----------------------------------- +
// | Thread_info | stack_end_magic | Var/call chain | stack_canary |
// + ------------------ + ----------------- + ----------------------------------- +
// | 28 | 44 |
// V |
// Restart_block v
//
// ESP + 0x0 + 0x40
// + ----------------------------------------------------------------------------- +
// | EBX | ECx | edX | ESI | EDI | EBP | eax | DS | es | FS | GS | orig_eax | EIP | Cs | eflags | oldesp | oldss |
// + ----------------------------------------------------------------------------- +
// | Kernel completed | CPU automatically completed |
// Http://hi.baidu.com/wzt85/blog/item/112a37132f6116c2f6039e44.html
Boot_init_stack_canary ();
// Cgroup: it is called control group. It is the action control of a group of processes.
// For example, we restrict the CPU usage of processes/bin/sh to 20%. We can create a cgroup with 20% CPU usage.
// Then add the/bin/sh process to the cgroup. Of course, a cgroup can have multiple processes.
// Http://blogold.chinaunix.net/u1/51562/showart_1736813.html
Cgroup_init_early ();
// Update all the immediate values in the kernel, but which values need to be viewed again?
Core_imv_update ();
// Disable the current cup interruption
Local_irq_disable ();
// Modify the early_boot_irqs_enabled flag;
// Use the static global variable early_boot_irqs_enabled to help us debug the code,
// This flag can help us know whether it is in the "Early bootup code" or warn us that an invalid terminal is opened.
Early_boot_irqs_off ();
// Each interrupt is described by an IRQ Descriptor (struct irq_desc.
// The main function of this function is to set the locks of all IRQ Descriptors (struct irq_desc) to uniform locks,
// Or each IRQ Descriptor (struct irq_desc) has a small lock.
Early_init_irq_lock_class ();
/*
* Interrupts are still disabled. Do necessary setups, then
* Enable them
*/
// Large kernel lock (BKL -- big kernel lock)
// Large kernel locks are essentially spin locks, but they are different from spin locks. Spin locks cannot be obtained recursively because they lead to deadlocks.
// But the large kernel lock can recursively obtain the lock. A large kernel lock is used to protect the entire kernel, while a spin lock is used to protect a very specific shared resource.
// Scheduling can occur when the process maintains a large kernel lock. The specific implementation is:
// When schedule is executed, schedule checks whether the process has a large kernel lock. If yes, it is released so that other processes can obtain the lock,
// When it is the turn of the process to run, let it re-obtain the large kernel lock. Note that scheduling does not occur during the spin lock retention period.
// It should be pointed out that there is only one major kernel lock in the entire kernel. In fact, it is not hard to understand that there is only one kernel, and the large kernel lock protects the entire kernel, of course, only one of them is enough.
// It should also be pointed out that the large kernel lock is left over from history and is rarely used in the kernel. Generally, it is not recommended to be used because the lock remains for a long time.
// Starting from kernel 2.6.11, a large kernel lock can be preemptible by configuring the kernel (the spin lock cannot be preemptible). In this case, it is essentially a mutex lock and is implemented using semaphores.
// APIs for large kernel locks include:
//
// Void lock_kernel (void );
//
// This function is used to obtain a large kernel lock. It can be called recursively without causing a deadlock.
//
// Void unlock_kernel (void );
//
// This function is used to release the large kernel lock. Of course, it must be paired with lock_kernel. The number of times that lock_kernel is called depends on the number of times that unlock_kernel is called.
// The APIs with large kernel locks are easy to use. You can use them as follows:
// Lock_kernel (); // access to protected shared resources... Unlock_kernel ();
// Http://blog.csdn.net/universus/archive/2010/05/25/5623971.aspx
Lock_kernel ();
// Initialize time ticket, clock
Tick_init ();
// The function tick_init () is very simple. Call the clockevents_register_notifier function to notify the chain registration element to clockevents_chain:
// Tick_notifier. The callback function of this element indicates that when the device information of the clock event changes (for example, when a new clock event device is added,
// The operation to be executed. The callback function is tick_policy.
// Http://blogold.chinaunix.net/u3/97642/showart_2050200.html
Boot_cpu_init ();
// Initialize the page address. Of course, this is an empty function for arm.
// Http://book.chinaunix.net/special/ebook/PrenticeHall/PrenticeHallPTRTheLinuxKernelPrimer/0131181637/ch08lev1sec5.html
Page_address_init ();
Printk (kern_notice "% s", linux_banner );
// System Structure-related kernel initialization process
// Http://www.cublog.cn/u3/94690/showart_2238008.html
Setup_arch (& command_line );
// Initialize memory management
Mm_init_owner (& init_mm, & init_task );
// Process the startup command. Here is the set cmd_line.
Setup_command_line (command_line );
// This function works when SMP is defined. Now it is an empty function. The usage of SMP is described later...
Setup_nr_cpu_ids ();
// If the config_smp macro is not defined, this function is empty.
// If the config_smp macro is defined, the setup_per_cpu_areas () function allocates memory for each CPU,
// Copy the data in the. Data. percpu segment. Apply for space for the per_cpu variable of each CPU in the system.
Setup_per_cpu_areas ();
// Defined in include/asm-x86/SMP. h.
// In the SMP environment, set some data of the boot CPU. The CPU used during boot is called the boot CPU
Smp_prepare_boot_cpu ();/* arch-specific boot-CPU hooks */
// Set the node and zone Data Structures
// Memory management explanation: http://blog.chinaunix.net/space.php? Uid = 361890 & Do = Blog & cuid = 2146541
Build_all_zonelists (null );
// Initialize the structure of page allocation
Page_alloc_init ();
Printk (kern_notice "kernel command line: % s/n", boot_command_line );
// Parse Kernel Parameters
// Kernel Parameter Analysis: http://hi.baidu.com/yuhuntero/blog/item/654a7411e45ce519b8127ba9.html
Parse_early_param ();
Parse_args ("booting kernel", static_command_line, _ start ___ Param,
_ Stop ___ param-_ start ___ Param,
& Unknown_bootoption );
/*
* These use large bootmem allocations and must precede
* Kmem_cache_init ()
*/
// Initialize the hash table to obtain the corresponding process description pointer from the PID of the process, and initialize the PID hash table according to the actual physical memory.
// Process Management http://blog.csdn.net/satanwxd/archive/2010/03/27/5422053.aspx involved here
Pidhash_init ();
// Initialize two important data structures of VFS: dcache and inode cache.
// Http://blog.csdn.net/yunsongice/archive/2011/02/01/6171324.aspx
Vfs_caches_init_early ();
// Sort the exception table set by kbuild during compilation, that is, all elements in _ start ___ ex_table and _ Stop ___ ex_table.
Sort_main_extable ();
// Initialize the interrupt vector table
// Http://blog.csdn.net/yunsongice/archive/2011/02/01/6171325.aspx
Trap_init ();
// Memory map Initialization
// Http://blog.csdn.net/huyugv_830913/archive/2010/09/15/5886970.aspx
Mm_init ();
/*
* Set up the scheduler prior starting any interrupts (such as
* Timer interrupt). Full topology setup happens at smp_init ()
* Time-but meanwhile we still have a functioning scheding.
*/
// Initialize the scheduler of the core process. The initialization priority of the scheduler is higher than that of any interrupt,
// And the initialization process 0 is the idle process, but the need_resched flag of the idle process is not set,
// You will continue to complete the rest of kernel initialization.
// Only prepare for the execution of the Process scheduler.
// The specific work it does is to call the init_bh function (kernel/softirq. c) to add the timer, tqueue, and immediate character queues to the lower half of the array
Sched_init ();
/*
* Disable preemption-early bootup scheduling is extremely
* Fragile until we cpu_idle () for the first time.
*/
// Add 1 to the preemptible counter
Preempt_disable ();
// Check whether the interrupt is enabled
If (! Irqs_disabled ()){
Printk (kern_warning "start_kernel (): Bug: interrupts were"
"Enabled * very * early, fixing it/N ");
Local_irq_disable ();
}
// Read-copy-update Initialization
// The RCU mechanism is a data consistency access mechanism provided after linux2.6,
// From the RCU (read-copy-Update) name, we can have a rough understanding of its implementation mechanism,
// When modifying data, you must first read the data and generate a copy to modify the copy,
// Update the old data into new data after the modification is complete. This is called RCU.
// Http://blog.ednchina.com/tiloog/193361/message.aspx
// Http://blogold.chinaunix.net/u1/51562/showart_1341707.html
Rcu_init ();
// Defined in lib/radix-tree.c.
// Linux uses the radix tree to manage disk blocks located in the file system buffer zone,
// Radix is a trie tree.
// Http://blog.csdn.net/walkland/archive/2009/03/19/4006121.aspx
Radix_tree_init ();
/* Init some links before init_isa_irqs ()*/
// Early_irq_init initializes each member structure in the array,
// For example, the interrupt number of each initial interrupt source. Other functions are basically empty.
Early_irq_init ();
// Initialize the IRQ interrupt and terminal descriptor.
// Initialize the maximum possible interrupt description structure supported by the system struct irqdesc variable array irq_desc [nr_irqs],
// Initialize each structure variable irq_desc [N] to a predefined bad interrupt description Structure Variable bad_irq_desc,
// Initialize the member structure variable pend of the interrupt linked list Header
Init_irq ();
// Prio-tree is a search tree. What is managed?
// Http://blog.csdn.net/dog250/archive/2010/06/28/5700317.aspx
Prio_tree_init ();
// Initialize the timer-related data structure
// Http://www.ibm.com/developerworks/cn/linux/l-cn-clocks/index.html
Init_timers ();
// Initializes a high-precision clock.
Hrtimers_init ();
// Soft Interrupt Initialization
// Http://blogold.chinaunix.net/u1/51562/showart_494363.html
Softirq_init ();
// Initialize the clock source
Timekeeping_init ();
// Initialize the system time,
// Check whether the system timer description structure struct sys_timer global variable system_timer is empty,
// If it is null, point it to the dummy_gettimeoffset () function.
// Http://www.ibm.com/developerworks/cn/linux/l-cn-clocks/index.html
Time_init ();
// Profile is only a tool for kernel debugging performance,
// This can be opened through instrumentation support> profile in menuconfig.
// Http://www.linuxdiyf.com/bbs//thread-71446-1-1.html
Profile_init ();
If (! Irqs_disabled ())
Printk (kern_crit "start_kernel (): Bug: interrupts were"
"Enabled early/N ");
// Corresponds to the start early_boot_irqs_off
Early_boot_irqs_on ();
// Corresponds to local_irq_disbale and is disconnected.
Local_irq_enable ();
/* Interrupts are enabled now so all green allocations are safe .*/
Gfp_allowed_mask = _ gfp_bits_mask;
// Initialize memory cache
// Http://my.chinaunix.net/space.php? Uid = 7588746 & Do = Blog & id = 153184
Kmem_cache_init_late ();
/*
* Hack alert! This is early. We're re enabling the console before
* We 've done PCI setups etc, and console_init () must be aware
* This. But we do want output early, in case something goes wrong.
*/
// Initialize the console to display the content of the printk. The previously called printk only stores data in the buffer zone,
// The content is printed on the console only after this function is called.
// After the function is executed, you can use the printk () function to print the system information that meets the printing level requirements in log_buf to the console.
Lele_init ();
If (panic_later)
Panic (panic_later, panic_param );
// If the config_lockdep macro is defined, the lock dependency information will be printed; otherwise, nothing will be done.
Lockdep_info ();
/*
* Need to run this when irqs are enabled, because it wants
* To self-test [Hard/soft]-irqs On/Off lock inversion bugs
* Too:
*/
// If config_debug_locking_api_selftests macro is defined
// Locking_selftest () is an empty function. Otherwise, the locking_selftest is executed.
Locking_selftest ();
# Ifdef config_blk_dev_initrd
If (initrd_start &&! Initrd_below_start_ OK &&
Page_to_pfn (pai_to_page (void *) initrd_start) <min_low_pfn ){
Printk (kern_crit "initrd overwritten (0x % 08lx <0x % 08lx )-"
"Disabling it./N ",
Page_to_pfn (pai_to_page (void *) initrd_start )),
Min_low_pfn );
Initrd_start = 0;
}
# Endif
// Page initialization. Refer to the above cgroup Mechanism
Page_cgroup_init ();
// Enable debug for page assignment
Enable_debug_pagealloc ();
// The function is null.
Kmemtrace_init ();
// How does memory lead detect initialization ???
Kmemleak_init ();
//
// Called after the kmem_caches are functional to setup a dedicated
// Cache pool, which has the slab_debug_objects flag set. This flag
// Prevents that the debug code is called on kmem_cache_free () for
// Debug tracker objects to avoid recursive CILS.
// After kmem_caches, a high-speed buffer pool is created and the slab_debug_objects flag is created .???
Debug_objects_mem_init ();
// IDR indicates the integer ID management mechanism in the Linux kernel,
// In essence, this is a mechanism that associates an integer ID number with a specific pointer.
// The IDR mechanism applies to the places where an integer and a specific pointer need to be associated.
// Http://blogold.chinaunix.net/u3/93255/showart_2524027.html
Idr_init_cache ();
// Is SMP supported? Is one core required ?? This should be analyzed
Setup_per_cpu_pageset ();
// NUMA (non uniform memory access) Policy
// What is it?
Numa_policy_init ();
If (late_time_init)
Late_time_init ();
// Initialize the scheduling clock
Sched_clock_init ();
// The calibrate_delay () function calculates the number of extremely short cycles executed by the CPU in one second,
// Obtain the bogomips value after processing the calculated value,
// Bogo indicates bogus (pseudo). MIPs is the abbreviation of millions of instructions per second (Millions of commands per second.
// In this way, we know that this function is actually a CPU performance test function in the Linux kernel.
// Http://blogold.chinaunix.net/u2/86768/showart_2196664.html
Calibrate_delay ();
// PID is the abbreviation of process ID
// Http://blog.csdn.net/satanwxd/archive/2010/03/27/5422053.aspx
Pidmap_init ();
// From mm/RMAP. c
// Allocate an anon_vma_cacheas the slab cache of anon_vma.
// This technology is an integral part of pfra (page box recycling algorithm) technology.
// This technology is born for positioning-quickly locates all page table items pointing to the same page box.
Anon_vma_init ();
# Ifdef config_x86
If (efi_enabled)
Efi_enter_virtual_mode ();
# Endif
// Create thread_info Cache
Thread_info_cache_init ();
// I applied for an slab to store credentials ?????? How to Understand?
Cred_init ();
// Calculate the number of processes allowed to be created based on the physical memory size
// Http://www.jollen.org/blog/2006/11/jollen_linux_3_fork_init.html
Fork_init (totalram_pages );
// Allocate the corresponding object cache area to various resource management structures of the process
// Http://www.shangshuwu.cn/index.php/linux
Proc_caches_init ();
// Create buffer_head slab Cache
Buffer_init ();
// Initialize the management stuff of the key
Key_init ();
// Initialization of system security, mainly Access Control
// Http://blog.csdn.net/nhczp/archive/2008/04/29/2341194.aspx
Security_init ();
// Related to debug Kernel
Dbg_late_init ();
// Call the kmem_cache_create () function to create various slab distributor caches for VFS
// Includes four slab distributor caches: names_cache, filp_cache, dquot_cache, and bh_cache.
Vfs_caches_init (totalram_pages );
// Create a signal queue
Signals_init ();
/* Rootfs populating might need page-writeback */
// Write-back Initialization
// Http://blog.csdn.net/yangp01/archive/2010/04/06/5454822.aspx
Page_writeback_init ();
# Ifdef config_proc_fs
Proc_root_init ();
# Endif
// It initializes the remaining subsys and then adds init_css_set to the hash array css_set_table.
// In the code above, css_set_hash () is the hash function of css_set_table.
// It is css_set-> subsys, which is the hash key value. Find the corresponding item in css_set_table [] and call hlist_add_head () to add init_css_set to the conflict item.
// Then, the cgroup file system is registered. This file system must be mounted when you use cgroup in your space.
// Finally, a file named cgroups is created under the root directory of Proc to observe the status of cgroup from the user space.
// Http://blogold.chinaunix.net/u1/51562/showart_1736813.html
Cgroup_init ();
// Http://blogold.chinaunix.net/u1/51562/showart_1777937.html
Cpuset_init ();
//// Process state Initialization is actually a high-speed cache that stores the thread state.
Taskstats_init_early ();
Delayacct_init ();
// This is an empty function.
Imv_init_complete ();
// Test various CPU defects and record detected defects so that other parts of the kernel can be used later.
Check_bugs ();
// Power-related Initialization
// Http://blogold.chinaunix.net/u/548/showart.php? Id = 377952
Acpi_early_init ();/* Before lapic and SMP init */
//
Sfi_init_late ();
Ftrace_init ();
/* Do the rest non-_ init 'ed, we're now alive */
// Create process 1 for detailed analysis
Rest_init ();
}

 

 

 

Http://blog.csdn.net/skywalkzf/article/details/6415708 rest_init Analysis

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.