操作系統(tǒng)課proc文件系統(tǒng)的讀寫實驗(踩坑記錄)

操作系統(tǒng)課的實驗癌幕,proc文件系統(tǒng)踩坑,及解決記錄

老師給的代碼

//proc.c
#include <linux/module.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>

static struct proc_dir_entry *mydir;
static struct proc_dir_entry *pfile;

static char msg[255];

static int myproc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
{
        int len = strlen(msg);

        if (off >= len)
                return 0;

        if (count > len - off)
                count = len - off;

        memcpy(page + off, msg + off, count);
        return off + count;
}

static int myproc_write(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
        unsigned long count2 = count;

        if (count2 >= sizeof(msg))
                count2 = sizeof(msg) - 1;

        if (copy_from_user(msg, buffer, count2))
                return -EFAULT;

        msg[count2] = '\0';
        return count;
}

static int __init myproc_init(void)
{
        mydir = proc_mkdir("mydir", NULL);
        if (!mydir) {
                printk(KERN_ERR "Can't create /proc/mydir\n");
                return -1;
        }

        pfile = create_proc_entry("pool", 0666, mydir);
        if (!pfile) {
                printk(KERN_ERR "Can't create /proc/mydir/pool\n");
                remove_proc_entry("mydir", NULL);
                return -1;
        }

        pfile->read_proc = myproc_read;
        pfile->write_proc = myproc_write;

        return 0;
}

static void __exit myproc_exit(void)
{
        remove_proc_entry("pool", mydir);
        remove_proc_entry("mydir", NULL);
}

module_init(myproc_init);
module_exit(myproc_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lilan");

問題

當我按照實驗指導使用make指令編譯時出現(xiàn)了implicit declaration of function ‘copy_from_user’implicit declaration of function ‘create_proc_entry’dereferencing pointer to incomplete type ‘struct proc_dir_entry’三個錯誤悼枢。

解決

implicit declaration of function ‘copy_from_user’

錯誤位置
if (copy_from_user(msg, buffer, count2))
解決過程

打開編譯時所依賴的庫(我這是 /lib/modules/5.3.0-53-generic/build/include)找到asm文件夾下的uaccess.h后發(fā)現(xiàn)里面的copy_from_user變動成了raw_copy_from_user()參數(shù)沒有變動犀概,修改函數(shù)名后問題就解決了

implicit declaration of function ‘create_proc_entry’

錯誤位置
        pfile = create_proc_entry("pool", 0666, mydir);
        if (!pfile) {
                printk(KERN_ERR "Can't create /proc/mydir/pool\n");
                remove_proc_entry("mydir", NULL);
                return -1;
        }

        pfile->read_proc = myproc_read;
        pfile->write_proc = myproc_write;

        return 0;
解決過程

按和上面一樣的方法找到linux文件夾下的proc_fs.h,查看后發(fā)現(xiàn)找不到create_proc_entry這個函數(shù)挂滓,不過找到了一個名為proc_create的函數(shù)苦银,于是猜測這是否就create_proc_entry的替代。

查看函數(shù)后蒙了赶站,原本的函數(shù)只有三個參數(shù)幔虏,而這個函數(shù)居然有四個參數(shù)。

于是面向百度編程贝椿,搜索一番后果然猜想沒錯想括,確實是由proc_create替代了之前的create_proc_entry,并且博客上還寫出了使用方法。參考的博客

根據(jù)博客上所寫烙博,第四個參數(shù)是用來指定read和write函數(shù)用的結(jié)構(gòu)體,那么dereferencing pointer to incomplete type ‘struct proc_dir_entry’這個錯誤也就明白了瑟蜈,因為通過定義結(jié)構(gòu)體來指定read和write函數(shù)了,所以原本用來指定的struct proc_dir_entry結(jié)構(gòu)體中自然就已經(jīng)沒有了這兩個指針渣窜。

修改后
static struct file_operations my_ops={//新增的結(jié)構(gòu)體
.read=myproc_read,
.write=myproc_write,
.owner=THIS_MODULE,
};
                    .
                    .
                    .
        pfile = proc_create("pool", 0666, mydir,&my_ops);//在這里新增了結(jié)構(gòu)體的地址
        if (!pfile) {
                printk(KERN_ERR "Can't create /proc/mydir/pool\n");
                remove_proc_entry("mydir", NULL);
                return -1;
        }
//兩個pfile->都刪除
        return 0;

然后

本以為這樣就解決了铺根,然后再次make,這下好了myproc_readmyproc_write也出現(xiàn)了implicit declaration of function 的錯誤(老師啊乔宿,不帶這么坑學生的……)

解決

于是我打開找到file_operations這個結(jié)構(gòu)體,找到了里面read和write函數(shù)的結(jié)構(gòu)一看

//file_operations中的
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);

