📄 pilchard.c
字号:
/*** Pilchard board driver (kernel 2.4.8)*/ #include <linux/module.h>#include <linux/kernel.h> #include <linux/config.h>#include <linux/mm.h>#include <linux/miscdevice.h>#include <linux/malloc.h>#include <linux/vmalloc.h>#include <linux/mman.h>#include <linux/init.h>#include <asm/uaccess.h>#include <asm/io.h>#include <asm/pgtable.h> static char *pilchard_base;#define PILCHARD_MAJOR 240 /* major number */#define PILCHARD_BUFZ 0x200000 /* size of Pilchard pilchard_base area */ /* this code is adapted from drivers/char/bttv.c:do_bttv_mmap */ static int pilchard_mmap(struct file *filp, struct vm_area_struct *vma){ unsigned long page,pos; unsigned long start = (unsigned long)vma->vm_start; unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start); #ifdef DEBUG printk(KERN_INFO "pilchard: mmap start=0x%lx size=%ld pilchard_base=0x%lx\n", start, size, (unsigned long)pilchard_base);#endif /* if userspace tries to mmap beyond end of our buffer, fail */ if (size > PILCHARD_BUFZ) return -EINVAL; /* start off at the start of the buffer */ pos= (unsigned long)pilchard_base; /* loop through all the physical pages in the buffer */ /* Remember this won't work for vmalloc()d memory ! */ while (size > 0) { /* remap a single physical page to the process's vma */ page = virt_to_phys((void *)pos); /* fourth argument is the protection of the map */ if (remap_page_range(start, page, PAGE_SIZE, PAGE_SHARED)) return -EAGAIN; start += PAGE_SIZE; pos += PAGE_SIZE; size -= PAGE_SIZE; } return 0; }static int pilchard_open(struct inode *inode, struct file *filp){#ifdef DEBUG printk(KERN_INFO "pilchard: open\n");#endif return 0; } static int pilchard_release(struct inode *inode, struct file *filp){#ifdef DEBUG printk(KERN_INFO "pilchard: release\n");#endif return 0;} /* VFS methods */ static struct file_operations pilchard_fops = { owner: THIS_MODULE, open: pilchard_open, release: pilchard_release, mmap: pilchard_mmap };int pilchard_init(void){ unsigned long pilmem; if (devfs_register_chrdev(PILCHARD_MAJOR, "pilchard", &pilchard_fops)) { printk(KERN_INFO "pilchard: can't register major=%d\n", PILCHARD_MAJOR); return -EIO; } pilmem = (((unsigned long)virt_to_bus(high_memory) >> 24) + 1) << 24;#ifdef DEBUG printk(KERN_INFO "pilchard: high_memory=0x%lx virt_to_bus(high_memory)=0x%lx pilmem=0x%lx\n", (unsigned long)high_memory, (unsigned long)virt_to_bus(high_memory), pilmem);#endif pilchard_base = ioremap(pilmem, PILCHARD_BUFZ); if (pilchard_base == (char *)NULL) { printk(KERN_INFO "pilchard: could not ioremap buffer\n"); unregister_chrdev(PILCHARD_MAJOR, "pilchard"); return -EIO; } return 0;}#ifdef MODULEint init_module(void){ printk(KERN_INFO "CUHK Pilchard driver major=%d\n", PILCHARD_MAJOR); return pilchard_init();}void cleanup_module(void){ iounmap(pilchard_base); unregister_chrdev(PILCHARD_MAJOR, "pilchard"); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -