Kernel Symbols and Config_modversions

Source: Internet
Author: User
Kernel Symbols and Config_modversions

Know modversion pretty good article, behind have linuxforum friend translation of Chinese version
-------------------------------------
Kernel Symbols and Config_modversions
-------------------------------------

Mark McLoughlin
mark@skynet.ie
Tue Mar 13, 2001

=================
Exporting symbols
=================

By default, no global variables or functions defined in a module
are exported to the kernel symbol table while the module is loaded.
However, there are ways which you could control which symbols
Exported.

If you are require that none of the module ' s symbols are exported
can use the Export_no_symbols macro.

If However, you require this only some of your global symbols
are exported you'll need to use the Export_symbol macro to EXPORT it.
If Config_modversions is turned on a further the "is required in"
Build process, but that would be explained later.

======================
How do does this Work?
======================

A kernel module that explicitly exports symbols'll have two
Special sections in its Object file:the symbol table ' __ksymtab ' and
The string table '. Kstrtab '. When a symbol was exported by a module
Using Export_symbol, two things happen:

o A string, which is either the symbol name or
Config_modversions is turned on, the symbol name with some
Extra versioning info attached, is defined in the string table.
o A MODULE_SYMBOL structure is defined in the symbol table. This
Structure contains a pointer to the symbol itself and a
Pointer to the entry in the string table.

When a module was loaded this info was added to the kernels symbol
Table and these symbols are now treated like any of the kernel ' s
exported symbols.

To take a peek at your module ' s symbol table do

$> objdump--disassemble-j __ksymtab SUNRPC.O

Or the string table do

$> objdump--disassemble-j. Kstrtab SUNRPC.O

========================
Config_modversions et al.
========================

Config_modversions is a notion thought up to make people ' s lives
Easier. In essence, what it's meant to achieve are that if you have a
Module you can attempt to load this module into no kernel, safe in the
Knowledge that it'll fail to load if any of the kernel data
structures, types or functions that the module uses have changed.

If your kernel is isn't compiled with config_modversions enabled
'll is able to load modules the were compiled specifically for
That kernel version and that were also compiled without modversions
Enabled.

However, if your kernel is compiled with config_modversions enabled
You are able to load a module, that is compiled for the same
Kernel version with modversions turned off. But-here ' s The important
Part folks-you'll also be able to load no modules compiled with
Mdoversions turned on, as long as the kernel API the module uses
Hasn ' t changed.

======================
How do does this Work?
======================

When config_modversions are turned on the kernel then a special
Piece of versioning info is appended to every symbol exported using
Export_symbol.

This versioning info is calculated using the genksyms command whose
Man page has this to say about how the info is calculated:

When a symbol table was found in the source, the symbol would be
Expanded to it full definition, where all struct ' s, unions,
Enums and typedefs would be expanded down to their basic part,
recursively. This final string would then be used as input to a
CRC algorithm that'll give an integer that'll change as
Soon as any of the included definitions changes, for this symbol.

The version information in the kernel normally looks like:
symbol_r12345678, where 12345678 is the hexadecimal
Representation of the CRC.

What This means are that the versioning info are calculated in such a
Way as that it'll only change when is the definition of that symbol
Changes.

The versioning string is ' appended ' by the use of a #define in
Linux/modversions.h for every exported symbol. The #define Usually
Winds up looking something as this (simplified):

#define PRINTK printk_r1b7d4074

What This does are effectively get rid of the function ' PRINTK '-
Alas, poor printk-and replace it with the more handsome
' printk_r1b7d4074 '.

If you have a look at the linux/modversions.h you'll notice that it
Just includes loads of. ver files. These are generated using a command
Similar to

$> GCC-E-d__genksyms__ $ | Genksyms-k $ > $

Notice that the C file if passed through the C preprocessor
Before being passed to genksyms. This are to collapse all macros and
Stuff beforehand.

================================
What does this mean for modules?
================================

When modules are being compiled for a kernel with
Config_modversions turned on, the header file Linux/modversions.h must
Be included in the top of every C file. This is a awful pain to
Do, so we just does it with the GCC flag '-include '.

Ifdef config_modules
Ifdef config_modversions
Modflags + +-dmodversions-include $ (hpath)/linux/modversions.h
endif

The extra modversions flag is used to indicate so this is a
Module being compiled with Config_modversions turned in as opposed to
The kernel being compiled with config_modversions enabled.

#######################
Translator: This is what I have seen the most clear modversion of Linux, combined with the previous insmod of the source code
The related part, the collation of a document, hoping to help the future learners.

=================
Symbol output
=================

By default, global variables and global functions defined in all modules are exported to the kernel when the module is loaded
Symbol table (Translator: Here we understand that there is no deviation, the author means that later modules use these variables and functions,
However, it is not added to the kernel variable kernel_module, ksyms lookup is done through module_list. )。 However
There is also a way to control the output of symbols in a module.

If you want to do not have any symbol output, just need to define the macro export_no_symbols on it. However, if you want to output
Part of the symbol in the module, you can use the macro export_symbol to accomplish the purpose. If the Config_modversions macro is at this point
is defined, there will be some actions to be completed when module is compiled, and we will explain later.

======================
So how does it work.
======================

A compiled kernel module file containing the output symbol will have two section (translator: This section is not good to translate
, is the section in the Elf file, the specific information see Elfspec.pdf), one is the symbol table sections ' __ksymtab ', one is the character
string section ' Kstrtab '. Of course it has to be defined in the module in the case of Export_symbol, (translator: Here, as the author says,
If Export_symbol is defined in the module, the following two sections will be in the compiled object file if Insmod finds
Without these two section,insmod will extract all the global symbols from object to generate the two section, and these two section
Sys_init_module system calls are reflected in the SYM in the module structure and are used by the latter. Two things will happen:

1. The composition of the string even though the name of the symbol, and if config_modversions is defined, the symbol name will be followed
There are some more versions of the information. (_RXXXXXXXX)
The 2.MODULE_SYMBOL structure will be defined in the symbol table, which contains the value of the symbol and the value of the name of the symbol, not
String instead of the index to the string table.

When the module is loaded, the symbols are loaded into the kernel symbol table, as if they were the kernel output. (Translator: This paragraph understands ibid.)
We can view the contents of this two section through the following two commands

$> objdump--disassemble-j __ksymtab SUNRPC.O

$> objdump--disassemble-j. Kstrtab SUNRPC.O

========================
The meaning of config_modversions
========================

Config_modversions's idea is to make it easier for people to use, basically it means that if you want to load a
module into the kernel, to ensure system security, if the data structure, type and function of the kernel used by the module are changed,
This time the load will fail.

If your kernel compiles without defining a config_modversions macro, then it is necessary to successfully load a module
The condition is satisfied that the version number of the module at compile time is the same as the kernel version number at load time, or that the module compiles without defining modversions
(Translator: I originally thought the author meant ' and ', so think he was wrong, in fact, or meaning, thank Hzeng help to correct)
However, if your kernel is defined by a macro config_modversions, then even if your module is in the same version of the kernel
The modversions is not defined at compile time and the module is still loaded successfully. However, if your module is compiled with the modversions defined
The prerequisite for successful loading is that the interfaces in the kernel used in the module do not change a bit.


======================
So how does it work.
======================

When the kernel is compiled, if the Config_modversions macro is defined, a specific piece of information will be appended to each pass
The macro export_symbol the name of the symbol that is defined and output.

This additional information is generated by command genksyms, and its manual is described as follows:

Genksyms will talk about all the definitions in a symbol, including structure, union, enumeration, the structure of the type definition open, and become
It compiles the final content before it is compiled, and then generates an integer with the CRC algorithm, so that if any of the definitions in a symbol
Changed, the integer will be different, for example:
This additional information about the version in the kernel may be like symbol_r12345678, this 12345678 is the CRC-calculated integer
The hexadecimal representation of the.

This means that the additional information associated with a version is calculated in such a way that if the definition of the symbol changes, the change will definitely
Reflected in this additional information.

The addition of this additional information is done through macros in Linux/modversions.h, usually as follows
#define PRINTK printk_r1b7d4074

This does not affect the use of the PRINTK function in programming, but the notation used for real compilation is a function with additional information.
If you look closely at the Linux/modversions.h file, you will find many. ver contains, in fact, it is through a command similar to the following
Generated by

$> GCC-E-d__genksyms__ $ | Genksyms-k $ > $

================================
What this means for a module.
================================

If your module is compiled in a config_modversions-defined kernel, then before all C programs linux/modversions.h
This header file must be included, which is a very painful thing, so we can do it through the GCC-include option

Ifdef config_modules
Ifdef config_modversions
Modflags + +-dmodversions-include $ (hpath)/linux/modversions.h
endif

The macro modversions is used to indicate that this module is used to define the Config_modversions kernel

Translator Follow-up:
Some of the original author's views, some doubt, see Insmod Source code section and this related content,

K_crcs = is_kernel_checksummed ()//kernel is using version-related additional information
M_crcs = is_module_checksummed (f);//Whether the module uses version-related additional information
if ((M_crcs = = 0 | | k_crcs = 0) &&//At least one has, and the version number does not match into
If both sides, then compare the CRC value on it, there is no need to compare the version number.
STRNCMP (K_strversion, M_strversion, Strversionlen)!= 0) {
if (flag_force_load) {//If there is a-f flag, give only warning
lprintf ("Warning:kernel-module version mismatch\n"
"\t%s is compiled for kernel version%s\n"
"\twhile This kernel is version%s",
FileName, m_strversion, k_strversion);
else {//if not, an error.
if (!quiet)
Error ("Kernel-module version mismatch\n"
"\t%s is compiled for kernel version%s\n"
"\twhile This kernel is version%s.",
FileName, m_strversion, k_strversion);
Goto out;
}
}
if (M_crcs!= K_crcs)//Note here
Obj_set_symbol_compare (f, ncv_strcmp, Ncv_symbol_hash);
If the two are not equal, the symbol name comparison function becomes ncv_strcmp instead of the original strcmp function,
This makes PRINTK and printk_r1b7d4074 the same. The hash function also becomes ncv_symbol_hash, which causes the hash to be discarded when computed
The CRC value that follows. If this is the case, if kernel does not define a Config_modversions macro, and the module defines the Modversion
Should be given and can be successfully loaded.



PostScript: Test found:
Kernel configuration does not define the config_modversion, the driver does not have to go to the problem of version, so that does not appear:
Insmod:couldn ' t find the kernel version the module is compiled for
The problem.
Convenient.

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.