close
http://daydreamer.idv.tw/rewrite.php/read-65.html
在embedded的設備上,driver需要讀取某些設定檔並根據設定值設定硬體,除了ioctl, file read/write之外,最簡單的方式莫過於直接在kernel space進行設定檔的讀寫,不過通常”寫入”這個功能很少用到,所以我略過這個東西不提
在kernel讀取檔案的方式非常簡單,小弟粗分為三個步驟,這三個步驟後方所列的就是kernel的API
1.Open file: filp_open
2.Read file: f_op->read
3.Close file: filp_close
程式的範例請直接參考下面所列,程式裡面比較值得一提的是get_fs和set_fs,kernel會根據set_fs的設定值決定要不要檢查讀/寫memory的界限,如果set_fs傳入的參數是kernel_ds,那kernel會bypass memory 界限的檢查,經過這樣的設定,才能正確取得檔案資料
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/unistd.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/mm.h>
#include <asm/uaccess.h>
mm_segment_t oldfs;
struct file *openFile(char *path,int flag,int mode)
{
struct file *fp;
fp=filp_open(path, flag, 0);
if (fp) return fp;
else return NULL;
}
int readFile(struct file *fp,char *buf,int readlen)
{
if (fp->f_op && fp->f_op->read)
return fp->f_op->read(fp,buf,readlen, &fp->f_pos);
else
return -1;
}
int closeFile(struct file *fp)
{
filp_close(fp,NULL);
return 0;
}
void initKernelEnv(void)
{
oldfs = get_fs();
set_fs(KERNEL_DS);
}
static int __init readfile_init(void)
{
char buf[1024];
struct file *fp;
int ret;
initKernelEnv();
fp=openFile("/etc/myconfig",O_RDONLY,0);
if (fp!=NULL)
{
memset(buf,0,1024);
if ((ret=readFile(fp,buf,1024))>0)
printk("buf:%s\n",buf);
else printk("read file error %d\n",ret);
closeFile(fp);
}
set_fs(oldfs);
return 0;
}
static void __exit readfile_exit(void)
{
printk("read file module remove successfully\n");
}
module_init(readfile_init);
module_exit(readfile_exit);
MODULE_DESCRIPTION("read a file in kernel module");
MODULE_AUTHOR("Joey Cheng<jemicheng@gmail.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("read file module");
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/unistd.h>
#include <linux/sched.h>
#include <linux/fs.h>
#include <linux/file.h>
#include <linux/mm.h>
#include <asm/uaccess.h>
mm_segment_t oldfs;
struct file *openFile(char *path,int flag,int mode)
{
struct file *fp;
fp=filp_open(path, flag, 0);
if (fp) return fp;
else return NULL;
}
int readFile(struct file *fp,char *buf,int readlen)
{
if (fp->f_op && fp->f_op->read)
return fp->f_op->read(fp,buf,readlen, &fp->f_pos);
else
return -1;
}
int closeFile(struct file *fp)
{
filp_close(fp,NULL);
return 0;
}
void initKernelEnv(void)
{
oldfs = get_fs();
set_fs(KERNEL_DS);
}
static int __init readfile_init(void)
{
char buf[1024];
struct file *fp;
int ret;
initKernelEnv();
fp=openFile("/etc/myconfig",O_RDONLY,0);
if (fp!=NULL)
{
memset(buf,0,1024);
if ((ret=readFile(fp,buf,1024))>0)
printk("buf:%s\n",buf);
else printk("read file error %d\n",ret);
closeFile(fp);
}
set_fs(oldfs);
return 0;
}
static void __exit readfile_exit(void)
{
printk("read file module remove successfully\n");
}
module_init(readfile_init);
module_exit(readfile_exit);
MODULE_DESCRIPTION("read a file in kernel module");
MODULE_AUTHOR("Joey Cheng<jemicheng@gmail.com>");
MODULE_LICENSE("GPL");
MODULE_ALIAS("read file module");
全站熱搜
留言列表