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

Linux Kernel 5.11.0模块读写文本文件方法及编译报错处理

Linux内核模块读写普通文件编译报错问题说明

需求背景

我需要在Linux内核模块中读取一个txt文件并写入另一个txt文件,查阅资料后发现有filp_read()、kernel_read()、vfs_read()等多种实现方案,但多次尝试都无法完成make编译。
已有提示可执行mv make Makefile修正文件名问题。

现有代码

reverse.c

#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/uaccess.h>

static char buf[] ="It's from linux kernel\n";
static char buf1[32];
 
int __init test_init(void)
{
    struct file *fp;
    mm_segment_t fs;
    loff_t pos;
    printk("test enter\n");
    fp =filp_open("/home/j0000/Desktop/file/kernel_file",O_RDWR | O_CREAT,0644);
    if (IS_ERR(fp)){
        printk("create file error\n");
        return -1;
    }
    fs =get_fs();
    set_fs(KERNEL_DS);
    pos =0;
    vfs_write(fp,buf, sizeof(buf), &pos);
    pos =0;
    vfs_read(fp,buf1, sizeof(buf), &pos);
    printk("Write contet=%s\n",buf1);
    filp_close(fp,NULL);
    set_fs(fs);
    return 0;
}
void __exit test_exit(void)
{
    printk("test exit\n");
}
 
module_init(test_init);
module_exit(test_exit);
 
MODULE_LICENSE("GPL");

Makefile

obj-m :=reverse.o                          
read_userspace-objs:= read_userspace_file.o     
KVERSION := $(shell uname -r)
KDIR := /usr/src/linux-headers-$(KVERSION)/
PWD := $(shell pwd)

default:
        make -C $(KDIR) M=$(PWD) modules

clean:
        rm -rf *.o *.cmd *.ko *.mod.c .tmp_versions Module.symvers modules.order

报错信息

首次报错

j0000@ubuntu:~/Desktop/file$ make
make -C /usr/src/linux-headers-5.11.0-37-generic/ M=/home/j0000/Desktop/file modules
make[1]: Entering directory '/usr/src/linux-headers-5.11.0-37-generic'
scripts/Makefile.build:44: /home/j0000/Desktop/file/Makefile: No such file or directory
make[2]: *** No rule to make target '/home/j0000/Desktop/file/Makefile'.  Stop.
make[1]: *** [Makefile:1849: /home/j0000/Desktop/file] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.11.0-37-generic'
make: *** [makefile:8: default] Error 2
j0000@ubuntu:~/Desktop/file$ 

修正文件名后报错

这类报错我已经遇到很多次了,想请问为什么当前场景下不能使用get_fs和set_fs接口?

j0000@ubuntu:~/Desktop/file$ make
make -C /usr/src/linux-headers-5.11.0-37-generic/ M=/home/j0000/Desktop/file modules
make[1]: Entering directory '/usr/src/linux-headers-5.11.0-37-generic'
  CC [M]  /home/j0000/Desktop/file/reverse.o
/home/j0000/Desktop/file/reverse.c: In function ‘test_init’:
/home/j0000/Desktop/file/reverse.c:20:9: error: implicit declaration of function ‘get_fs’; did you mean ‘sget_fc’? [-Werror=implicit-function-declaration]
   20 |     fs =get_fs();
      |         ^~~~~~
      |         sget_fc
/home/j0000/Desktop/file/reverse.c:20:9: error: incompatible types when assigning to type ‘mm_segment_t’ {aka ‘struct <anonymous>’} from type ‘int’
/home/j0000/Desktop/file/reverse.c:21:5: error: implicit declaration of function ‘set_fs’; did you mean ‘sget_fc’? [-Werror=implicit-function-declaration]
   21 |     set_fs(KERNEL_DS);
      |     ^~~~~~
      |         sget_fc
/home/j0000/Desktop/file/reverse.c:21:12: error: ‘KERNEL_DS’ undeclared (first use in this function); did you mean ‘KERNFS_NS’?
   21 |     set_fs(KERNEL_DS);
      |            ^~~~~~~~~
      |            KERNFS_NS
/home/j0000/Desktop/file/reverse.c:21:12: note: each undeclared identifier is reported only once for each function it appears in
cc1: some warnings being treated as errors
make[2]: *** [scripts/Makefile.build:288: /home/j0000/Desktop/file/reverse.o] Error 1
make[1]: *** [Makefile:1849: /home/j0000/Desktop/file] Error 2
make[1]: Leaving directory '/usr/src/linux-headers-5.11.0-37-generic'
make: *** [Makefile:8: default] Error 2

问题解答

  1. 首次报错原因:本地的编译配置文件名是小写的makefile,内核编译脚本默认查找大写的Makefile,执行mv make Makefile即可修复该问题。
  2. get_fs/set_fs相关报错原因:Linux内核从5.10版本开始正式移除了get_fs()、set_fs()接口以及KERNEL_DS宏,旧的通过修改地址空间限制调用vfs读写的方案不再适配高版本内核,你参考的教程是针对旧版本内核编写的,因此会出现未声明的错误。
  3. 修复方案:使用kernel_read和kernel_write接口替代vfs系列接口,这两个接口专门用于内核空间直接操作文件,不需要手动调整地址空间限制,天然支持内核虚拟地址作为缓冲区,适配5.10及以上版本内核。
    修改后的核心逻辑示例:
fp = filp_open("/home/j0000/Desktop/file/kernel_file", O_RDWR | O_CREAT, 0644);
if (IS_ERR(fp)) {
    printk("create file error\n");
    return PTR_ERR(fp);
}
pos = 0;
kernel_write(fp, buf, sizeof(buf), &pos);
pos = 0;
kernel_read(fp, buf1, sizeof(buf), &pos);
printk("Read content=%s\n", buf1);
filp_close(fp, NULL);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 15:15:03