字符驅動
阿新 • • 發佈:2018-08-28
發送數據 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
字符驅動