linux核心檔案讀取

2021-06-18 08:38:42 字數 3307 閱讀 5832

平時

網路部分的東西碰的多些,這塊一開始還真不知道怎麼寫,因為肯定和在

使用者空間下是不同的。google過後,得到以下答案。一般可以用兩種方法:第一種是用

系統呼叫。第二種方法是filp->open()等函式。下面分別來說下這兩種方法。

1 利用系統呼叫:

sys_open,sys_write,sys_read等。

其實分析過sys_open可以知道,最後呼叫的也是filp->open。

sys_open ==> do_sys_open ==> filp->open

在linux

sir上的乙個帖子,上面乙個版主說:sys_open和程序緊密相關,往往不在核心中使用。

而其實sys_open最後也是呼叫了filp->open。

其實好像linux2.6.20後面就不推薦使用sys_open,那我們這裡就就後者進行詳細的介紹

2 filp->open等函式。

在模組中,使用者空間的open,read,write,llseek等函式都是不可以使用的。應該使用其在核心中對應的函式。可以使用filp->open配合struct file裡的read/write來進行對

檔案的讀寫操作。

例子1:

#include

#include

#include

#include

#include

module_author("[email protected]."); 

module_description("kernel study and test."); 

void fileread(const char * filename) 

void filewrite(char* filename, char* data)

fs=get_fs();

set_fs(kernel_ds);

filp->f_op->write(filp, data, strlen(data),&filp->f_pos);

set_fs(fs);

filp_close(filp,null);

}int init_module() 

void cleanup_module() 

複製**

eg2:

#include

#include

#include

#include

#include

#include

#include/* get_fs(),set_fs(),get_ds() */

#define file_dir "/root/test.txt"

module_license("gpl");

module_author("[email protected]");

char *buff = "module read/write test";

char tmp[100];

static struct file *filp = null;

static int __init wr_test_init(void)

return 0;

}static void __exit wr_test_exit(void)

module_init(wr_test_init);

module_exit(wr_test_exit);

複製**

3.makefile

obj-m := os_attack.o

kdir := /lib/modules/$(uname -r)/build/

pwd := $(shell pwd)

all:module

module:

$(make) -c $(kdir) m=$(pwd) modules

clean:

rm -rf *.ko *.mod.c *.o module.* modules.* .*.cmd .tmp_versions

複製**

注意:在呼叫filp->f_op->read和filp->f_op->write等對檔案的操作之前,應該先設定fs。

預設情況下,filp->f_op->read或者filp->f_op->write會對傳進來的引數buff進行指標檢查。如果不是在使用者空間會拒絕訪問。因為是在核心模組中,所以buff肯定不在使用者空間,所以要增大其定址範圍。

拿filp->f_op->write為例來說明:

filp->f_op->write最終會呼叫access_ok ==> range_ok.

而range_ok會判斷訪問的位址是否在0 ~ addr_limit之間。如果在,則ok,繼續。如果不在,則禁止訪問。而核心空間傳過來的buff肯定大於addr_limit。所以要set_fs(get_ds())。

這些函式在asm/uaccess.h中定義。以下是這個標頭檔案中的部分內容:

#define make_mm_seg(s)    ((mm_segment_t) )

#define kernel_ds    make_mm_seg(-1ul)

#define user_ds        make_mm_seg(page_offset)

#define get_ds()    (kernel_ds)

#define get_fs()    (current_thread_info()->addr_limit)

#define set_fs(x)    (current_thread_info()->addr_limit = (x))

#define segment_eq(a, b)    ((a).seg == (b).seg)

可以看到set_fs(get_ds())改變了addr_limit的值。這樣就使得從模組中傳遞進去的引數也可以正常使用了。

在寫測試模組的時候,要實現的功能是寫進去什麼,然後讀出來放在tmp陣列中。但寫完了以後filp->f_ops已經在末尾了,這個時候讀是什麼也讀不到的,如果想要讀到資料,則應該改變filp->f-ops的值,這就要用到filp->f_op->llseek函式了。上網查了下,其中的引數需要記下筆記:

系統呼叫:

off_t sys_lseek(unsigned int fd, off_t offset, unsigned int origin)

offset是偏移量。

若origin是seek_set(0),則將該檔案的位移量設定為距檔案開始處offset 個位元組。

若origin是seek_cur(1),則將該檔案的位移量設定為其當前值加offset, offset可為正或負。

若origin是seek_end(2),則將該檔案的位移量設定為檔案長度加offset, offset可為正或負。

檔案讀取 LINUX核心

file i o in kernel module by flyduck 2001 03 21 define kernel define module include include include include include include include define eof 1 defin...

linux 讀取檔案

linux讀取檔案是經常要用到的操作,以下示例 說明看注釋 讀取檔案snlist.txt中的每一行內容賦給sn變數 while read sn doecho sn is sn 判斷是否是檔案 if d sn then echo sn not existed else 對sn進行 拆分並獲取最後乙個結...

Linux上讀取檔案

linux上讀取檔案的方法 bin bash this is a script fortest exec config file 1 該指令碼傳乙個檔名為引數 file no 1 echo config file exec config file 將 config file中的內容作為exec的標準...