在insmod之后不同意符号symbol_name的版本

时间:2015-11-16 11:20:19

标签: c linux linux-kernel

我是内核编程的新手。

为了实现我的项目工作,我从kernel.org下载了最新的稳定内核(v4.3)

仅仅是为了检查我已经将内核目录中的一些文件复制到我的项目目录中。对其进行了更改并向其中插入了更多代码。

然后我使用

编译 SLES11 Linux内核
+ (BOOL)isForceTouchCapable
{
    if (![[self class] isAtLeastElCapitan])
        return NO;

    io_iterator_t iterator;

    //get default HIDDevice dictionary
    CFMutableDictionaryRef mDict = IOServiceMatching(kIOHIDDeviceKey);

    //add manufacturer "Apple Inc." to dict
    CFDictionaryAddValue(mDict, CFSTR(kIOHIDManufacturerKey), CFSTR("Apple Inc."));

    //get matching services, depending on dict
    IOReturn ioReturnValue = IOServiceGetMatchingServices(kIOMasterPortDefault, mDict, &iterator);

    BOOL result = YES;
    if (ioReturnValue != kIOReturnSuccess)
        NSLog(@"error getting matching services for force touch devices");
    else
    {
        //recursively go through each device found and its children and grandchildren, etc.
        result = [[self class] _containsForceTouchDevice:iterator];
        IOObjectRelease(iterator);
    }

    return result;
}

+ (BOOL)_containsForceTouchDevice:(io_iterator_t)iterator
{
    io_object_t object = 0;
    BOOL success = NO;
    while ((object = IOIteratorNext(iterator)))
    {
        CFMutableDictionaryRef result = NULL;
        kern_return_t state = IORegistryEntryCreateCFProperties(object, &result, kCFAllocatorDefault, 0);
        if (state == KERN_SUCCESS && result != NULL)
        {
            if (CFDictionaryContainsKey(result, CFSTR("DefaultMultitouchProperties")))
            {
                CFDictionaryRef dict = CFDictionaryGetValue(result, CFSTR("DefaultMultitouchProperties"));
                CFTypeRef val = NULL;
                if (CFDictionaryGetValueIfPresent(dict, CFSTR("ForceSupported"), &val))
                {
                    Boolean aBool = CFBooleanGetValue(val);
                    if (aBool) //supported
                        success = YES;
                }
            }
        }

        if (result != NULL)
            CFRelease(result);

        if (success)
        {
            IOObjectRelease(object);
            break;
        } else
        {
            io_iterator_t childIterator = 0;
            kern_return_t err = IORegistryEntryGetChildIterator(object, kIOServicePlane, &childIterator);
            if (!err)
            {
                success = [[self class] _containsForceTouchDevice:childIterator];
                IOObjectRelease(childIterator);
            } else
                success = NO;

            IOObjectRelease(object);
        }
    }

    return success;
}

我使用了下面的makefile

make -C /lib/modules/$(uname -r)/build M=$PWD modules

编译成功。 但是当我尝试使用

插入内核时
obj-m := my_module.o
my_module-objs := module_main.0 other_module1.o other_module2.o other_module3.o

显示以下内容

  

不同意符号symbol_name

的版本

enter image description here

4 个答案:

答案 0 :(得分:8)

您需要针对要运行的相同版本内核构建内核模块。因此,如果您已经下载了内核4.3源代码,则需要编译版本的内核,并在尝试加载内核之前启动该内核。

您有两种解决方案:

  1. 下载当前运行的内核的内核源代码(可以在SLES上安装zypper install kernel-source或在其他发行版上安装等效命令。)
  2. 将4.3内核编译并安装到您的操作系统中。如果你需要帮助,那就问一个单独的问题(它可能属于超级用户而不是这里)。请注意,如果内核和glibc紧密耦合,并且如果您有一个非常旧的C库,则可能无法运行新内核。

答案 1 :(得分:2)

make -C / lib / modules / $(uname -r)/ build M = $ PWD modules, " $(uname -r)"表明您正在编译正在运行的内核版本,因此如果您没有更改标题,您应该可以在当前内核中修改模块。

从你的文字, "只是为了检查我已经将内核目录中的一些文件复制到我的项目目录中。对其进行了更改并向其中插入了更多代码。"

如果您对内核源代码进行了修改,那么您可能需要重新编译新内核并使用新的更新内核进行引导。然后,您应该能够使用修改后的头文件编译内核模块。

答案 2 :(得分:2)

这里的问题是你的内核模块正在使用其他内核模块的导出符号,在这种情况下,它们似乎是linux InfiniBand RDMA堆栈的导出方法或符号。

要解决符号版本问题,请从

复制 Module.symvers 文件
/usr/src/ofa-kernel

目录并将其粘贴到当前工作目录中。然后再次制作模块。现在insmod应该可以正常工作。

  

注意:Module.symvers文件包含所有内核的信息   模块导出符号。因此,通过将其复制到您的工作目录,   您正在帮助kbuild了解有关使用的导出符号的更多信息。

如果您没有找到Module.symvers或它是空的,那么使用create_Module.symvers.sh创建一个

答案 3 :(得分:1)

看起来你构建了agAinst right kernel.something来处理内核的编译方式。 (请参阅Config_conversions)。试试--force