scull字符驅(qū)動的讀

1.scull.c

#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/uaccess.h>
#include <linux/errno.h>
#include <linux/kdev_t.h>
#include <linux/types.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/fs.h>

#define DEV_NAME "scull"

static struct file_operations scull_fops;
static dev_t dev;
static int scull_major = 0;
static int scull_minor;
static int scull_dvnum;

struct scull_dev {
        struct scull_qset *data;
        int quantum;
        int qset;
        unsigned long size;
        unsigned int access_key;
        struct semaphore sem;
        struct cdev cdev;
};

struct scull_qset {
        void **data;
        struct scull_qset *next;
};

struct scull_dev scull_dev;

static int scull_trim(struct scull_dev *dev)
{
        struct scull_qset *next, *dptr;
        int qset = dev->qset;
        int i;

        for(dptr=dev->data; dptr; dptr=next)
        {
                if(dptr->data)
                {
                        for(i=0; i<qset; i++)
                                kfree(dptr->data[i]);
                        kfree(dptr->data);
                        dptr->data = NULL;
                }

                next = dptr->next;

                kfree(dptr);
        }

        return 0;
}

static struct scull_qset *scull_follow(struct scull_dev *dev, int item)
{
        struct scull_qset *next, *dptr;
        int i;

        dptr=dev->data;

        for(i=0; i<item && dptr; i++)
        {
                next = dptr->next;
                dptr = next;
        }

        return dptr;
}

int scull_open(struct inode *inode, struct file *filp)
{
        struct scull_dev *dev;

        dev = container_of(inode->i_cdev, struct scull_dev, cdev);
        filp->private_data = dev;

        if((filp->f_flags && O_ACCMODE) == O_WRONLY)
        {
                scull_trim(dev);
        }

        printk(KERN_NOTICE "opened the file[%p]\n", filp);

        return 0;
}

int scull_release(struct inode *inode, struct file *filp)
{
        printk(KERN_NOTICE "closed the file[%p]\n", filp);

        return 0;
}

//讀scull字符設(shè)備
ssize_t scull_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
        struct scull_dev *dev = filp->private_data;
        struct scull_qset *dptr;
        int quantum = dev->quantum;
        int qset = dev->qset;
        int itemsize = quantum * qset;
        int item, s_pos, q_pos, rest;
        ssize_t retval = 0;

        //if(down_interruptible(&dev->sem))
        //      return -ERESTARTSYS;

        if(*f_pos >= dev->size)
                goto out;

        if(*f_pos + count > dev->size)
                count = dev->size - *f_pos;

        item = (long)*f_pos / itemsize;
        rest = (long)*f_pos % itemsize;
        s_pos = rest / quantum;
        q_pos = rest % quantum;

        dptr = scull_follow(dev, item);

        if(dptr==NULL || !dptr->data || !dptr->data[s_pos])
        {
                goto out;
        }

        if(count > quantum - q_pos)
        {
                count = quantum - q_pos;
        }

        if(copy_to_user(buf, dptr->data[s_pos]+q_pos, count))
        {
                retval = -EFAULT;
                goto out;
        }

        *f_pos += count;
        retval = count;

out:
        //up(&dev->sem);

        printk(KERN_NOTICE "read the file[%p]\n", filp);

        return retval;
}

static void scull_setup_cdev(dev_t devno, struct scull_dev *dev, int index)
{
        //int devno;
        int err;

        //devno = MKDEV(scull_major, scull_minor);

        scull_fops.open = scull_open;
        scull_fops.release = scull_release;
        scull_fops.read = scull_read;
        cdev_init(&dev->cdev, &scull_fops);
        dev->cdev.owner = THIS_MODULE;
        dev->cdev.ops = &scull_fops;

        err = cdev_add(&dev->cdev, devno, 1);

        if(err)
                printk(KERN_NOTICE "Error %d adding scull%d\n", err, index);
}

static int __init scull_init(void)
{
        int ret;

        printk("init module\n");

        if(scull_major)
        {
                dev = MKDEV(scull_major, scull_minor);
                ret = register_chrdev_region(dev, scull_dvnum, DEV_NAME);
        }
        else
        {
                scull_dvnum = 4;
                scull_minor = 0;
                ret = alloc_chrdev_region(&dev, scull_minor, scull_dvnum, DEV_NAME);
                scull_major = MAJOR(dev);
        }

        if(ret < 0)
        {
                printk("scull: can't get major %d\n", scull_major);
        }

        scull_setup_cdev(dev, &scull_dev, 0);

        return 0;
}

static void __exit scull_exit(void)
{
        cdev_del(&scull_dev.cdev);

        unregister_chrdev_region(dev, scull_dvnum);

        printk("exit module, major=[%d]\n", scull_major);
}

module_init(scull_init);
module_exit(scull_exit);

2.編譯模塊

$ make

