In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-04-13 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/03 Report--
A driver can be dynamically loaded into the kernel as a module, or statically compiled into the kernel as a part of the kernel, and the function of module_init/module_exit is to load the driver into the kernel dynamically.
In addition to initializing the load, module_init also has the function of releasing memory later. A large part of the code in linux kernel is device driver code, which has initialization and deinitialization functions. These codes are usually executed only once. In order to make more efficient use of memory, the memory occupied by these codes can be released.
Linux does this by adding the _ _ init attribute to all functions that need to be initialized and run only once. The _ _ init macro tells the compiler to put the function in the section (.init.text) if the module is compiled into the kernel. The parameter of module_exit is similar to _ _ init when it is unloaded. If the driver is compiled into the kernel, the _ _ exit macro ignores the cleanup function, because the module compiled into the kernel does not need to clean up. Obviously _ _ init and _ _ exit are invalid for dynamically loaded modules and only support full compilation into the kernel.
In the later stages of kernel initialization, release the memory space occupied by all these function codes. The connector puts the function with the _ _ init attribute in the same section, and after using it, releases the entire section. This area can be cleared to save system memory when the function is initialized. The message "Freeing unused kernel memory: xxxk freed" that Kenrel sees when it starts is related to it.
Let's look at the source code. In init/main.c, start_kernel is the first c function that enters kernel (), and the last line of this function is rest_init ().
Static void rest_init (void)
{
.
Kernel_thread (kernel_init, NULL, CLONE_FS | CLONE_SIGHAND)
Unlock_kernel ()
Cpu_idle ()
.
}
A kernel thread is created with a function at the end of the main function kernel_init:
/ *
* Ok, we have completed the initial bootup, and
* we're essentially up and running. Get rid of the
* initmem segments and start the user-mode stuff..
, /
Init_post ()
The first sentence in this init_post is free_initmem (); it is used to release initialization code and data.
Void free_initmem (void)
{
If (! machine_is_integrator () & &! machine_is_cintegrator ()) {
Free_area ((unsigned long) (& _ _ init_begin)
(unsigned long) (& _ _ init_end)
"init")
}
}
Next up is kernel memory management.
Just as you need to include the header files of the C library for writing C programs, Linux kernel programming also needs to include Kernel header files, and most Linux drivers need to include the following three header files:
# include
# include
# include
Among them, init.h defines the functions related to driver initialization and exit, (module_init, module_exit)
Kernel.h defines frequently used function prototypes and macro definitions
Module.h defines functions, variables, and macros related to kernel modules.
Almost every linux driver has a module_init (defined with module_exit in Init.h (/ include/linux)). Yes, the loading of the driver depends on it. Why do you need such a macro? The reason is that according to the general programming idea, each part of the initialization function will be called in a fixed function, such as:
Void init (void)
{
Init_a ()
Init_b ()
}
If you add another initialization function, then add a line after init_b (): init_c (); this can indeed complete our function, but this has some problems, that is, you cannot add an initialization function independently. Every time you add a new function, you have to modify the init function. You can deal with this in another way, as long as you decorate it with a macro:
Void init_a (void)
{
}
_ _ initlist (init_a, 1)
How does it initialize the list of functions through this macro? Let's first take a look at the definition of _ _ initlist:
# define _ _ init _ _ attribute__ ((unused, _ _ section__ (".initlist"))
# define _ _ initlist (fn, lvl) /
Static initlist_t _ _ init_##fn _ _ init = {/
Magic: INIT_MAGIC, /
Callback: fn, /
Level: lvl}
Please note: _ _ section__ (".initlist"), what does this attribute do? It tells the connector that the variable is stored in the .initlist section, and if all initialization functions use this macro, then each function will have a corresponding initlist_t structure variable stored in the .initlist section, that is, we can find pointers to all initialization functions in the .initlist section. How can I find the address of the .initlist section?
Extern u32 _ _ initlist_start
Extern u32 _ _ initlist_end
These two variables work. _ _ initlist_start is the beginning of the .initlist section and _ _ initlist_end is the end. Through these two variables, we can access all initialization functions. Where are these two variables defined? In a connector script file
. = ALIGN (4)
.initlist: {
_ _ initlist_start =.
* (.initlist)
_ _ initlist_end =.
}
The values of these two variables are exactly defined at the beginning and end of the .initlist section, so we can access all initialization functions through these two variables.
Similarly, this method is also used in the kernel, so we write drivers independently, and we don't have to add our own code to call our own initialization and exit functions in a fixed place. The connector is ready for us. Let's analyze module_init first. The definition is as follows:
# define module_init (x) _ initcall (x); / / include/linux/init.h
# define _ initcall (fn) device_initcall (fn)
# 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
If a driver wants to use func as the entry point for the driver, it can be declared as follows: module_init (func); after being processed by the above macro, it becomes _ _ initcall_func6 _ _ used to be added to the ".initcall" area of the kernel image. When the kernel loads, it searches for all entries in ".initcall" and loads them according to priority. The priority of the normal driver sequence is 6. The priorities of other modules are listed as follows: the lower the value, the first to load.
# 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)
As you can see, it is declared to be the first to load pure_initcall.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.