Linux内核模块中的读写文件

Linux内核模块中的读写文件

我知道所有关于为什么不应该从内核读取/写入文件的讨论,而应该如何使用/procNetLink去做这件事。我无论如何都想读/写。我也读过把我逼疯-你不该在内核里做的事.

但是,问题是2.6.30不出口sys_read()..更确切地说,它被包裹在SYSCALL_DEFINE3..因此,如果我在我的模块中使用它,我会收到以下警告:

WARNING: "sys_read" [xxx.ko] undefined!WARNING: "sys_open" [xxx.ko] undefined!

显然insmod无法加载模块,因为链接不正确。

问题:

  • 如何在2.6.22之后在内核中读写(其中

    sys_read()/sys_open()

    不出口)?
  • 通常,如何使用封装在宏中的系统调用

    SYSCALL_DEFINEn()

    从内核里?


白衣染霜花
浏览 1646回答 3
3回答

慕森王

您应该意识到,在可能的情况下,您应该避免文件I/O。其主要思想是“更深一层”,并呼吁VFS级函数而不是直接使用SysCall处理程序:包括:#include&nbsp;<linux/fs.h>#include&nbsp;<asm/segment.h>#include&nbsp;<asm/uaccess.h>#include&nbsp;<linux/buffer_head.h>打开文件(类似于打开):struct&nbsp;file&nbsp;*file_open(const&nbsp;char&nbsp;*path,&nbsp;int&nbsp;flags,&nbsp;int&nbsp;rights)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;struct&nbsp;file&nbsp;*filp&nbsp;=&nbsp;NULL; &nbsp;&nbsp;&nbsp;&nbsp;mm_segment_t&nbsp;oldfs; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;err&nbsp;=&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;oldfs&nbsp;=&nbsp;get_fs(); &nbsp;&nbsp;&nbsp;&nbsp;set_fs(get_ds()); &nbsp;&nbsp;&nbsp;&nbsp;filp&nbsp;=&nbsp;filp_open(path,&nbsp;flags,&nbsp;rights); &nbsp;&nbsp;&nbsp;&nbsp;set_fs(oldfs); &nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(IS_ERR(filp))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;err&nbsp;=&nbsp;PTR_ERR(filp); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;NULL; &nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;filp;}关闭文件(类似于CLOSE):void&nbsp;file_close(struct&nbsp;file&nbsp;*file)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;filp_close(file,&nbsp;NULL);}从文件中读取数据(类似于扩展):int&nbsp;file_read(struct&nbsp;file&nbsp;*file,&nbsp;unsigned&nbsp;long&nbsp;long&nbsp;offset,&nbsp;unsigned&nbsp;char&nbsp;*data,&nbsp;unsigned&nbsp;int&nbsp;size)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;mm_segment_t&nbsp;oldfs; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;ret; &nbsp;&nbsp;&nbsp;&nbsp;oldfs&nbsp;=&nbsp;get_fs(); &nbsp;&nbsp;&nbsp;&nbsp;set_fs(get_ds()); &nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;=&nbsp;vfs_read(file,&nbsp;data,&nbsp;size,&nbsp;&offset); &nbsp;&nbsp;&nbsp;&nbsp;set_fs(oldfs); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ret;}将数据写入文件(类似于pwrite):int&nbsp;file_write(struct&nbsp;file&nbsp;*file,&nbsp;unsigned&nbsp;long&nbsp;long&nbsp;offset,&nbsp;unsigned&nbsp;char&nbsp;*data,&nbsp;unsigned&nbsp;int&nbsp;size)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;mm_segment_t&nbsp;oldfs; &nbsp;&nbsp;&nbsp;&nbsp;int&nbsp;ret; &nbsp;&nbsp;&nbsp;&nbsp;oldfs&nbsp;=&nbsp;get_fs(); &nbsp;&nbsp;&nbsp;&nbsp;set_fs(get_ds()); &nbsp;&nbsp;&nbsp;&nbsp;ret&nbsp;=&nbsp;vfs_write(file,&nbsp;data,&nbsp;size,&nbsp;&offset); &nbsp;&nbsp;&nbsp;&nbsp;set_fs(oldfs); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;ret;}同步更改文件(类似于fsync):int&nbsp;file_sync(struct&nbsp;file&nbsp;*file)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;vfs_fsync(file,&nbsp;0); &nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;0;}[编辑]最初,我建议使用file_fsync,它在较新的内核版本中消失了。感谢那个可怜的人提出的改变,但他的改变被拒绝了。编辑在我审阅之前就被拒绝了。

侃侃无极

从Linux内核的4.14版本开始,vfs_read和vfs_write功能是不再出口在模块中使用。相反,只为内核的文件访问提供了功能:#&nbsp;Read&nbsp;the&nbsp;file&nbsp;from&nbsp;the&nbsp;kernel&nbsp;space.ssize_t&nbsp;kernel_read(struct&nbsp;file&nbsp;*file,&nbsp;void&nbsp;*buf,&nbsp;size_t&nbsp;count,&nbsp;loff_t&nbsp;*pos); #&nbsp;Write&nbsp;the&nbsp;file&nbsp;from&nbsp;the&nbsp;kernel&nbsp;space.ssize_t&nbsp;kernel_write(struct&nbsp;file&nbsp;*file,&nbsp;const&nbsp;void&nbsp;*buf,&nbsp;size_t&nbsp;count, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;loff_t&nbsp;*pos);还有,filp_open不再接受用户空间字符串,因此可以用于内核访问。直接(不跳舞)set_fs).
打开App,查看更多内容
随时随地看视频慕课网APP