mirror of
https://github.com/0xAX/linux-insides.git
synced 2024-12-22 06:38:07 +00:00
Concpets: initcall: Fixed typos and other errors.
Signed-off-by: Piyush Pangtey <gokuvsvegita@gmail.com>
This commit is contained in:
parent
e8f10c1e3f
commit
bc1144ea67
@ -4,7 +4,7 @@ The initcall mechanism
|
||||
Introduction
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
As you may understand from the part's title, this part will cover interesting and important concpet in the Linux kernel which is called - `initcall`. We already saw definitions like these:
|
||||
As you may understand from the title, this part will cover interesting and important concept in the Linux kernel which is called - `initcall`. We already saw definitions like these:
|
||||
|
||||
```C
|
||||
early_param("debug", debug_kernel);
|
||||
@ -16,7 +16,7 @@ or
|
||||
arch_initcall(init_pit_clocksource);
|
||||
```
|
||||
|
||||
in some parts of the Linux kernel. Before we will see how this mechanism is implemented in the Linux kernel, we must know actually what is it and how the Linux kernel uses it. Definitions like these represent a [callback](https://en.wikipedia.org/wiki/Callback_%28computer_programming%29) function which will be called during initialization of the Linux kernel or right after. Actually the main point of the `initcall` mechanism is to determine correct order of the built-in modules and subsystems initialization. For example let's look at the following function:
|
||||
in some parts of the Linux kernel. Before we see how this mechanism is implemented in the Linux kernel, we must know actually what is it and how the Linux kernel uses it. Definitions like these represent a [callback](https://en.wikipedia.org/wiki/Callback_%28computer_programming%29) function which will be called during initialization of the Linux kernel or right after it. Actually the main point of the `initcall` mechanism is to determine correct order of the built-in modules and subsystems initialization. For example let's look at the following function:
|
||||
|
||||
```C
|
||||
static int __init nmi_warning_debugfs(void)
|
||||
@ -44,7 +44,7 @@ The Linux kernel calls all architecture-specific `initcalls` before the `fs` rel
|
||||
* `device`;
|
||||
* `late`.
|
||||
|
||||
All of their names are represetned by the `initcall_level_names` array which is defined in the [init/main.c](https://github.com/torvalds/linux/blob/master/init/main.c) source code file:
|
||||
All of their names are represented by the `initcall_level_names` array which is defined in the [init/main.c](https://github.com/torvalds/linux/blob/master/init/main.c) source code file:
|
||||
|
||||
```C
|
||||
static char *initcall_level_names[] __initdata = {
|
||||
@ -59,7 +59,7 @@ static char *initcall_level_names[] __initdata = {
|
||||
};
|
||||
```
|
||||
|
||||
All functions which are marked as `initcall` by these identificators, will be called in the same order or at first will be called `early initcalls`, at second `core initcalls` and etc. From this moment we know a little about `initcall` mechanism, so we can start to dive into the source code of the Linux kernel to see how this mechanism implemented.
|
||||
All functions which are marked as `initcall` by these identificators, will be called in the same order or at first `early initcalls` will be called, at second `core initcalls` and etc. From this moment we know a little about `initcall` mechanism, so we can start to dive into the source code of the Linux kernel to see how this mechanism is implemented.
|
||||
|
||||
Implementation initcall mechanism in the Linux kernel
|
||||
--------------------------------------------------------------------------------
|
||||
@ -77,9 +77,9 @@ The Linux kernel provides a set of macros from the [include/linux/init.h](https:
|
||||
#define late_initcall(fn) __define_initcall(fn, 7)
|
||||
```
|
||||
|
||||
and as we may see just expands to the call of the `__define_initcall` macro from the same header file. As we may see, the `__define_inticall` macro takes two arguments:
|
||||
and as we may see these macros just expands to the call of the `__define_initcall` macro from the same header file. As we may see, the `__define_inticall` macro takes two arguments:
|
||||
|
||||
* `fn` - callback function which is will be called during call of `initcalls` of the certain level;
|
||||
* `fn` - callback function which will be called during call of `initcalls` of the certain level;
|
||||
* `id` - identificator to identify `initcall` to prevent error when two the same `initcalls` point to the same handler.
|
||||
|
||||
The implementation of the `__define_initcall` macro looks like:
|
||||
@ -91,7 +91,7 @@ The implementation of the `__define_initcall` macro looks like:
|
||||
LTO_REFERENCE_INITCALL(__initcall_##fn##id)
|
||||
```
|
||||
|
||||
To understand the `__define_initcall` macro, first of all let's look at the `initcall_t` type. This type is defined in the same [header]() file and represetns pointer to a function which returns pointer to [integer](https://en.wikipedia.org/wiki/Integer) which will be result of the `initcall`:
|
||||
To understand the `__define_initcall` macro, first of all let's look at the `initcall_t` type. This type is defined in the same [header]() file and represents pointer to a function which returns pointer to [integer](https://en.wikipedia.org/wiki/Integer) which will be result of the `initcall`:
|
||||
|
||||
```C
|
||||
typedef int (*initcall_t)(void);
|
||||
@ -135,7 +135,7 @@ which prevents `variable defined but not used` warning. The last line of the `__
|
||||
LTO_REFERENCE_INITCALL(__initcall_##fn##id)
|
||||
```
|
||||
|
||||
depens on the `CONFIG_LTO` kernel configuration option and just provides stub for the compiler [Link time optimization](https://gcc.gnu.org/wiki/LinkTimeOptimization):
|
||||
depends on the `CONFIG_LTO` kernel configuration option and just provides stub for the compiler [Link time optimization](https://gcc.gnu.org/wiki/LinkTimeOptimization):
|
||||
|
||||
```
|
||||
#ifdef CONFIG_LTO
|
||||
@ -255,7 +255,7 @@ int __init_or_module do_one_initcall(initcall_t fn)
|
||||
}
|
||||
```
|
||||
|
||||
Let's try to understand what does the `do_on_initcall` function does. First of all we increase [preemtion](https://en.wikipedia.org/wiki/Preemption_%28computing%29) counter to check it later to be sure that it is not imbalanced. After this step we can see the call of the `initcall_bakclist` function which
|
||||
Let's try to understand what does the `do_on_initcall` function does. First of all we increase [preemption](https://en.wikipedia.org/wiki/Preemption_%28computing%29) counter to check it later to be sure that it is not imbalanced. After this step we can see the call of the `initcall_backlist` function which
|
||||
goes over the `blacklisted_initcalls` list which stores blacklisted `initcalls` and releases the given `initcall` if it is located in this list:
|
||||
|
||||
```C
|
||||
@ -285,7 +285,7 @@ Depends on the valule of the `initcall_debug` variable, the `do_one_initcall_deb
|
||||
bool initcall_debug;
|
||||
```
|
||||
|
||||
and provides ability to print some informatinion to the kernel [log buffer](https://en.wikipedia.org/wiki/Dmesg). The value of the variable can be set from the kernel commandle via the `initcall_debug` parameter. As we can read from the [documentation](https://www.kernel.org/doc/Documentation/kernel-parameters.txt) of the Linux kernel command line:
|
||||
and provides ability to print some information to the kernel [log buffer](https://en.wikipedia.org/wiki/Dmesg). The value of the variable can be set from the kernel commands via the `initcall_debug` parameter. As we can read from the [documentation](https://www.kernel.org/doc/Documentation/kernel-parameters.txt) of the Linux kernel command line:
|
||||
|
||||
```
|
||||
initcall_debug [KNL] Trace initcalls as they are executed. Useful
|
||||
@ -315,7 +315,7 @@ static int __init_or_module do_one_initcall_debug(initcall_t fn)
|
||||
}
|
||||
```
|
||||
|
||||
As an `initcall` was called by the one of the ` do_one_initcall` or `do_one_initcall_debug` functions, we may see two checks in the end of the `do_one_initcall` function. The first check amount of possible `__preempt_count_add` and `__preempt_count_sub` calls inside of the executed initcall, and if this value is not equal to the previous value of the preemptible counter, we add the `preemption imbalance` string to the message buffer and set correct value of the preemptible counter:
|
||||
As an `initcall` was called by the one of the ` do_one_initcall` or `do_one_initcall_debug` functions, we may see two checks in the end of the `do_one_initcall` function. The first one checks the amount of possible `__preempt_count_add` and `__preempt_count_sub` calls inside of the executed initcall, and if this value is not equal to the previous value of the preemptible counter, we add the `preemption imbalance` string to the message buffer and set correct value of the preemptible counter:
|
||||
|
||||
```C
|
||||
if (preempt_count() != count) {
|
||||
@ -341,7 +341,7 @@ First of all, we have missed one level of `initcalls`, this is `rootfs initcalls
|
||||
#define rootfs_initcall(fn) __define_initcall(fn, rootfs)
|
||||
```
|
||||
|
||||
As we may understand from the macro's name, its main purpose to store callbacks which are related to the [rootfs](https://en.wikipedia.org/wiki/Initramfs). Besides this goal, it may be useful to initialize a stuff after initialization related to filesystems level, but before devices related stuff not initizlied. For example, the decompression of the [initramfs](https://en.wikipedia.org/wiki/Initramfs) which is occurred in the `populate_rootfs` function from the [init/initramfs.c](https://github.com/torvalds/linux/blob/master/init/initramfs.c) source code file:
|
||||
As we may understand from the macro's name, its main purpose is to store callbacks which are related to the [rootfs](https://en.wikipedia.org/wiki/Initramfs). Besides this goal, it may be useful to initialize other stuffs after initialization related to filesystems level, but only before devices related stuff are not initialized. For example, the decompression of the [initramfs](https://en.wikipedia.org/wiki/Initramfs) which occurred in the `populate_rootfs` function from the [init/initramfs.c](https://github.com/torvalds/linux/blob/master/init/initramfs.c) source code file:
|
||||
|
||||
```C
|
||||
rootfs_initcall(populate_rootfs);
|
||||
|
Loading…
Reference in New Issue
Block a user