C/C++知识点之字符驱动
小标 2019-03-14 来源 : 阅读 657 评论 0

摘要:本文主要向大家介绍了C/C++知识点之字符驱动,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

本文主要向大家介绍了C/C++知识点之字符驱动,通过具体的内容向大家展示,希望对大家学习C/C++知识点有所帮助。

C/C++知识点之字符驱动


//#include <linux/config.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>

#include <linux/kernel.h>   /* printk() */
#include <linux/slab.h>   /* kmalloc() */
#include <linux/fs.h>       /* everything... */
#include <linux/errno.h>    /* error codes */
#include <linux/types.h>    /* size_t */
#include <linux/mm.h>
#include <linux/kdev_t.h>
#include <asm/page.h>
#include <linux/cdev.h>

#include <linux/device.h>
//主设备号
static int simple_major = 0;
//从设置号
static int minor=0;
module_param(simple_major, int, 0);
MODULE_AUTHOR("Jonathan Corbet");
MODULE_LICENSE("Dual BSD/GPL");
int simple_open (struct inode *inode, struct file *filp)
{
    return 0;
}

static int simple_release(struct inode *inode, struct file *filp)
{
    return 0;
}

void simple_vma_open(struct vm_area_struct *vma)
{
    printk(KERN_NOTICE "Simple VMA open, virt %lx, phys %lx\n",
           vma->vm_start, vma->vm_pgoff << PAGE_SHIFT);
}

void simple_vma_close(struct vm_area_struct *vma)
{
    printk(KERN_NOTICE "Simple VMA close.\n");
}

static struct vm_operations_struct simple_remap_vm_ops = {
    .open =  simple_vma_open,
    .close = simple_vma_close,
};

static int simple_remap_mmap(struct file *filp, struct vm_area_struct *vma)
{
    if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
                        vma->vm_end - vma->vm_start,
                        vma->vm_page_prot))
        return -EAGAIN;

    vma->vm_ops = &simple_remap_vm_ops;
    simple_vma_open(vma);
    return 0;
}

struct page *simple_vma_nopage(struct vm_area_struct *vma,
                               unsigned long address, int *type)
{
    struct page *pageptr;
    unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
    unsigned long physaddr = address - vma->vm_start + offset;
    unsigned long pageframe = physaddr >> PAGE_SHIFT;

    // Eventually remove these printks
    printk (KERN_NOTICE "---- Nopage, off %lx phys %lx\n", offset, physaddr);
    printk (KERN_NOTICE "VA is %p\n", __va (physaddr));
    printk (KERN_NOTICE "Page at %p\n", virt_to_page (__va (physaddr)));
    if (!pfn_valid(pageframe))
        //return NOPAGE_SIGBUS;
    return NULL;
    pageptr = pfn_to_page(pageframe);
    printk (KERN_NOTICE "page->index = %ld mapping %p\n", pageptr->index, pageptr->mapping);
    printk (KERN_NOTICE "Page frame %ld\n", pageframe);
    get_page(pageptr);
    if (type)
        *type = VM_FAULT_MINOR;
    return pageptr;
}

static struct vm_operations_struct simple_nopage_vm_ops = {
    .open =   simple_vma_open,
    .close =  simple_vma_close,
    //.nopage = simple_vma_nopage,
};

static int simple_nopage_mmap(struct file *filp, struct vm_area_struct *vma)
{
    unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;

    if (offset >= __pa(high_memory) || (filp->f_flags & O_SYNC))
        vma->vm_flags |= VM_IO;
   // vma->vm_flags |= VM_RESERVED;
    vma->vm_flags |=(VM_DONTEXPAND | VM_DONTDUMP);

    vma->vm_ops = &simple_nopage_vm_ops;
    simple_vma_open(vma);
    return 0;
}

/*
 * Set up the cdev structure for a device.
 */
