📄 nvram.c
字号:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/hardware.h>
#include <asm/mach-types.h>
#include <linux/version.h>
#include <asm-arm/arch-iop33x/iop33x.h>
unsigned char *nvram_remap_address;
#define nvram_NAME "nvram_driver"
#define nvram_MAJOR 127
#define nvram_SIZE 0x8000
typedef struct{
int openflag;
char buf[nvram_SIZE];
}nvram_dev;
static nvram_dev df_dev;
static int
nvram_open(struct inode *inode,struct file *filp);
static int
nvram_release(struct inode *inode,struct file *filp);
static loff_t
nvram_llseek(struct file *file, loff_t offset, int origin);
static ssize_t
read_nvram(struct file *file, char __user *buf, size_t count, loff_t *ppos);
static ssize_t
write_nvram(struct file *file, const char __user *buf, size_t count, loff_t *ppos);
static int
nvram_init(void);
static void
nvram_exit(void);
struct file_operations nvram_fops = {
owner: THIS_MODULE,
llseek: nvram_llseek,
read: read_nvram,
write: write_nvram,
open: nvram_open,
release: nvram_release,
};
static int
nvram_open(struct inode *inode,struct file *filp) /* open device */
{
nvram_dev *dev;
dev=&df_dev;
nvram_remap_address =ioremap(0xce870000, 0x8000); if(dev->openflag !=0)
{
return -EBUSY;
}
dev->openflag =1;
filp->private_data =dev;
// MOD_INC_USE_COUNT;
return 0;
}
static int
nvram_release(struct inode *inode,struct file *filp) /* close device */
{
nvram_dev *dev=(nvram_dev *)filp->private_data;
// MOD_DEC_USE_COUNT;
dev->openflag = 0; return 0; }
static int __init nvram_init(void)
{
int result = register_chrdev(nvram_MAJOR,nvram_NAME,&nvram_fops);
if(result<0)
{
printk(KERN_ALERT"nvram: can't get major %d\n",nvram_MAJOR);
return result;
}
return 0;
}
static void __exit nvram_exit(void)
{
unregister_chrdev(nvram_MAJOR,nvram_NAME);
iounmap((void *)nvram_remap_address);
}
static unsigned char read_byte_nvram(int addr)
{
return inb(nvram_remap_address + addr + 1);
}
static void write_byte_nvram(unsigned char val, int addr)
{
outb(val, nvram_remap_address + addr + 1);
}
static loff_t nvram_llseek(struct file *file, loff_t offset, int origin)
{
lock_kernel();
switch (origin) {
case 1:
offset += file->f_pos;
break;
case 2:
offset += 0x8000 - 1;
break;
}
if (offset < 0) {
unlock_kernel();
return -EINVAL;
}
file->f_pos = offset;
unlock_kernel();
return file->f_pos;
}
static ssize_t read_nvram(struct file *file, char __user *buf, size_t count, loff_t *ppos)
{
unsigned int i; char __user *p = buf;
if (!access_ok(VERIFY_WRITE, buf, count))
return -EFAULT;
if (*ppos >= 0x8000 - 1)
return 0;
for (i = *ppos; count > 0 && i < 0x8000 - 1; ++i, ++p, --count)
if (__put_user(read_byte_nvram(i), p))
return -EFAULT;
*ppos = i;
return p - buf;
}
static ssize_t write_nvram(struct file *file, const char *buf, size_t count, loff_t *ppos)
{
unsigned int i;
nvram_dev *dev=(nvram_dev *)filp->private_data;
if(count==0)
return 0; if(copy_from_user(dev->buf,buf,count)) { printk(KERN_ALERT"copy from user erro!!\n"); return -EFAULT; } // const char *p = buf;
unsigned char c;
// if (!access_ok(VERIFY_READ, buf, count))
// return -EFAULT;
if (*ppos >= 0x8000 - 1)
return 0;
// for (i = *ppos; count > 0 && i < 0x8000 - 1; ++i, ++p, --count) {
// if (__get_user(c, p))
// return -EFAULT;
for (i=0;i<count;i++)
{
write_byte_nvram(dev->buf[i],i)
}
}
}
module_init(nvram_init);
module_exit(nvram_exit);
//MODULE_ALIAS("nvram");
//MODULE_DESCRIPTION("nvram Driver For EM104-MINI2410");
//MODULE_LICENSE("GPL");
//MODULE_AUTHOR("jjj. <jjjstudio@163.com>");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -