Unlike our usual writing program, if it is just a global variable, it can be successfully connected while compiling the kernel, but there is no way to use the variable after the connection.
And the module loading is run-time, it refers to a variable, the kernel needs to parse it, otherwise the module can not work, Export_symbol defined as follows
Fine __export_symbol (sym, SEC)
extern typeof (Sym) sym; /
__crc_symbol (sym, sec)/
static const char __kstrtab_# #sym []/
__attribute__ ((Section ("__ksymtab_strings"))/
= Module_symbol_prefix #sym; /
static const struct Kernel_symbol __ksymtab_# #sym/
__ATTRIBUTE_USED__/
__attribute__ (Section ("__ksymtab" sec), unused)
= {(unsigned long) &sym, __kstrtab_# #sym}
It is placed in a fixed section, so that when the kernel is parsed, the symbol is found in this section, and the repositioned and common (. O) principle is similar to the//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////////
System.map is the address of the function at the time of the link. After the connection is complete, it is not known which symbol is at that address during the kernel run. And this file is for debugging. The contents of which kernel did not know.
The symbol of Export_symbol is to save these symbols and corresponding addresses, and in the process of running the kernel, you can find the corresponding addresses of these symbols.
module in the loading process, its essence is dynamically connected to the kernel, if the module in the reference to the kernel or other modules of the symbols, it is necessary to export_symbol these symbols, so as to find the corresponding address connection ah. Or you can't connect.
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Linux symbol Export Methord [2007-03-06]
[1] If we want export the symbol in a module, just use the Export_symbol (xxxx) in the C or H file.
and compile the module by adding the compile flag-dexport_symtab.
Then We can use the XXXX into the other module.
[2] If we want export some symbol in Kernel this is isn't in a module such as XXXX in THE/ARCH/PPC/FEC.C.
Firstly, define the XXXX in the FEC.C;
Secondly, make a new file which contain the "extern" define the XXXX (for example, extern int xxxx);
Lastly, in the PPC_KSYMS.C we includes the new file, and add the Export_symbol (xxxx).
Then We can use the XXXX
Insmod Mod1.ko must be loaded first because the function body is inside him, then loading insmod Mod2.ko is normal
-dexport_symtab in compilation options, and with an external description to warn less
The following simple code:
/*mod1.c*/
#include <linux/init.h>
#include <linux/module.h>
Module_license ("Dual BSD/GPL");
static int He1 (void)
{
PRINTK (kern_info "He1"). \ n ");
return 0;
}
Export_symbol (HE1);
static int __init hello_init (void)
{
PRINTK (Kern_alert "Hello, world\n");
return 0;
}
static void __exit hello_exit (void)
{
PRINTK (Kern_alert "Goodbye, cruel world\n");
}
Module_init (Hello_init);
Module_exit (Hello_exit);
==================================
/*mod2.c*/
#include <linux/init.h>
#include <linux/module.h>
Module_license ("Dual BSD/GPL");
static int He2 (void)
{
extern int He1 (void);
He1 ();
PRINTK (kern_info "He2"). \ n ");
return 0;
}
static int __init hello_init (void)
{
He2 ();
PRINTK (Kern_alert "Hello, world\n");
return 0;
}
static void __exit hello_exit (void)
{
PRINTK (Kern_alert "Goodbye, cruel world\n");
}
Module_init (Hello_init);
Module_exit (Hello_exit);
### Makefile---
# # Author:hefuhua@163.com
# # Version: $Id: makefile,v 0.0 2007/01/26 02:02:51 Leno EXP $
# # Keywords:
# # X-url:
Ifneq ($ (kernelrelease),)
Obj-m: =-dexport_symtab #加载该参数的地方
Obj-m: = MOD2.O
Else
Kerneldir? =/lib/modules/$ (Shell uname-r)/build
PWD: = $ (Shell PWD)
Default
$ (make)-C $ (Kerneldir) m=$ (PWD) modules
endif
/////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////
Export_symbol Use small kee
1. Basic Concepts
The use of Export_symbol is to export a function as a symbolic way to other modules.
2. Precautions to use:
#include <linux/module.h> files are required in the. c file using Export_symbol.
Write function First
Func_a ()
{
}
Use Export_symbol again
Export_symbol (FUNC_A);
System.map and Export_symbol (to be perfected) 2007-03-03 16:07system.map[1] is a Linux kernel symbol file that maintains the corresponding relationship between the kernel function name and the name of the non stack variable and the respective address.
If a kernel function or variable is to be called by a kernel module, it must be handled using the Export_symbol macro, one of which is to connect the symbol to each __ksymtab_xx_xx section of the binary file (see include/linux/ Module.h, use the __ATTRIBUTE__ keyword of the GCC compiler to implement [2]). When the kernel loads the module, it first confirms that each kernel function called by the module has been export (see __find_symbol () kernel/module.c).
For example, FC5 lack of capital to vanilla the core of the patch, so that it no longer export sys_open symbol, this can search the kernel corresponding System.map file for confirmation, to see if there are __ksymtab_sys_open symbols.
[1] The System.map File
http://www.dirac.org/linux/system.map/
[2] Using GNU C __attribute__
Http://www.unixwiz.net/techtips/gnu-c-attributes.html
The System.map File
System.map
There seems to be a dearth of information about the System.map file. It ' s really nothing mysterious, and in the scheme of things, it's really not that important. But A lack of documentation makes it shady. It ' s like an earlobe; We all have one, but nobody really knows why. This is a little Web page I cooked up that explains the why.
Note, I ' m not out to be 100% correct. For instance, it's possible for a system to don't have/proc filesystem support, but most do. I ' m going to assume for you "go with the" and have a fairly typical system.
Some of the stuff on oopses comes from Alessandro Rubini ' s "Linux Device Drivers" which are where I learned most of what I Know about kernel programming.
What Are symbols?
In the "context of" programming, a symbol is the building block of a program:it's is a variable name or a function name. It should be of the surprise this kernel has symbols, just like the programs you write. The difference is, of course, this kernel is a very complicated piece of coding and has many, many global symbols.
What is the Kernel Symbol Table?
The kernel doesn ' t use symbol names. It ' s much happier knowing a variable or function name by the variable or function ' s address. Rather than using size_t bytesread (), the kernel prefers to refer to this variable as (for example) C0343f20.
Humans, on the other hand, does not appreciate addresses like C0343f20. We prefer to use something like size_t bytesread (). Normally, this doesn ' t present much of a problem. The kernel is mainly written in C, so the compiler/linker allows us to use symbol names when we code and allows the kernel To use addresses when it runs. The Everyone is happy.
There are situations, however, where we need to know the "address of" a symbol (or the symbol for a). This are done by a symbol table, and are very similar to how GDB can give your function name from ' address ' (or an addre SS from a function name). A symbol table is a listing the all symbols along with their address. This is example of a symbol table:
c03441a0 B Dmi_broken
C03441A4 B Is_sony_vaio_laptop
C03441C0 b dmi_ident
c0344200 b pci_bios_present
c0344204 b pirq_table
c0344208 b Pirq_router
c034420c b Pirq_router_dev
c0344220 b Ascii_buffer
c0344224 b ascii_buf_bytes
You can have a variable named Dmi_broken the kernel address c03441a0.
What is the System.map File?
There are 2 files that are used as a symbol table:
/proc/ksyms
System.map
There. You are know what the System.map file is.
Every time for your compile a new kernel, the addresses of various symbol names are to change.
/proc/ksyms is a ' proc file ' and is ' created on the Fly ' when a kernel-up. Actually, it ' s not really a file; It ' s simply a representation of kernel data which is given the illusion of being a disk file. If you don ' t believe me, try finding the FileSize of/proc/ksyms. Therefore, it would always be correct for the kernel this is currently running.
However, System.map is a actual file on your filesystem. When you are compile a new kernel, your old system.map has wrong symbol information. A new System.map is generated with each kernel compile and your need to replace the old copy with your new copy.
What is an Oops?
What is the most common bug in your homebrewed programs? The Segfault. Good ol ' signal 11.
What is the most common bugs in the Linux kernel? The Segfault. Except here, the notion of a segfault are much more complicated and can are, as can imagine, much more serious. When the kernel dereferences a invalid pointer, it's not called a segfault--it's called an "oops". An oops indicates a kernel bug and should always is reported and fixed.
Note This is oops the same thing as a segfault. Your program cannot recover from a segfault. The kernel doesn ' t necessarily have to being in a unstable state when a oops. The Linux kernel is very robust; The oops may just to kill the current process and leave the rest of the "kernel in a" good, solid state.
An oops are not a kernel panic. In a panic, the kernel cannot continue; The system grinds to a halt and must is restarted. An oops could cause a panic if a vital part of the system is destroyed. An oops in a device driver, for example, would almost never a cause.
When an oops occurs, the system'll print out information This is relevent to debugging the problem, like the contents of All the CPU registers, and the location of page descriptor tables. In particular, the contents of the EIP (instruction pointer) is printed. Like this:
Eip:0010:[<00000000>]
Call Trace: [<c010b860>]
What does a Oops Have to does with System.map?
You can agree this information given in EIP and call Trace are not very informative. But More importantly, it's really not informative to a kernel developer. Since a symbol doesn ' t have a fixed address, c010b860 can point anywhere.
To help us understand cryptic oops output, Linux uses a daemon called, the KLOGD kernel. KLOGD intercepts kernel oopses and logs them with syslogd, changing some to the useless information like c010b860 with INF Ormation that humans can use. In the other words, klogd are a kernel message logger which can perform name-address. Once KLOGD tranforms The kernel message, it uses whatever logger are in place to log system wide messages, usually syslogd.
To perform name-address resolution, KLOGD uses System.map. Now you know what a oops has to does with System.map.
There ' s other software besides the kernel logger daemon of that uses. I ' ll get to that shortly.
Fine Print:
There are actually two types of address resolutions performed by KLOGD.
Static translation, which uses the System.map file.
Dynamic translation, which is used with loadable modules. These translations don ' t use System.map and are therefore not relevant to this discussion, but I ' ll describe it briefly any How:
KLOGD Dynamic Translation
Suppose you load a kernel module which generates a oops. An oops generated, and klogd intercepts it. It is found this oops occured at d00cf810. Since this address belongs to a dynamically loaded module, it has no entry in the System.map file. Klogd'll search for it, find nothing, and conclude that a loadable module must have generated the Oops. KLOGD then queries the kernel for symbols this were exported by loadable. Even if the module author didn ' t export his symbols, at the very least, klogd'll know what module generated the Oops, WH The ICH is better than knowing nothing about the oops at all.
Where Should system.map be located?
System.map should is located wherever the software that uses it looks for it. That's being said, let me talk the about where KLOGD looks for it. Upon bootup, if klogd isn ' t given the location of System.map as an argument, it'll look for System.map in three places, In the following order:
/boot/system.map
/system.map
/usr/src/linux/system.map
System.map also has versioning information, and KLOGD intelligently for the searches map file. For instance, suppose ' re running kernel 2.4.18 and the associated map file Is/boot/system.map. You are compile a new kernel 2.5.1 in the tree/usr/src/linux. During the compiling process, the File/usr/src/linux/system.map is created. When you boot your new kernel, klogd'll, At/boot/system.map, determine it ' s not the correct map file for the Booting kernel, then look at/usr/src/linux/system.map, determine "It is" the correct map file for the booting kernel a nd start reading the symbols.
A few Nota bene ' s:
Somewhere during the 2.5.x series, the Linux kernel started to untar into linux-version, rather than just Linux (show of H ANDs--How many people have been waiting for this to happen? I don ' t know if KLOGD has been modified to search In/usr/src/linux-version/system.map yet. Todo:look at the KLOGD source. If someone beats me to it, please email me and let me know if KLOGD has been to look in the new directory name fo R the Linux source code.
The man page doesn ' t tell the whole the story. Look in this:
# strace-f/sbin/klogd | grep ' System.map '
31208 Open ("/boot/system.map-2.4.18", o_rdonly| O_largefile) = 2
Apparently, not a does klogd look for the correct version of the map in the 3 KLOGD search directories, but KLOGD also Knows to look for the name ' System.map ' followed by '-kernelversion ', like system.map-2.4.18. This is undocumented feature of KLOGD.
A few drivers need system.map to resolve symbols since they ' re linked against kernel headers instead of glibc). They won ' t work correctly without the System.map for the particular kernel. This isn't the same thing as a module not loading because of a kernel version mismatch. That is has to does with the kernel version and not the kernel symbol table which changes between kernels of the same
What Else uses the System.map
System.map isn ' t just useful for debugging kernel oopses. Other programs like lsof:
satan# strace lsof 2>&1 1>/dev/null | grep System
Readlink ("/proc/22711/fd/4", "/boot/system.map-2.4.18", 4095) = 23
and PS:
satan# strace PS 2>&1 1>/dev/null | grep System
Open ("/boot/system.map-2.4.18", o_rdonly| o_nonblock| O_noctty) = 6
And DOSEMU require a correct system.map.
What happens If I Don ' t Have A healthy System.map?
Suppose your have multiple kernels on the same machine. Need a separate System.map file for each kernel! If you run a kernel with no (or a incorrect) System.map, you'll periodically a message like:
System.map does not match actual kernel
Not a fatal error, but can is annoying to the everytime you use PS. Some software, like Dosemu, could not work correctly. Lastly, your KLOGD or ksymoops output won't is reliable in the case of a kernel oops.