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");
arrow
arrow
    全站熱搜
    創作者介紹
    創作者 立你斯 的頭像
    立你斯

    立你斯學習記錄

    立你斯 發表在 痞客邦 留言(0) 人氣()