📄 staticram.c
字号:
/* driver/char/staticram.c
*
* This file provide IO reading and writing from user space.
* Pls create some device file in diretory /dev/ppcflash whose major is 218.
* This driver support 0-255 devices. In user space user can read and write
* IO through open and ioctl function provided by glibc.
*
* Sun Qigang 2007-4-1
*/
#include <linux/fs.h>
#include <linux/iobuf.h>
#include <linux/major.h>
#include <linux/blkdev.h>
#include <linux/capability.h>
#include <linux/smp_lock.h>
#include <asm/uaccess.h>
#include <asm/hardware.h>
#include <asm/arch/AT91RM9200.h>
#include <asm/io.h>
#include <linux/vmalloc.h>
#include <linux/module.h>#include <linux/mm.h>#include <linux/wrapper.h> /* mem_map_(un)reserve */#include <linux/slab.h> /* kmalloc and kfree */
#define STATICRAM_MAJOR 226
#define STATICRAM_ADDR 0x80000000#define STATICRAM_SIZE 0x80000
typedef char staticram_device_t;
static devfs_handle_t staticram_devfs_dir;
static staticram_device_t staticram_devices[256];
static long v_addr = 0; /* read and write address */
static int staticram_open(struct inode *, struct file *);
static int staticram_release(struct inode *, struct file *);
static int staticram_ctl_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
static ssize_t staticram_read(struct file * file, char * buf, size_t count, loff_t *ppos);static ssize_t staticram_write(struct file * file, const char * buf, size_t count, loff_t *ppos);static int staticram_mmap(struct file *file, struct vm_area_struct *vma);
//#################################################################
static struct file_operations staticram_ctl_fops = {
open: staticram_open,
read: staticram_read,
write: staticram_write, mmap: staticram_mmap,
ioctl: staticram_ctl_ioctl, release: staticram_release,
};
static int staticram_open(struct inode *inode, struct file *filp)
{
int minor;
minor = MINOR(inode->i_rdev);
printk("staticram open ok\n");
staticram_devices[minor]++;
return 0;
}
static ssize_t staticram_read(struct file * file, char * buf, size_t count, loff_t *ppos)
{ ssize_t read; unsigned char *staticram_read_val; int i; if (count > 0x80000) count = 0x80000; read = 0; (void *)v_addr = ioremap(STATICRAM_ADDR, 0x80000); staticram_read_val = (char *)kmalloc(count, GFP_KERNEL); for(i=0; i<count; i++) { *(staticram_read_val + i) = (*(volatile unsigned int *)(v_addr + i)); printk(":::0x%01x \n",*(staticram_read_val + i)); } // if (copy_to_user(buf, __va(p), count)) if (copy_to_user(buf, staticram_read_val, count)) return -EFAULT; read += count; kfree(staticram_read_val); iounmap((void *)v_addr); return read;}
static ssize_t staticram_write(struct file * file, const char * buf, size_t count, loff_t *ppos)
{
ssize_t written; unsigned char *staticram_write_val; int i; if (count > 0x80000) count = 0x80000; written = 0; staticram_write_val = (char *)kmalloc(count, GFP_KERNEL); if (copy_from_user(staticram_write_val, (void *)buf, count)) return -EFAULT; (void *)v_addr = ioremap(STATICRAM_ADDR, 0x80000); for(i=0; i<count; i++) { *(volatile unsigned int *)(v_addr + i) = *(staticram_write_val + i); // printk("::::::0x%01x \n",*(staticram_write_val + i)); } written += count; kfree(staticram_write_val); iounmap((void *)v_addr); return written;}
static int staticram_release(struct inode *inode, struct file *filp)
{
int minor;
minor = MINOR(inode->i_rdev);
if (staticram_devices[minor])
staticram_devices[minor]--;
printk("staticram release ok\n");
return 0;
}
static int staticram_mmap(struct file *file, struct vm_area_struct *vma)
{ unsigned long off = vma->vm_pgoff << PAGE_SHIFT; unsigned long physical = STATICRAM_ADDR + off; unsigned long vsize = vma->vm_end - vma->vm_start; unsigned long psize = STATICRAM_SIZE - off; if (vsize > psize) { printk("size too big\n"); return -EINVAL; //spans too high } vma->vm_flags |= VM_IO | VM_RESERVED | VM_LOCKED; vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); remap_page_range(vma->vm_start, physical, vsize, vma->vm_page_prot); return 0;}
static int staticram_ctl_ioctl(struct inode *inode,
struct file *flip,
unsigned int command,
unsigned long arg)
{
int err = 0;
#if 0
switch (command) {
case ADDR:
return 0;
case WRITE:
return 0;
case READ:
return 0;
default:
err = -EINVAL;
}
#endif
return err;
}
static int __init staticram_init (void)
{
// register_chrdev(STATICRAM_MAJOR, "staticram", &staticram_ctl_fops);
//############################################################################
//
//The" devfs"is very important!!!register file command
//note:devfs and register ;but ,devfs= register+mknod
//Here isn't use :mknod /dev/staticram c 226 0 /* Setup CS7 */ AT91_SYS->PIOC_PDR |= AT91C_PIO_PC13; AT91_SYS->PIOC_ASR |= AT91C_PC13_NCS7; // Initialization of the Static Memory Controller for Chip Select 7 (0x00005083)--(0x0000428a) /* AT91_SYS->EBI_SMC2_CSR[7] = (AT91C_SMC2_NWS & 0x04) | AT91C_SMC2_WSEN | * (AT91C_SMC2_TDF & 0x000) | AT91C_SMC2_DBW_8 | (AT91C_SMC2_RWSETUP & 0x01000000) * | (AT91C_SMC2_RWHOLD & 0x10000000); */ AT91_SYS->EBI_SMC2_CSR[7] = (AT91C_SMC2_NWS & 0x0a) | AT91C_SMC2_WSEN | (AT91C_SMC2_TDF & 0x200) | AT91C_SMC2_DBW_8; staticram_devfs_dir= devfs_register(NULL,"staticram",DEVFS_FL_DEFAULT,STATICRAM_MAJOR,
0, S_IFCHR |S_IRUSR |S_IWUSR |S_IRGRP |S_IWGRP,
&staticram_ctl_fops, NULL);
printk ("staticram driver installed OK. \n");
return 0;
}
static void __exit staticram_exit(void)
{ //iounmap((void *)v_addr);
devfs_unregister(staticram_devfs_dir);
printk("staticram driver uninstalled OK. \n");
}
module_init(staticram_init);
module_exit(staticram_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("sqg");
MODULE_DESCRIPTION("staticram Driver for rm9200");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -