_ Define_initcall (Level, FN)

Source: Internet
Author: User

In Linux drivers, _ define_initcall (Level, FN) is often used, especially in the driver and init function, for example, the i2c_adapter driver has such a function subsys_initcall (imapx200_i2c_adap_init). For details about its usage, refer to the following documents.

 

Macro definition _ define_initcall (Level, FN) is very important for Kernel initialization. It instructs the compiler, place the starting address values of a series of initialization functions in a certain order in a section. In the kernel initialization segment, do_initcballs () extracts the starting addresses of these functions in the form of function pointers from this section in order to complete the corresponding initialization in sequence. The initialization of some parts of the kernel depends on the initialization of some other parts, so this order is often very important.

Which is defined from the _ define_initcall (Level, FN) Macro?CodeStart with the analysis and name it initcall in sequence. the section structure of init, and finally analyzes how the kernel initialization function do_initcballs () utilizes macro definition _ define_initcall (Level, FN) and its related derived seven macro definitions, to initialize some parts of the kernel in sequence.

1. Analysis _ define_initcall (Level, FN) macro definition
1) The macro is defined in inlclude \ Linux \ init. h:
# DEFINE _ define_initcall (Level, FN )\
Static initcall_t _ initcall _ # FN \
_ Attribute _ (_ Section _ (". initcall" level ". init ")))\
= FN
Initcall_t is a function pointer type:
Typedef int (* initcall_t) (void );
Attribute _ attribute _ (_ Section _ () indicates that the object is placed in the section referred to by the name in the brackets. Therefore, the definition of this macro is as follows: 1) declare a function pointer named _ initcall _ # FN (where # indicates replacing the connection); 2) initialize this function pointer to FN; 3) during compilation, place this function pointer variable to the name ". initcall "level ". init "section (for example, level =" 1 ", indicates that the section name is ". initcall1.init ").
2) Example: __define_initcall (6, pci_init)
The macro call above indicates: 1) declare a function pointer _ initcall_pic_init = pci_init; and 2) the pointer Variable _ initcall_pic_init needs to be placed in the name. initcall6.init section (the essence is to place the first address of this function pic_init in this section ).
3) This macro is not directly used, but is defined as the following other simpler 7 derivative macros.
These macro extensions are also defined in inlclude \ Linux \ init. h:
# Define core_initcall (FN) _ define_initcall ("1", FN)
# Define postcore_initcall (FN) _ define_initcall ("2", FN)
# Define arch_initcall (FN) _ define_initcall ("3", FN)
# Define subsys_initcall (FN) _ define_initcall ("4", FN)
# Define fs_initcall (FN) _ define_initcall ("5", FN)
# Define device_initcall (FN) _ define_initcall ("6", FN)
# Define late_initcall (FN) _ define_initcall ("7", FN)
Therefore, the function pointer declared by macro core_initcall () will be placed in the name. initcall1.init section, and the function pointer declared by macro postcore_initcall () will be placed in the name. initcall2.init section, and so on.
4) Example: device_initcall (pci_init)
Interpretation is as follows: 1-2 ).
2. Related to the initialization call section -- initcall. init is divided into seven subsections.
1) They are. initcall1.init,. initcall2.init,..., and. initcall7.init in sequence.
2) sort by order
3) their definitions are in vmlinux. LDS. S.
For example, for i386 +, there are:
_ Initcall_start = .;
. Initcall. init :{
* (. Initcall1.init)
* (. Initcall2.init)
* (. Initcall3.init)
* (. Initcall4.init)
* (. Initcall5.init)
* (. Initcall6.init)
* (. Initcall7.init)
}
_ Initcall_end = .;
In makefile

Ldflags_vmlinux + =-t arch/$ (ARCH)/kernel/vmlinux. LDS. s
4) The total start position of the seven sections is marked as _ initcall_start, and the end is marked as _ initcall_end.
3. the kernel initialization function do_basic_setup (): do_initcall() will start from. initcall. in init, all function pointers are retrieved from the seven sections in turn, and the functions pointed to by these function pointers are called to complete kernel initialization.
The function is defined in init \ main. C:
Extern initcall_t _ initcall_start, _ initcall_end;
Static void _ init do_initcils (void)
{
Initcall_t * call;
....
For (call = & __ initcall_start; call

**************************************** *******************************

If you want an initialization function to be called during kernel initialization, you should use macro _ define_initcall (Level, FN) or its seven derivative macros are used to place the initial address of the FN initialization function to the related section in the initialization order. During kernel initialization, do_initcballs () will find these functions in sequence from this section for execution.

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.