Transferred from: http://www.cnblogs.com/superlcc/archive/2012/09/12/2681930.html
Now take Module_init as an example to analyze the order of Initcall calls in the kernel
In the header file Init.h, there is the following definition:
#define MODULE_INIT (x) __initcall (x);
Obviously, Module_init () is just a mask, uncover this mask, hidden underneath is __initcall ()
__initcall () Where is the sacred? Continue to reveal the truth:
#define __initcall (FN) Device_initcall (FN)
So deep, keep looking:
#define Device_initcall (FN) __define_initcall ("6", fn,6)
#define __define_initcall (Level,fn,id) \
Static initcall_t __initcall_# #fn # #id __used \
__ATTRIBUTE__ ((__section__ (". Initcall" Level ". Init"))) = fn
In the end we see the module_init: __define_initcall (level,fn,id), carefully scrutinize the true, know that this is a macro, it will pass the function name passed to module_init into __initcall prefix, The function name is suffixed with 6, and the function is defined in the code snippet. Initcall6.init inside.
In the code snippet. Initcall6.init inside? What the hell is this function hiding here for? Locate the file vmlinux.lds.h with this string, and the associated code is as follows:
#define INITCALLS \
* (. initcallearly.init) \
Vmlinux_symbol (__early_initcall_end) =.; \
* (. initcall0.init) \
* (. initcall0s.init) \
* (. initcall1.init) \
* (. initcall1s.init) \
* (. initcall2.init) \
* (. initcall2s.init) \
* (. initcall3.init) \
* (. initcall3s.init) \
* (. initcall4.init) \
* (. initcall4s.init) \
* (. initcall5.init) \
* (. initcall5s.init) \
* (. initcallrootfs.init) \
* (. initcall6.init) \
* (. initcall6s.init) \
* (. initcall7.init) \
* (. Initcall7s.init)
Deadly, but also a strange macro, but fortunately he looks not ugly, and find out the law, see what this is a thing?
The string. Initcall6.init inclusions in this macro of the nth row, the specific number of their own, they are all in order to form a whole, and this whole constitutes a macro written in uppercase Initcalls, from the momentum of this thing to give people a good feeling, so magical, then he was there?
The pit father's, pale no find place, came very much time, he unexpectedly in a remote VMLINUX.LDS.S inside! Estimated beyond the range of children's shoes can be accepted, it is not, this is a compilation file! Ah, anyway, traced source to find the Initcalls's mother, but found that this is a completely strange world! The egg for this pain for a long time, eventually still muster up to Wu song fight the tiger Courage still rushed in. People say despair after there will be hope, Willow dark after another village, brother I eyeful with tears in the discovery they are human! This excitement ah, not few words can be said clearly, to see initcalls her family house how:
............ Omit a large segment of ......
__initcall_start =.;
Initcalls
__initcall_end =.;
__con_initcall_start =.;
* (. Con_initcall.init)
__con_initcall_end =.;
__security_initcall_start =.;
* (. Security_initcall.init)
__security_initcall_end =.;
............ Omit a large paragraph ..... ......
Do you think this is still a little humanitarian, not like Arabic for or Tibetan as you want to jump off, to meet its three big aunt, for like __initcall_start =. With __initcall_end =. Like Hujiahuwei, we've had a lot of trouble with him when we were a newcomer. , the impression is quite profound, see it's decay at a glance, here is not the dot is the current address, an equal sign is not the current address of the point is paid to the left of the variable, it is difficult to have two brushes of my, according to this, reckoned with __initcall_start and __ Initcall_end will have an accomplice in. c files and their dark-boyfriends in collusion, will be a good tease it again, pass first, and then see what's new, eh? No, or back, no pain I generally will not be asked to taste, the sweetness is another, hahaha,
To the point, initcalls in __initcall_start =. and __initcall_end =, the relevant paragraph code that represents the connotation of the Initcalls macro is stored here, and Module_init represents the mosaic of the segment, Waiting for one turn to be patronize, from initcalls content to see it was visited at the time of the row or quite after, then the other is He Shan it? It looks the following decomposition:
#define Pure_initcall (FN) __define_initcall ("0", fn,0)
#define Core_initcall (FN) __define_initcall ("1", fn,1)
#define CORE_INITCALL_SYNC (FN) __define_initcall ("1s", fn,1s)
#define Postcore_initcall (FN) __define_initcall ("2", fn,2)
#define POSTCORE_INITCALL_SYNC (FN) __define_initcall ("2s", fn,2s)
#define Arch_initcall (FN) __define_initcall ("3", fn,3)
#define ARCH_INITCALL_SYNC (FN) __define_initcall ("3s", fn,3s)
#define Subsys_initcall (FN) __define_initcall ("4", fn,4)
#define SUBSYS_INITCALL_SYNC (FN) __define_initcall ("4s", fn,4s)
#define Fs_initcall (FN) __define_initcall ("5", fn,5)
#define FS_INITCALL_SYNC (FN) __define_initcall ("5s", fn,5s)
#define Rootfs_initcall (FN) __define_initcall ("Rootfs", Fn,rootfs)
#define Device_initcall (FN) __define_initcall ("6", fn,6)
#define DEVICE_INITCALL_SYNC (FN) __define_initcall ("6s", fn,6s)
#define Late_initcall (FN) __define_initcall ("7", fn,7)
#define LATE_INITCALL_SYNC (FN) __define_initcall ("7s", fn,7s)
At this point we should understand how each initcall and how it is organized in the Code storage space, let's see what the kernel is calling it.
The kernel boot process is as follows
Main () Àlinux_main () àstart_uml () Àstart_kernel_proc () Àstart_kernelàrest_initàkernel_initàdo_basic_setupàdo_ Initcalls
The code for Do_initcalls is shown below
static void __init do_initcalls (void)
{
initcall_t *call;
for (call = __early_initcall_end, call < __initcall_end; call++)
Do_one_initcall (*call);
/* Make sure there are no pending stuff from the initcall sequence */
Flush_scheduled_work ();
}
In the above code, __early_initcall_end is defined in Initcalls, __initcall_end is defined in the file vmlinux.lds.s, they represent the starting and ending addresses of some of the initialization functions of the pointer array, the execution function do_ Initcalls, the sequence of functions contained in the array of pointers is called to perform some necessary initialization work. At this point, understand the initcall of the implementation of the moment.
Execution sequencing of various initcall (Module_init, Postcore_initcall, Arch_initcall, Subsys_initcall, Fs_initcall) "Turn"