After uboot completes the system boot and copies the Linux kernel to the memory, bootm-> do_bootm_linux () jumps to the start position of the kernel;
The compressed kernel entry is in arch/ARM/boot/compressed/head. s, which decompress the call function decompress_kernel () and print "Uncompressing Linux... ", call gunzip () to print" done, booting the kernel."
Then call_kernel, run the extracted kernel, and run Linux/ARCH/ARM/kernel/head. s calls start_kernel to transfer the General C code unrelated to the architecture, and completes a series of system initialization in start_kernel (). The registration of the device and driver is completed at this time:
-------------------------
Asmlinkage void _ initStart_kernel(Void)
{
Char * command_line;
Extern struct kernel_param _ start ___ Param [], _ Stop ___ Param [];
········································ ···································
Printk (kern_notice "kernel command line: % s/n", saved_command_line );
// Print the kernel command line
Parse_early_param ();
Parse_args ("booting kernel", command_line, _ start ___ Param,
_ Stop ___ param-_ start ___ Param,
& Unknown_bootoption );
// Parse startup parameters passed by boot
········································ ···································
/* Do the rest non-_ init 'ed, we're now alive */
Rest_init ();
}
The rest_init () function in start_kernel () will create the first core thread kernel_thread (init, null, clone_fs | clone_sighand) and call the init () function:
Static intInit(Void * unused )-------------------
{
·······················
Do_basic_setup ();
······················
/*
* We try each of these until one succeeds.
*
* The Bourne shell can be used instead of init if we are
* Trying to recover a really broken machine.
*/
If (execute_command) {// determines whether the init parameter is specified at startup
// If this parameter is specified, the INIT process of the user is executed. If the process succeeds, no response is returned.
Run_init_process (execute_command );
Printk (kern_warning "failed to execute % S. Attempting"
"Defaults.../N", execute_command );
}
/* If the init startup parameter is not specified, search for the INIT process in the following directory. If the process succeeds, no error is returned. Otherwise, an error message is printed */
Run_init_process ("/sbin/init ");
Run_init_process ("/etc/init ");
Run_init_process ("/bin/init ");
Run_init_process ("/bin/sh ");
Panic ("No init found. Try passing init = option to kernel .");
}
Then call the do_basic_setup () function (the system structure-related part has been initialized, and the device is initialized now ):
/*
* OK, the machine is now initialized. None of the devices
* Have been touched yet, but the CPU subsystem is up and
* Running, and memory and process management works.
*
* Now we can finally start doing some real work ..
*/
Static void _ initDo_basic_setup(Void )-----------------
{
/* Drivers will send hotplug events */
Init_workqueues ();
Usermodehelper_init ();
Driver_init (); // establishes a device model subsystem.
# Ifdef config_sysctl
Sysctl_init ();
# Endif
/* Networking initialization needs a process context */
Sock_init ();
Do_initcils (); // system initialization (including devices, file systems, and kernel modules)
}
-------------------------
/**
* Driver_init-Initialize driver model.
*
* Call the driver model init functions to initialize their
* Subsystems. called early from init/Main. C.
*/
Void _ initDriver_init(Void)
{
/* These are the core pieces */
Devices_init ();
-------------
Int _ init devices_init (void)
{
Return subsystem_register (& devices_subsys );
}
-----------------------
Buses_init ();
Classes_init ();
Firmware_init ();
/* These are also core pieces, but must come after
* Core pieces.
*/
Platform_bus_init ();
System_bus_init ();
Cpu_dev_init ();
Memory_dev_init ();
Attribute_container_init ();
}
---------------------------
Extern initcall_t _ initcall_start [], _ initcall_end [];
Static void _ initDo_initcils(Void)
{
Initcall_t * call;
Int COUNT = preempt_count ();
For (call = _ initcall_start; call -----------------
_ Initcall_start = .;
* (. Initcall1.init)
* (. Initcall2.init)
* (. Initcall3.init)
* (. Initcall4.init)
* (. Initcall5.init)
* (. Initcall6.init)
* (. Initcall7.init)
_ Initcall_end = .;
---------------------
# Ifndef module/* If the driver module is statically compiled into the kernel */
········································ ·······
/* Initcils are now grouped by functionality into separate
* Subsections. Ordering inside the subsections is determined
* By link order.
* For backwards compatibility, initcall () puts the call in
* The device init subsection.
*/
# DEFINE _ define_initcall (Level, FN )/
Static initcall_t _ initcall _ # FN _ attribute_used __/
_ Attribute _ (_ Section _ (". initcall" level ". init") = FN
# Define core_initcall (FN) _ define_initcall ("1", FN)
# Define postcore_initcall (FN) _ define_initcall ("2", FN)
# Define arch_initcall (FN) _ define_initcall ("3", FN)
// The device is initialized here
/* ---- Eg: arch_initcall (at91sam9261_device_init )---
Static int _ init at91sam9261_device_init (void)
{
At91_add_device_udc ();
At91_add_device_dm9000 ();
Armebs3_add_input_buttons ();
Return platform_add_devices (at91sam9261_devices, array_size (at91sam9261_devices ));
}
------------------------*/
# Define subsys_initcall (FN) _ define_initcall ("4", FN)
# Define fs_initcall (FN) _ define_initcall ("5", FN)
# Define device_initcall (FN) _ define_initcall ("6", FN)
// Initialize the driver module for static compilation.
# Define late_initcall (FN) _ define_initcall ("7", FN)
# DEFINE _ initcall (FN) device_initcall (FN)
/**
* Module_init ()-driver initialization entry point
* @ X: function to be run at kernel boot time or module insertion
*
* Module_init () will either be called during do_initcils (if
* Builtin) or at module insertion time (if a module). There can only
* Be one per module.
*/
# Define module_init (x) _ initcall (X );
// The statically compiled driver module, as device_initcall, is called by do_initcils when the kernel is started.
/**
* Module_exit ()-driver exit entry point
* @ X: function to be run when driver is removed
*
* Module_exit () will wrap the driver clean-up code
* With cleanup_module () when used with rmmod when
* The driver is a module. If the driver is statically
* Compiled into the kernel, module_exit () has no effect.
* There can only be one per module.
*/
# Define module_exit (x) _ exitcall (X );
# Else/* module if the driver module dynamically loads the kernel */
········································ ·······
/* Each module must use one module_init (), or one no_module_init */
# Define module_init (initfn )/
Static inline initcall_t _ inittest (void )/
{Return initfn ;}/
Int init_module (void) _ attribute _ (alias (# initfn )));
// Insmod is called through the system sys_init_module (const char * name_user, struct module * mod_user)
// Load the dynamic driver module into the kernel space
/* This is only required if you want to be unloadable .*/
# Define module_exit (exitfn )/
Static inline exitcall_t _ exittest (void )/
{Return exitfn ;}/
Void cleanup_module (void) _ attribute _ (alias (# exitfn )));
-----------------------------
This article is from the chinaunix blog. If you want to view the original text, click:Http://blog.chinaunix.net/u2/68846/showart_694377.html