Reference from :愛做夢的蘆薈
在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 界限的檢查,經過這樣的設定,才能正確取得檔案資料
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 "); 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