http://blog.sina.com.cn/s/blog_b37976350101ubpx.html
1.编译kernel的时候,会生成Module.symvers文件,记录每个Symbol 和相应的CRC code,例如: 比如这个kernel 版本是2.6.32
0x6c2a547d usb_submit_urb vmlinux EXPORT_SYMBOL_GPL
0x31f97103 usb_alloc_urb vmlinux EXPORT_SYMBOL_GPL
2.编译动态module的时候,也会生成类似的文件module_name.mod.c,将module调用到的system call 记录在里面,这个的symbol使用编译module的时候指向的kernel路径。
3.加载动态module的时候,kernel会去check加载模块的每一个symbol的CRC,看看是否与kernel相应的symbol相同,不同的话就会报错。 同一个kernel版本,不同的config也会出这个问题。
“***module”: disagrees about version of symbol device_add
“***module”: Unknown symbol device_add
vim Module.symvers
0x17506ac5 kmem_cache_alloc vmlinux EXPORT_SYMBOL
0x55417264 unregister_vt_notifier vmlinux EXPORT_SYMBOL_GPL
0x938896a2 replace_page_cache_page vmlinux EXPORT_SYMBOL_GPL
0x70523a7a __cond_resched_softirq vmlinux EXPORT_SYMBOL
0x7e074472 set_anon_super vmlinux EXPORT_SYMBOL
0x4369e54a request_firmware vmlinux EXPORT_SYMBOL
0x3d622071 of_get_property vmlinux EXPORT_SYMBOL
0x0ba486f9 drm_atomic_set_crtc_for_connector vmlinux EXPORT_SYMBOL
0xc05acdee rtc_class_open vmlinux EXPORT_SYMBOL_GPL
0xeb98ad1a snd_soc_platform_read vmlinux EXPORT_SYMBOL_GPL
0x487a4460 cpumask_set_cpu_local_first vmlinux EXPORT_SYMBOL
0x0a2487e0 unblock_all_signals vmlinux EXPORT_SYMBOL
0x3020bd56 i2c_put_adapter vmlinux EXPORT_SYMBOL
0x56feee6e irq_to_desc vmlinux EXPORT_SYMBOL
0x09b9a426 hwmon_device_unregister vmlinux EXPORT_SYMBOL_GPL
0x80ca5026 _bin2bcd vmlinux EXPORT_SYMBOL
0x3c54e121 dev_uc_sync vmlinux EXPORT_SYMBOL
0xfbaaf01e console_lock vmlinux EXPORT_SYMBOL
0xe113bbbc csum_partial vmlinux EXPORT_SYMBOL
0xfd3d4077 dev_mc_sync vmlinux EXPORT_SYMBOL
0xc068440e __kfifo_alloc vmlinux EXPORT_SYMBOL
0xaaa68389 kmap_atomic vmlinux EXPORT_SYMBOL
0x7f603654 tcp_v4_mtu_reduced vmlinux EXPORT_SYMBOL
vim drivers/usb/serial/usbserial.mod.c
#include
#include
#include
MODULE_INFO(vermagic, VERMAGIC_STRING);
__visible struct module __this_module
__attribute__((section(".gnu.linkonce.this_module"))) = {
.name = KBUILD_MODNAME,
.init = init_module,
#ifdef CONFIG_MODULE_UNLOAD
.exit = cleanup_module,
#endif
.arch = MODULE_ARCH_INIT,
};
MODULE_INFO(intree, "Y");
static const struct modversion_info ____versions[]
__used
__attribute__((section("__versions"))) = {
{ 0x65137d02, __VMLINUX_SYMBOL_STR(module_layout) },
{ 0xe52a86c0, __VMLINUX_SYMBOL_STR(tty_port_tty_get) },
{ 0x6d662533, __VMLINUX_SYMBOL_STR(_find_first_bit_le) },
{ 0x2d3385d3, __VMLINUX_SYMBOL_STR(system_wq) },
{ 0x77dbe8c4, __VMLINUX_SYMBOL_STR(bus_register) },
{ 0xee57ea5d, __VMLINUX_SYMBOL_STR(kmalloc_caches) },
{ 0x12da5bb2, __VMLINUX_SYMBOL_STR(__kmalloc) },
{ 0xda21f824, __VMLINUX_SYMBOL_STR(driver_register) },
{ 0x13d0adf7, __VMLINUX_SYMBOL_STR(__kfifo_out) },
{ 0x5fc56a46, __VMLINUX_SYMBOL_STR(_raw_spin_unlock) },
{ 0x70f42fd4, __VMLINUX_SYMBOL_STR(single_open) },
{ 0x2e5810c6, __VMLINUX_SYMBOL_STR(__aeabi_unwind_cpp_pr1) },
{ 0xc068440e, __VMLINUX_SYMBOL_STR(__kfifo_alloc) },
{ 0x51360db1, __VMLINUX_SYMBOL_STR(single_release) },
{ 0x6f86333c, __VMLINUX_SYMBOL_STR(seq_puts) },
{ 0xd763c17b, __VMLINUX_SYMBOL_STR(tty_port_open) },
{ 0x2a3aa678, __VMLINUX_SYMBOL_STR(_test_and_clear_bit) },
{ 0x5c43cb42, __VMLINUX_SYMBOL_STR(seq_printf) },
{ 0x4aaa9b1f, __VMLINUX_SYMBOL_STR(tty_port_hangup) },
{ 0x4205ad24, __VMLINUX_SYMBOL_STR(cancel_work_sync) },
...
{ 0x216407ab, __VMLINUX_SYMBOL_STR(usb_alloc_urb) },
{ 0x3eeaf4e2, __VMLINUX_SYMBOL_STR(usb_put_intf) },
};
static const char __module_depends[]
__used
__attribute__((section(".modinfo"))) =
"depends=";
#define MODULE_INFO(tag, info) __MODULE_INFO(tag, tag, info)
#define __MODULE_INFO(tag, name, info) \
static const char __UNIQUE_ID(name)[] \
__used __attribute__((section(".modinfo"), unused, aligned(1))) \
= __stringify(tag) "=" info
struct modversion_info {
unsigned long crc;
char name[MODULE_NAME_LEN];
};