Linux内核中读写文件数据的方法
有时候需要在Linuxkernel--大多是在需要调试的驱动程序--中读写文件数据。在kernel中操作文件没有标准库可用,需要利用kernel的一些函数,这些函数主要有: filp_open() filp_close(), vfs_read()vfs_write(),set_fs(),get_fs()等,这些函数在linux/fs.h和asm/uaccess.h头文件中声明。下面介绍主要步骤:
1. 打开文件
filp_open()在kernel中可以打开文件,其原形如下:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <linux/string.h>
#include <linux/mm.h>
#include <linux/syscalls.h>
#include <asm/unistd.h>
#include <asm/uaccess.h>
#define MY_FILE "/root/LogFile"
char buf[128];
struct file *file = NULL;
static int __init init(void)
{
mm_segment_t old_fs;
printk("Hello, I'm the module that intends to write messages to file.\n");
if(file == NULL)
file = filp_open(MY_FILE, O_RDWR | O_APPEND | O_CREAT, 0644);
if (IS_ERR(file)) {
printk("error occured while opening file %s, exiting...\n", MY_FILE);
return 0;
}
sprintf(buf,"%s", "The Messages.");
old_fs = get_fs();
set_fs(KERNEL_DS);
file->f_op->write(file, (char *)buf, sizeof(buf), &file->f_pos);
set_fs(old_fs);
filp_close(file, NULL);
file = NULL;
return 0;
}
static void __exit fini(void)
{
if(file != NULL)
filp_close(file, NULL);
}
module_init(init);
module_exit(fini);
MODULE_LICENSE("GPL");
在linux内核编程时,进行系统调用(如文件操作)时如果要访问用户空间的参数,可以用set_fs,get_ds等函数实现访问。get_ds获得kernel的内存访问地址范围(IA32是4GB),set_fs是设置当前的地址访问限制值,get_fs是取得当前的地址访问限制值。进程由用户态进入核态,linux进程的task_struct结构中的成员addr_limit也应该由0xBFFFFFFF变为0xFFFFFFFF(addr_limit规定了进程有用户态核内核态情况下的虚拟地址空间访问范围,在用户态,addr_limit成员值是0xBFFFFFFF也就是有3GB的虚拟内存空间,在核心态,是0xFFFFFFFF,范围扩展了1GB)。使用这三个函数是为了安全性。为了保证用户态的地址所指向空间有效,函数会做一些检查工作。
如果set_fs(KERNEL_DS),函数将跳过这些检查。
下面是典型用法:
//#define __NO_VERSION__
//#define __KERNEL__
//#define MODULE
#define __KERNEL_SYSCALLS__
#include <linux/unistd.h>;
#include <linux/init.h>;
#include <linux/module.h>;
#include <linux/kernel.h>;
#include <linux/file.h>;
#include <linux/fs.h>;
#include <linux/sched.h>;
#include <asm/uaccess.h>;
#include <asm/processor.h>;
int init_module(void)
{
struct file *fp = NULL;
char buf[100];
int i;
for(i=0;i<100;i++)
buf[i] = 0;
printk(KERN_ALERT "Hello ,ftyjl.\n");
fp = filp_open("/tmp/8899", 3, 0); //内核的open函数,返回struct file *
if (fp == NULL)
printk(KERN_ALERT "filp_open error ,ftyjl.\n");
mm_segment_t old_fs=get_fs(); //下面两步,设置当前执行环境为kernel_ds,否则会出错
set_fs(get_ds());
fp->f_op->read(fp, buf, 2, &fp->f_pos); //调用真正的read
set_fs(old_fs); //恢复环境
printk(KERN_ALERT "ftyjl:read[%s]\n", buf);
printk(KERN_ALERT "end of Hello ,ftyjl.\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_ALERT "Good bye, ftyjl\n");
}
MODULE_LICENSE("Proprietary");
转自:http://blog.csdn.net/tommy_wxie/article/details/8193954
http://blog.csdn.net/zjc0888/article/details/7266730
Linux内核中读写文件数据的方法相关推荐
- 【转】 Linux内核中读写文件数据的方法--不错
原文网址:http://blog.csdn.net/tommy_wxie/article/details/8193954 Linux内核中读写文件数据的方法 有时候需要在Linuxkernel ...
- 如何在linux内核中读写文件
在VFS的支持下,用户态进程读写任何类型的文件系统都可以使用read和write着两个系统调用,但是在linux内核中没有这样的系统调用我们如何操作文件呢?我们知道read和write在进入内核态之后 ...
- linux内核中读写文件
之前以为在内核中不能创建文件,其实不是这样子的,只要文件系统跑起来之后就可以像在用户空间一样操作文件. 用户空间 内核 open() ...
- 在linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS)
在linux内核中操作文件的方法--使用get_fs()和set_fs(KERNEL_DS) #include <linux/kernel.h> #include <linux/mo ...
- Linux中文件描述符1,linux内核中的文件描述符(一)--基础知识简介
原标题:linux内核中的文件描述符(一)--基础知识简介 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blo ...
- linux内核中的文件描述符(一)--基础知识简介
linux内核中的文件描述符(一)--基础知识简介 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.cs ...
- linux内核中打开文件 及属性控制
共两篇文章:还可以参考linux那些事linx_sysfs ====================================================================== ...
- linux内核中的文件描述符(四)--fd的分配--get_unused_fd
linux内核中的文件描述符(四)--fd的分配--get_unused_fd Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123( ...
- linux内核中的文件描述符(三)--fd的回收
linux内核中的文件描述符(三)--fd的回收 Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csd ...
最新文章
- 客快物流大数据项目(四十六):Spark操作Kudu dataFrame操作kudu
- (转载)Google Analytics(Google分析)使用技巧
- linux c语言 ppt,linux操作系统下c语言编程入门.ppt
- 图片优化_Web 性能优化: 图片优化让网站大小减少 62%
- ERROR: SampleCB() - buffer sizes do not match 解决方法
- 一个技术人的知识管理方法论
- EasyNVR H5无插件摄像机直播解决方案前端解析之:videojs初始化的一些样式处理...
- 虚拟网站禁用php,虚拟主机php程序fsockopen函数被禁用
- Thinkpad L430无法识别Trackpoint解决方案
- 51单片机指令系统详解
- Debian 6(Squeeze)升级至Debian 7(Wheezy)
- 团队协作工具调研笔记
- 测绘资质专业类别及乙级作业限制范围是什么?
- java定时开始和关闭_springboot自带定时器实现定时任务的开启关闭以及定时时间可以配置详解...
- onMeasure学习笔记
- MTKCam3流程学习 - openCamera
- 网页图片快速显示的六种办法
- 常微分方程求解在MATLAB,MatLab常微分方程及常微分方程组的求解
- 实验三构造与析构函数
- CIO40: IT人之三观”不正、三十“南”立
热门文章
- 关于动画培养灵感的网站
- VC++实现获取DNS服务器
- 海思芯片硬件java加速_海思Hi3719C V100芯片简介
- python0x80070005拒绝访问_PowerShell启用winrm失败:拒绝访问 0x80070005 -2147024891
- 实验6 控制结构综合程序设计 7-3 简单计算器
- centos 删除crontab_CentOS安装crontab及使用方法
- python字符编码使用_python – Numpy字符串编码
- 算法与数据结构_数据结构与算法专题--算法基本概念
- Java黑皮书课后题第4章:*4.17(一个月的天数)编写一个程序,提示用户输入一个年份和一个月份名称的前3个字母(第一个字母使用大写形式),显示该月中的天数。如果月份非法则显示出错信息
- Java黑皮书课后题第3章:3.10(游戏:加法测试)程序清单3-3随机产生一个减法问题。修改这个程序,随机产生一个计算两个小于100的整数的加法问题