//我的
int myproc_read(char *page, char **start, off_t off, int count, int *eof, void *data)
int myproc_write(struct file *file, const char __user *buffer, unsigned long count, void *data)

這尼瑪相差也太大了位迂,唉看來是要把老師給的代碼來一個大整改了啊(吐血)

修改的過程我就不描述了,這里貼上改好的代碼,如果未來恰好有學弟學妹的也碰上了同樣的實驗,遇見了同樣的問題,希望能有所幫助囤官。因為實驗報告要求代碼詳細注釋冬阳,注釋我也就保留不刪了(注釋是我自己的理解有錯別噴,哈哈)党饮。

#include <linux/module.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>

static struct proc_dir_entry *mydir;
static struct proc_dir_entry *pfile;
static ssize_t myproc_write(struct file *file, const char __user *buff, size_t len,  loff_t *pos);
static ssize_t myproc_read(struct file *filp,char __user *buff,size_t len, loff_t *pos);
static char msg[255];
static struct file_operations my_ops={//定義file_operations的結(jié)構(gòu)體指定read和write函數(shù)
.read=myproc_read,
.write=myproc_write,
.owner=THIS_MODULE,
};

static ssize_t myproc_read(struct file *filp,char __user *buff,size_t count, loff_t *pos)
{
    unsigned int len=strlen(msg);//得到內(nèi)核空間大小
    unsigned long p = *pos;//獲取偏移量
    if(p>=len)//如果偏移超過了空間容量則返回0
        return 0;
        if (count > len-p)//如果用戶讀取大于內(nèi)核空間肝陪,修正為全部讀出
                count = len-p;

        if(raw_copy_to_user(buff+p,msg+p, count))//將內(nèi)核空間內(nèi)容復制進用戶空間
        return -EFAULT;//如果失敗返回錯誤碼
    *pos+=count;//偏移量修正
    printk("read pos:%ld,count:%ld\n",p,count);
        return count;//返回讀取長度
}
static ssize_t myproc_write(struct file *file, const char __user *buff, size_t len,  loff_t *pos)
{
    unsigned long len2 = len;
        if (len2>=sizeof(msg))//如果寫入的內(nèi)容超出內(nèi)核空間容量
            len2=sizeof(msg)-1;//只保留可存儲部分

        if (raw_copy_from_user(msg, buff, len2))//將緩存的內(nèi)容寫入內(nèi)核空間
                return -EFAULT;//返回錯誤碼
        msg[len2] = '\0';//結(jié)束標識符
        return len;//返回寫入長度
}

static int __init myproc_init(void)
{
        mydir = proc_mkdir("mydir", NULL);//創(chuàng)建proc文件夾mydir
        if (!mydir) {
                printk(KERN_ERR "Can't create /proc/mydir\n");//創(chuàng)建失敗系統(tǒng)報錯并結(jié)束模塊
                return -1;
        }

        pfile = proc_create("pool", 0666, mydir,&my_ops);//創(chuàng)建proc文件pool并賦予用戶讀寫權(quán)限,并指定讀寫方法
        if (!pfile) {
                printk(KERN_ERR "Can't create /proc/mydir/pool\n");
                remove_proc_entry("mydir", NULL);
                return -1;//如果創(chuàng)建失敗刪除mydir文件夾并報錯結(jié)束模塊
        }
        return 0;
}

