Kernel options during boot
Linux users pass the Kernel configuration options to the Boot Record, The Boot Record, and then the options to the kernel, and then fine-tune the kernel through the boot configuration parameters. During system boot, parse_args is called to parse the configuration parameters entered during boot twice.
The input string parameters for parse_args function parsing are in the form of "variable name = value". Appropriate processing functions are enabled Based on the parsed keywords. When the module is loaded, parse_args is also used to parse the command column parameters.
Keyword Registration
Kernel components use the _ setup macro defined in include/Linux/init. h to register keywords and related processing functions:
_ Setup (string, function_handler)
String is the keyword, while function_handler is the associated processing function. When the kernel is initialized, The parse_args function parses the string keyword to be, and then runs the related function_handler function, but the string must end with the = character, any string that follows the = character will be passed to the function_handler function as a function input parameter. These parameters are stored in the memory block. setup. init.
For example, in the arch \ Arm \ kernel \ process. c file, you only need to enter a keyword for the instance:
Static int _ init nohlt_setup (char * _ unused)
{
Hlt_counter = 1;
Return 1;
}
Static int _ init hlt_setup (char * _ unused)
{
Hlt_counter = 0;
Return 1;
}
_ Setup ("nohlt", nohlt_setup );
_ Setup ("hlt", hlt_setup );
In the net/core/dev. c file of the network subsystem, the netdev = keyword and corresponding processing function netdev_boot_setup are registered:
Int _ init netdev_boot_setup (char * str)
{
Int ints [5];
Struct ifmap map;
Str = get_options (str, ARRAY_SIZE (ints), ints );
If (! Str |! * Str)
Return 0;
/* Save settings */
Memset (& map, 0, sizeof (map ));
If (ints [0]> 0)
Map. irq = ints [1];
If (ints [0]> 1)
Map. base_addr = ints [2];
If (ints [0]> 2)
Map. mem_start = ints [3];
If (ints [0]> 3)
Map. mem_end = ints [4];
/* Add new entry to the list */
Return netdev_boot_setup_add (str, & map );
}
_ Setup ("netdev =", netdev_boot_setup );
In the net/ethernet/eth. c file, the ether = keyword is registered to the same handler netdev_boot_setup.
_ Setup ("ether =", netdev_boot_setup );
When one end of the Code is compiled as a module, the __setup Macro will be taken care of, that is, it is defined as a null operation.
# Ifndef MODULE
......
# DEFINE _ setup (STR, FN )\
_ Setup_param (STR, FN, FN, 0)
......
# Else
......
# DEFINE _ setup (STR, func)/* nothing */
# Endif
In the init \ main. c file, in the start_kernel function:
Asmlinkage void _ init start_kernel (void)
{
......
Parse_early_param ();
Parse_args ("booting kernel", static_command_line, _ start ___ Param,
_ Stop ___ param-_ start ___ Param,
& Unknown_bootoption );
......
}
Start_kernel calls parse_args twice to parse the bootstrap configuration parameters because the parameters during the bootstrap process are actually divided into two categories. Each call is for one of the following types:
- Default Option: Most parameters belong to this category. These parameters are defined by the _ setup macro and are processed when parse_args is called for the second time.
- Early options: some options need to be processed earlier during kernel boot. These parameters are defined by the early_param macro instead of the _ setup macro. These options are the responsibility of parse_early_params. The only difference between early_param and _ setup macros is that early_param sets a special mark to distinguish the inner nuclear energy from the two situations, which is part of the obs_kernel_param data structure.
# DEFINE _ setup (STR, FN )\
_ Setup_param (STR, FN, FN, 0)
/* Note: FN is as per module_param, not _ setup! Emits warning if FN
* Returns non-zero .*/
# Define early_param (STR, FN )\
_ Setup_param (STR, FN, FN, 1)
When calling the parse_args function for the second time in the start_kernel function, the module options entered by the module_param macro are checked. These options are stored in the kernel_param data structure, the module_param macro ensures that the data structure is stored in a specific memory block (_ PARAM) with the pointer _ start ___ Param
And _ Stop ___ Param.
_ Setup_start ...... _ Setup_end: this region will be released at the end of the boot phase. You cannot view or modify these options during running;
_ Start ___ Param ...... _ Stop ___ Param: this region will not be released, and its content will be output to the/sys file system. These options can be displayed to users.
Keywords defined by the _ setup () and early_param () macros will be placed in the _ setup_start ...... In the _ setup_end region, only the keywords defined by the early_param macro are set with the early flag.
Struct obs_kernel_param {
Const char * STR;
INT (* setup_func) (char *);
Int early;
};
STR is the keyword, setup_func is the associated processing function, and early is the early mark. _ Setup_param macro: All obs_kernel_params instances are stored in the dedicated memory area, which makes it easier to traverse. The _ setup_start and _ setup_end pointers point to the beginning and end of the area respectively. When these regions are no longer used, the memory can be quickly released.