You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在用户态C程序中获取Linux内核模块版本信息?

在用户态C程序中获取Linux内核模块的MODULE_VERSION信息

当然可以实现,下面给你三种靠谱的方案,按需选择:

方案一:读取sysfs接口(优先推荐,最简单高效)

内核模块加载后,Linux会自动在/sys/module/<你的模块名>/version路径下生成一个文本文件,里面直接存着MODULE_VERSION定义的版本号。直接读取这个文件就行,不需要额外依赖,权限要求也低(普通用户一般就能读)。

代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 替换成你的模块名
#define MODULE_NAME "my_test_driver"
#define SYSFS_VERSION_PATH "/sys/module/" MODULE_NAME "/version"

char* get_module_version_sysfs() {
    FILE* fp = fopen(SYSFS_VERSION_PATH, "r");
    if (!fp) {
        perror("Failed to open sysfs version file");
        return NULL;
    }

    // 分配足够的内存存版本号(256字节足够大部分场景)
    char* version = malloc(256);
    if (!version) {
        perror("Failed to allocate memory");
        fclose(fp);
        return NULL;
    }

    if (fgets(version, 256, fp) == NULL) {
        perror("Failed to read version string");
        free(version);
        fclose(fp);
        return NULL;
    }

    // 去掉换行符
    version[strcspn(version, "\n")] = '\0';
    fclose(fp);
    return version;
}

int main() {
    char* ver = get_module_version_sysfs();
    if (ver) {
        printf("Module version: %s\n", ver);
        free(ver);
    }
    return 0;
}

方案二:调用modinfo命令解析输出

如果你不想直接操作文件,也可以通过popen调用系统自带的modinfo命令,捕获它的输出后提取版本号。这种方式不用关心底层实现,但依赖系统有modinfo工具。

代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MODULE_NAME "my_test_driver"

char* get_module_version_modinfo() {
    char cmd[256];
    // 用-F参数直接指定输出version字段,省得自己解析全量输出
    snprintf(cmd, sizeof(cmd), "modinfo -F version " MODULE_NAME);

    FILE* fp = popen(cmd, "r");
    if (!fp) {
        perror("Failed to run modinfo command");
        return NULL;
    }

    char* version = malloc(256);
    if (!version) {
        perror("Failed to allocate memory");
        pclose(fp);
        return NULL;
    }

    if (fgets(version, 256, fp) == NULL) {
        perror("Failed to read modinfo output");
        free(version);
        pclose(fp);
        return NULL;
    }

    version[strcspn(version, "\n")] = '\0';
    pclose(fp);
    return version;
}

int main() {
    char* ver = get_module_version_modinfo();
    if (ver) {
        printf("Module version: %s\n", ver);
        free(ver);
    }
    return 0;
}

方案三:直接解析内核模块的ELF文件

MODULE_VERSION宏会把版本信息存在内核模块(.ko文件)的.modinfo节里,内容是version=xxx这样的键值对。如果模块还没加载,或者你想直接读模块文件本身,可以用这种方式,需要依赖libelf库来解析ELF格式。

代码示例(编译时要链接libelf:gcc -o get_ver get_ver.c -lelf):

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <libelf.h>
#include <gelf.h>

// 替换成你的模块文件路径
#define MODULE_FILE "/home/user/my_test_driver.ko"

char* get_module_version_elf() {
    // 初始化ELF库版本
    if (elf_version(EV_CURRENT) == EV_NONE) {
        fprintf(stderr, "ELF library version mismatch\n");
        return NULL;
    }

    int fd = open(MODULE_FILE, O_RDONLY);
    if (fd < 0) {
        perror("Failed to open module file");
        return NULL;
    }

    Elf* elf = elf_begin(fd, ELF_C_READ, NULL);
    if (!elf) {
        perror("Failed to initialize ELF handle");
        close(fd);
        return NULL;
    }

    Elf_Scn* scn = NULL;
    GElf_Shdr shdr;
    // 遍历所有节,找到.modinfo
    while ((scn = elf_nextscn(elf, scn)) != NULL) {
        gelf_getshdr(scn, &shdr);
        char* section_name = elf_strptr(elf, elf_getshdrstrndx(elf), shdr.sh_name);
        if (strcmp(section_name, ".modinfo") == 0) {
            Elf_Data* data = elf_getdata(scn, NULL);
            if (!data) {
                perror("Failed to read .modinfo section data");
                elf_end(elf);
                close(fd);
                return NULL;
            }

            // 查找version=字段
            char* modinfo_buf = (char*)data->d_buf;
            char* version_start = strstr(modinfo_buf, "version=");
            if (!version_start) {
                fprintf(stderr, "Version info not found in .modinfo section\n");
                elf_end(elf);
                close(fd);
                return NULL;
            }

            // 跳过"version="前缀,复制版本号
            version_start += strlen("version=");
            char* version = strdup(version_start);
            if (!version) {
                perror("Failed to duplicate version string");
                elf_end(elf);
                close(fd);
                return NULL;
            }

            elf_end(elf);
            close(fd);
            return version;
        }
    }

    fprintf(stderr, ".modinfo section not found in module file\n");
    elf_end(elf);
    close(fd);
    return NULL;
}

int main() {
    char* ver = get_module_version_elf();
    if (ver) {
        printf("Module version: %s\n", ver);
        free(ver);
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者rickastley

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 13:25:03