3.安裝模塊

# insmod

4.創(chuàng)建設(shè)備

# ./scull_load

5.打開, 讀和關(guān)閉設(shè)備

# cat /dev/scull0

6.查看打印日志

# tail -n 4 /var/log/messages
Nov  6 00:02:41 linux kernel: [ 5831.619786] init module
Nov  6 00:02:45 linux kernel: [ 5835.560676] opened the file[ffff8800452738c0]
Nov  6 00:02:45 linux kernel: [ 5835.560687] read the file[ffff8800452738c0]
Nov  6 00:02:45 linux kernel: [ 5835.560692] closed the file[ffff8800452738c0]
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末腕窥,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子掖举,更是在濱河造成了極大的恐慌米间,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,324評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡澄暮,警方通過查閱死者的電腦和手機名段,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,356評論 3 392
  • 文/潘曉璐 我一進店門阱扬,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人伸辟,你說我怎么就攤上這事麻惶。” “怎么了信夫?”我有些...
    開封第一講書人閱讀 162,328評論 0 353
  • 文/不壞的土叔 我叫張陵窃蹋,是天一觀的道長。 經(jīng)常有香客問我静稻,道長警没,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,147評論 1 292
  • 正文 為了忘掉前任振湾,我火速辦了婚禮杀迹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘押搪。我一直安慰自己树酪,他們只是感情好,可當我...
    茶點故事閱讀 67,160評論 6 388
  • 文/花漫 我一把揭開白布大州。 她就那樣靜靜地躺著续语,像睡著了一般。 火紅的嫁衣襯著肌膚如雪厦画。 梳的紋絲不亂的頭發(fā)上疮茄,一...
    開封第一講書人閱讀 51,115評論 1 296
  • 那天,我揣著相機與錄音根暑,去河邊找鬼力试。 笑死,一個胖子當著我的面吹牛购裙,可吹牛的內(nèi)容都是我干的懂版。 我是一名探鬼主播,決...
    沈念sama閱讀 40,025評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼躏率,長吁一口氣:“原來是場噩夢啊……” “哼躯畴!你這毒婦竟也來了民鼓?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,867評論 0 274
  • 序言:老撾萬榮一對情侶失蹤蓬抄,失蹤者是張志新(化名)和其女友劉穎丰嘉,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嚷缭,經(jīng)...
    沈念sama閱讀 45,307評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡饮亏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,528評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了阅爽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片路幸。...
    茶點故事閱讀 39,688評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖付翁,靈堂內(nèi)的尸體忽然破棺而出简肴,到底是詐尸還是另有隱情,我是刑警寧澤百侧,帶...
    沈念sama閱讀 35,409評論 5 343
  • 正文 年R本政府宣布砰识,位于F島的核電站,受9級特大地震影響佣渴,放射性物質(zhì)發(fā)生泄漏辫狼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,001評論 3 325
  • 文/蒙蒙 一辛润、第九天 我趴在偏房一處隱蔽的房頂上張望膨处。 院中可真熱鬧,春花似錦频蛔、人聲如沸灵迫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,657評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽瀑粥。三九已至,卻和暖如春三圆,著一層夾襖步出監(jiān)牢的瞬間狞换,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,811評論 1 268
  • 我被黑心中介騙來泰國打工舟肉, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留修噪,地道東北人。 一個月前我還...
    沈念sama閱讀 47,685評論 2 368
  • 正文 我出身青樓路媚,卻偏偏與公主長得像黄琼,于是被迫代替她去往敵國和親貌夕。 傳聞我的和親對象是個殘疾皇子唇跨,可洞房花燭夜當晚...
    茶點故事閱讀 44,573評論 2 353

推薦閱讀更多精彩內(nèi)容

  • ORA-00001: 違反唯一約束條件 (.) 錯誤說明:當在唯一索引所對應(yīng)的列上鍵入重復(fù)值時款咖,會觸發(fā)此異常退盯。 O...
    我想起個好名字閱讀 5,306評論 0 9
  • feisky云計算、虛擬化與Linux技術(shù)筆記posts - 1014, comments - 298, trac...
    不排版閱讀 3,843評論 0 5
  • 專業(yè)考題類型管理運行工作負責人一般作業(yè)考題內(nèi)容選項A選項B選項C選項D選項E選項F正確答案 變電單選GYSZ本規(guī)程...
    小白兔去釣魚閱讀 8,984評論 0 13
  • 一撤师、Python簡介和環(huán)境搭建以及pip的安裝 4課時實驗課主要內(nèi)容 【Python簡介】: Python 是一個...
    _小老虎_閱讀 5,744評論 0 10
  • 游譚柘寺 賞景 霧里山中古寺連剂府, 此情此景修千年, 時節(jié)恰好金黃葉剃盾, 就已流連忘世間腺占。 拜佛 ...
    孤々閱讀 265評論 0 0