//https://www.cnblogs.com/chen-farsight/p/6181341.html
//struct file_operations {
//      struct module *owner;//拥有该结构的模块的指针,一般为THIS_MODULES
//    loff_t (*llseek) (struct file *, loff_t, int);//用来修改文件当前的读写位置
//    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);//从设备中同步读取数据
//    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);//向设备发送数据
//    ssize_t (*aio_read) (struct kiocb *, const struct iovec *, unsigned long, loff_t);//初始化一个异步的读取操作
//    ssize_t (*aio_write) (struct kiocb *, const struct iovec *, unsigned long, loff_t);//初始化一个异步的写入操作
//      int (*readdir) (struct file *, void *, filldir_t);//仅用于读取目录,对于设备文件,该字段为NULL
//    unsigned int (*poll) (struct file *, struct poll_table_struct *); //轮询函数,判断目前是否可以进行非阻塞的读写或写入
//      int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long); //执行设备I/O控制命令
//      long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long); //不使用BLK文件系统,将使用此种函数指针代替ioctl
//      long (*compat_ioctl) (struct file *, unsigned int, unsigned long); //在64位系统上,32位的ioctl调用将使用此函数指针代替
//      int (*mmap) (struct file *, struct vm_area_struct *); //用于请求将设备内存映射到进程地址空间
//      int (*open) (struct inode *, struct file *); //打开
//      int (*flush) (struct file *, fl_owner_t id);
//      int (*release) (struct inode *, struct file *); //关闭
//      int (*fsync) (struct file *, struct dentry *, int datasync); //刷新待处理的数据
//      int (*aio_fsync) (struct kiocb *, int datasync); //异步刷新待处理的数据
//      int (*fasync) (int, struct file *, int); //通知设备FASYNC标志发生变化
//      int (*lock) (struct file *, int, struct file_lock *);
//      ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
//      unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
//      int (*check_flags)(int);
//      int (*flock) (struct file *, int, struct file_lock *);
//      ssize_t (*splice_write)(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int);
//      ssize_t (*splice_read)(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int);
//      int (*setlease)(struct file *, long, struct file_lock **);
//};
static void simple_setup_cdev(struct cdev *dev, int minor,
                              struct file_operations *fops)
{
    int err, devno = MKDEV(simple_major, minor);
    //字符设备注册
    cdev_init(dev, fops);
    //当前模块挺有这个设备
    dev->owner = THIS_MODULE;
    dev->ops = fops;
    //添加
    err = cdev_add (dev, devno, 1);
    if (err)
        printk (KERN_NOTICE "Error %d adding simple%d", err, minor);
}

//初始化
static struct file_operations simple_remap_ops = {
    .owner   = THIS_MODULE,
    .open    = simple_open,
    .release = simple_release,
    .mmap    = simple_remap_mmap,
};

//初始化
static struct file_operations simple_nopage_ops = {
    .owner   = THIS_MODULE,
    .open    = simple_open,
    .release = simple_release,
    .mmap    = simple_nopage_mmap,
};

#define MAX_SIMPLE_DEV 2

#if 0
static struct file_operations *simple_fops[MAX_SIMPLE_DEV] = {
    &simple_remap_ops,
    &simple_nopage_ops,
};
#endif

//俩个简单的字符设备
static struct cdev SimpleDevs[MAX_SIMPLE_DEV];

static int simple_init(void)
{
    int result;
    //MKDEV是将主设备号和次设备号转换成dev_t类型
    dev_t dev = MKDEV(simple_major, minor);

    //找出设备号
    if (simple_major)
        //进行字符设备设备节点的分配
        result = register_chrdev_region(dev, 2, "simple");
    else {
        //动态申请
        result = alloc_chrdev_region(&dev, 0, 2, "simple");
        simple_major = MAJOR(dev);
    }
    if (result < 0) {
        printk(KERN_WARNING "simple: unable to get major %d\n", simple_major);
        return result;
    }
    if (simple_major == 0)
        simple_major = result;
    printk(KERN_WARNING "haha!!!!\n");
    //设置俩个字符设备
    simple_setup_cdev(SimpleDevs, 0, &simple_remap_ops);
    simple_setup_cdev(SimpleDevs + 1, 1, &simple_nopage_ops);
    return 0;
}

static void simple_cleanup(void)
{
    cdev_del(SimpleDevs);
    cdev_del(SimpleDevs + 1);
    unregister_chrdev_region(MKDEV(simple_major, 0), 2);
}

module_init(simple_init);
module_exit(simple_cleanup);


obj-m   := hello.o

KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD       := $(shell pwd)

all:
    $(MAKE) -C $(KERNELDIR) M=$(PWD)

clean:
    rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions


root@ubuntu:~/Desktop# make
make -C /lib/modules/4.2.0-27-generic/build M=/root/Desktop
make[1]: Entering directory `/usr/src/linux-headers-4.2.0-27-generic'
  LD      /root/Desktop/built-in.o
  CC [M]  /root/Desktop/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /root/Desktop/hello.mod.o
  LD [M]  /root/Desktop/hello.ko
make[1]: Leaving directory `/usr/src/linux-headers-4.2.0-27-generic'
root@ubuntu:~/Desktop# insmod ./hello.ko
insmod: ERROR: could not insert module ./hello.ko: File exists
root@ubuntu:~/Desktop# lsmod
Module                  Size  Used by
hello                  16384  0
coretemp               16384  0
crct10dif_pclmul       16384  0
crc32_pclmul           16384  0
aesni_intel           167936  0
snd_ens1371            28672  0
snd_ac97_codec        131072  1 snd_ens1371
aes_x86_64             20480  1 aesni_intel
gameport               16384  1 snd_ens1371
ac97_bus               16384  1 snd_ac97_codec
vmw_balloon            16384  0
lrw                    16384  1 aesni_intel
gf128mul               16384  1 lrw
glue_helper            16384  1 aesni_intel
ablk_helper            16384  1 aesni_intel
snd_pcm               102400  2 snd_ac97_codec,snd_ens1371
cryptd                 20480  2 aesni_intel,ablk_helper
snd_seq_midi           16384  0
snd_seq_midi_event     16384  1 snd_seq_midi
input_leds             16384  0
joydev                 20480  0
serio_raw              16384  0
snd_rawmidi            32768  2 snd_ens1371,snd_seq_midi
snd_seq                69632  2 snd_seq_midi_event,snd_seq_midi
vmwgfx                172032  3
snd_seq_device         16384  3 snd_seq,snd_rawmidi,snd_seq_midi
ttm                    94208  1 vmwgfx
snd_timer              32768  2 snd_pcm,snd_seq
btusb                  45056  0
drm_kms_helper        126976  1 vmwgfx
snd                    81920  7 snd_ac97_codec,snd_timer,snd_pcm,snd_seq,snd_rawmidi,snd_ens1371,snd_seq_device
btrtl                  16384  1 btusb
btbcm                  16384  1 btusb
btintel                16384  1 btusb
drm                   360448  6 ttm,drm_kms_helper,vmwgfx
soundcore              16384  1 snd
vmw_vmci               65536  0
i2c_piix4              24576  0
shpchp                 36864  0
nfit                   32768  0
rfcomm                 69632  8
bnep                   20480  2
8250_fintek            16384  0
bluetooth             512000  25 bnep,btbcm,btrtl,btusb,rfcomm,btintel
binfmt_misc            20480  1
mac_hid                16384  0
parport_pc             32768  0
ppdev                  20480  0
lp                     20480  0
parport                49152  3 lp,ppdev,parport_pc
hid_generic            16384  0
usbhid                 49152  0
hid                   118784  2 hid_generic,usbhid
psmouse               126976  0
mptspi                 24576  2
mptscsih               40960  1 mptspi
mptbase                98304  2 mptspi,mptscsih
ahci                   36864  0
libahci                32768  1 ahci
e1000                 131072  0
scsi_transport_spi     32768  1 mptspi
pata_acpi              16384  0
root@ubuntu:~/Desktop# rmmod ./hello.ko
root@ubuntu:~/Desktop# lsmod
Module                  Size  Used by
coretemp               16384  0
crct10dif_pclmul       16384  0
crc32_pclmul           16384  0
aesni_intel           167936  0
snd_ens1371            28672  0
snd_ac97_codec        131072  1 snd_ens1371
aes_x86_64             20480  1 aesni_intel
gameport               16384  1 snd_ens1371
ac97_bus               16384  1 snd_ac97_codec
vmw_balloon            16384  0
lrw                    16384  1 aesni_intel
gf128mul               16384  1 lrw
glue_helper            16384  1 aesni_intel
ablk_helper            16384  1 aesni_intel
snd_pcm               102400  2 snd_ac97_codec,snd_ens1371
cryptd                 20480  2 aesni_intel,ablk_helper
snd_seq_midi           16384  0
snd_seq_midi_event     16384  1 snd_seq_midi
input_leds             16384  0
joydev                 20480  0
serio_raw              16384  0
snd_rawmidi            32768  2 snd_ens1371,snd_seq_midi
snd_seq                69632  2 snd_seq_midi_event,snd_seq_midi
vmwgfx                172032  3
snd_seq_device         16384  3 snd_seq,snd_rawmidi,snd_seq_midi
ttm                    94208  1 vmwgfx
snd_timer              32768  2 snd_pcm,snd_seq
btusb                  45056  0
drm_kms_helper        126976  1 vmwgfx
snd                    81920  7 snd_ac97_codec,snd_timer,snd_pcm,snd_seq,snd_rawmidi,snd_ens1371,snd_seq_device
btrtl                  16384  1 btusb
btbcm                  16384  1 btusb
btintel                16384  1 btusb
drm                   360448  6 ttm,drm_kms_helper,vmwgfx
soundcore              16384  1 snd
vmw_vmci               65536  0
i2c_piix4              24576  0
shpchp                 36864  0
nfit                   32768  0
rfcomm                 69632  8
bnep                   20480  2
8250_fintek            16384  0
bluetooth             512000  25 bnep,btbcm,btrtl,btusb,rfcomm,btintel
binfmt_misc            20480  1
mac_hid                16384  0
parport_pc             32768  0
ppdev                  20480  0
lp                     20480  0
parport                49152  3 lp,ppdev,parport_pc
hid_generic            16384  0
usbhid                 49152  0
hid                   118784  2 hid_generic,usbhid
psmouse               126976  0
mptspi                 24576  2
mptscsih               40960  1 mptspi
mptbase                98304  2 mptspi,mptscsih
ahci                   36864  0
libahci                32768  1 ahci
e1000                 131072  0
scsi_transport_spi     32768  1 mptspi
pata_acpi              16384  0
root@ubuntu:~/Desktop# rmmod ./hello.ko
rmmod: ERROR: Module hello is not currently loaded
root@ubuntu:~/Desktop# lsmod
Module                  Size  Used by
coretemp               16384  0
crct10dif_pclmul       16384  0
crc32_pclmul           16384  0
aesni_intel           167936  0
snd_ens1371            28672  0
snd_ac97_codec        131072  1 snd_ens1371
aes_x86_64             20480  1 aesni_intel
gameport               16384  1 snd_ens1371
ac97_bus               16384  1 snd_ac97_codec
vmw_balloon            16384  0
lrw                    16384  1 aesni_intel
gf128mul               16384  1 lrw
glue_helper            16384  1 aesni_intel
ablk_helper            16384  1 aesni_intel
snd_pcm               102400  2 snd_ac97_codec,snd_ens1371
cryptd                 20480  2 aesni_intel,ablk_helper
snd_seq_midi           16384  0
snd_seq_midi_event     16384  1 snd_seq_midi
input_leds             16384  0
joydev                 20480  0
serio_raw              16384  0
snd_rawmidi            32768  2 snd_ens1371,snd_seq_midi
snd_seq                69632  2 snd_seq_midi_event,snd_seq_midi
vmwgfx                172032  3
snd_seq_device         16384  3 snd_seq,snd_rawmidi,snd_seq_midi
ttm                    94208  1 vmwgfx
snd_timer              32768  2 snd_pcm,snd_seq
btusb                  45056  0
drm_kms_helper        126976  1 vmwgfx
snd                    81920  7 snd_ac97_codec,snd_timer,snd_pcm,snd_seq,snd_rawmidi,snd_ens1371,snd_seq_device
btrtl                  16384  1 btusb
btbcm                  16384  1 btusb
btintel                16384  1 btusb
drm                   360448  6 ttm,drm_kms_helper,vmwgfx
soundcore              16384  1 snd
vmw_vmci               65536  0
i2c_piix4              24576  0
shpchp                 36864  0
nfit                   32768  0
rfcomm                 69632  8
bnep                   20480  2
8250_fintek            16384  0
bluetooth             512000  25 bnep,btbcm,btrtl,btusb,rfcomm,btintel
binfmt_misc            20480  1
mac_hid                16384  0
parport_pc             32768  0
ppdev                  20480  0
lp                     20480  0
parport                49152  3 lp,ppdev,parport_pc
hid_generic            16384  0
usbhid                 49152  0
hid                   118784  2 hid_generic,usbhid
psmouse               126976  0
mptspi                 24576  2
mptscsih               40960  1 mptspi
mptbase                98304  2 mptspi,mptscsih
ahci                   36864  0
libahci                32768  1 ahci
e1000                 131072  0
scsi_transport_spi     32768  1 mptspi
pata_acpi              16384  0
root@ubuntu:~/Desktop# insmod ./hello.ko
root@ubuntu:~/Desktop# tail /var/log/kern.log
Aug 26 07:31:10 ubuntu kernel: [ 1602.408792] the process is"1383225440"(pid 3571)
Aug 26 07:32:39 ubuntu kernel: [ 1691.260987] Bye, kernel!
Aug 26 07:33:50 ubuntu kernel: [ 1762.382921] the process is"1656784352"(pid 3890)
Aug 26 07:54:13 ubuntu kernel: [ 2984.808053] e1000: eth0 NIC Link is Down
Aug 26 07:54:17 ubuntu kernel: [ 2988.809018] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None
Aug 26 08:04:09 ubuntu kernel: [ 3580.921624] Bye, kernel!
Aug 26 08:04:11 ubuntu kernel: [ 3583.102812] hello: unknown parameter 'howmany' ignored
Aug 26 08:04:11 ubuntu kernel: [ 3583.102818] hello: unknown parameter 'whom' ignored
Aug 26 08:04:11 ubuntu kernel: [ 3583.106649] the process is"1514516256"(pid 3973)
Aug 26 09:43:32 ubuntu kernel: [ 9544.684133] Bye, kernel!
root@ubuntu:~/Desktop# rmmod ./hello.ko
root@ubuntu:~/Desktop# make
make -C /lib/modules/4.2.0-27-generic/build M=/root/Desktop
make[1]: Entering directory `/usr/src/linux-headers-4.2.0-27-generic'
  CC [M]  /root/Desktop/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /root/Desktop/hello.mod.o
  LD [M]  /root/Desktop/hello.ko
make[1]: Leaving directory `/usr/src/linux-headers-4.2.0-27-generic'
root@ubuntu:~/Desktop# insmod ./hello.ko
root@ubuntu:~/Desktop# tail /var/log/kern.log
Aug 26 07:32:39 ubuntu kernel: [ 1691.260987] Bye, kernel!
Aug 26 07:33:50 ubuntu kernel: [ 1762.382921] the process is"1656784352"(pid 3890)
Aug 26 07:54:13 ubuntu kernel: [ 2984.808053] e1000: eth0 NIC Link is Down
Aug 26 07:54:17 ubuntu kernel: [ 2988.809018] e1000: eth0 NIC Link is Up 1000 Mbps Full Duplex, Flow Control: None
Aug 26 08:04:09 ubuntu kernel: [ 3580.921624] Bye, kernel!
Aug 26 08:04:11 ubuntu kernel: [ 3583.102812] hello: unknown parameter 'howmany' ignored
Aug 26 08:04:11 ubuntu kernel: [ 3583.102818] hello: unknown parameter 'whom' ignored
Aug 26 08:04:11 ubuntu kernel: [ 3583.106649] the process is"1514516256"(pid 3973)
Aug 26 09:43:32 ubuntu kernel: [ 9544.684133] Bye, kernel!
Aug 26 09:45:34 ubuntu kernel: [ 9666.366106] haha!!!!
root@ubuntu:~/Desktop# make

 

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标编程语言C/C+频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程