1. 程式人生 > >字符驅動

字符驅動

發送數據 NPU des __user acpi intel col truct shadow

//#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

技術分享圖片

字符驅動