static void __exit myproc_exit(void)
{
        remove_proc_entry("pool", mydir);//刪除mydir文件夾中的pool文件
        remove_proc_entry("mydir", NULL);//刪除mydir文件夾
}

module_init(myproc_init);//模塊初始化調(diào)用myproc_init函數(shù)
module_exit(myproc_exit);//模塊卸載時調(diào)用myproc_exit函數(shù)
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Rainc");

個人博客:https://www.rainc.top/2020/06/01/essay/proc

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市刑顺,隨后出現(xiàn)的幾起案子氯窍,更是在濱河造成了極大的恐慌,老刑警劉巖蹲堂,帶你破解...
    沈念sama閱讀 222,729評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件狼讨,死亡現(xiàn)場離奇詭異,居然都是意外死亡柒竞,警方通過查閱死者的電腦和手機政供,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,226評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來朽基,“玉大人布隔,你說我怎么就攤上這事〖诨ⅲ” “怎么了衅檀?”我有些...
    開封第一講書人閱讀 169,461評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長霎俩。 經(jīng)常有香客問我哀军,道長,這世上最難降的妖魔是什么打却? 我笑而不...
    開封第一講書人閱讀 60,135評論 1 300
  • 正文 為了忘掉前任杉适,我火速辦了婚禮,結(jié)果婚禮上学密,老公的妹妹穿的比我還像新娘淘衙。我一直安慰自己,他們只是感情好腻暮,可當我...
    茶點故事閱讀 69,130評論 6 398
  • 文/花漫 我一把揭開白布彤守。 她就那樣靜靜地躺著,像睡著了一般哭靖。 火紅的嫁衣襯著肌膚如雪具垫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,736評論 1 312
  • 那天试幽,我揣著相機與錄音筝蚕,去河邊找鬼。 笑死,一個胖子當著我的面吹牛起宽,可吹牛的內(nèi)容都是我干的洲胖。 我是一名探鬼主播,決...
    沈念sama閱讀 41,179評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼坯沪,長吁一口氣:“原來是場噩夢啊……” “哼绿映!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起腐晾,我...
    開封第一講書人閱讀 40,124評論 0 277
  • 序言:老撾萬榮一對情侶失蹤叉弦,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后藻糖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體淹冰,經(jīng)...
    沈念sama閱讀 46,657評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,723評論 3 342
  • 正文 我和宋清朗相戀三年巨柒,在試婚紗的時候發(fā)現(xiàn)自己被綠了樱拴。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,872評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡潘拱,死狀恐怖疹鳄,靈堂內(nèi)的尸體忽然破棺而出拧略,到底是詐尸還是另有隱情芦岂,我是刑警寧澤,帶...
    沈念sama閱讀 36,533評論 5 351
  • 正文 年R本政府宣布垫蛆,位于F島的核電站禽最,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏袱饭。R本人自食惡果不足惜川无,卻給世界環(huán)境...
    茶點故事閱讀 42,213評論 3 336
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望虑乖。 院中可真熱鬧懦趋,春花似錦、人聲如沸疹味。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,700評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽糙捺。三九已至诫咱,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間洪灯,已是汗流浹背坎缭。 一陣腳步聲響...
    開封第一講書人閱讀 33,819評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人掏呼。 一個月前我還...
    沈念sama閱讀 49,304評論 3 379
  • 正文 我出身青樓坏快,卻偏偏與公主長得像,于是被迫代替她去往敵國和親憎夷。 傳聞我的和親對象是個殘疾皇子假消,可洞房花燭夜當晚...
    茶點故事閱讀 45,876評論 2 361