📄 flash.c
字号:
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/modversions.h>
#include <linux/timer.h>
#include <linux/mm.h>
#include <linux/param.h>
#include <linux/fs.h>
#include <linux/config.h>
#include <asm/delay.h>
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <linux/malloc.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <asm/page.h>
#include <asm/mmu.h>
#include <linux/init.h>
#define DEVICE_NAME "/dev/flash"
static short Major;
static int p;
static int rp;
unsigned long baseaddr;
int flash_erase()
{
volatile unsigned short *addr=(volatile unsigned short *)baseaddr;
unsigned long start;
*(addr+0x555)=0xaa;
*(addr+0x2aa)=0x55;
*(addr+0x555)=0x80;
*(addr+0x555)=0xaa;
*(addr+0x2aa)=0x55;
addr=(volatile unsigned short *)baseaddr;
*(addr)=0x30;
for(addr=(volatile unsigned short *)baseaddr;addr<(volatile unsigned short *)baseaddr+0x10000;addr++){
start=jiffies;
while(*addr!=0xffff){if((jiffies-start)>500 )return -1;}
}
addr=(volatile unsigned short *)baseaddr;
*addr=0xf0;
return 0;
}
int flash_write_word(volatile unsigned short * dest, unsigned short data)
{
volatile unsigned short *addr=(volatile unsigned short *)baseaddr;
unsigned long start;
if((*((volatile unsigned short*)dest) &data)!=data){return 2;}
*(addr+0x555)=0xaa;
*(addr+0x2aa)=0x55;
*(addr+0x555)=0xa0;
*((volatile unsigned short *)dest)=data;
start=jiffies;
while((*((volatile unsigned short *)dest) & 0x0080) != (data & 0x0080)){
if((jiffies-start)>500 )return -1;
}
return 0;
}
static ssize_t aaa_read(struct file *file, char *buf,size_t len, loff_t *off)
{
int err;
int readlen;
unsigned short filesize=*(volatile unsigned short *)(baseaddr+0x10000-2);
char *cp=(volatile unsigned char *)(baseaddr+rp);
if(rp+len>filesize)readlen=filesize-rp;
else readlen=len;
err=copy_to_user((void *)buf,(void *)(cp),readlen);
if(err)
return -1;
else{
rp+=readlen;
return readlen;
}
}
static ssize_t aaa_write(struct file *file, const char *buf,size_t len, loff_t *off)
{
static int b=0; //First write
int i;
int err;
static char *cp; //buffer of 64K
if(b==0){
cp=kmalloc(64*1024,GFP_KERNEL);
if(cp==NULL){
printk("Memory Alloc Fails\n");
return -1;
}
b=1;
}
err=copy_from_user((void *)&cp[p],buf,len);
if(err){
printk("Copy from user fails\n");
kfree(cp);
return -1;
}
p+=len;
if(cp[p-1]==0xFF && cp[p-2]==0xFF && cp[p-3]==0xFF && cp[p-4]==0xFF){
unsigned short *sp=(unsigned short *)cp;
flash_erase();
for(i=0;i<p/2;i++){
flash_write_word((volatile unsigned short *)(baseaddr+i*2),sp[i]);
}
if((p%2)==1)flash_write_word((volatile unsigned short *)(baseaddr+p-1),0xffff);
flash_write_word((volatile unsigned short *)(baseaddr+0x10000-2),p-4);
p=0;
b=0;
kfree(cp);
}
return 0;
}
static int aaa_ioctl(struct inode *inodp,struct file *filp,unsigned int command,unsigned long arg)
{
baseaddr=0xe0600000+command*0x10000;
if(command==30)baseaddr=0xe00f0000;
return 0;
}
static int aaa_open(struct inode * inodp,struct file* fp)
{
p=0;
rp=0;
return 0;
}
static int aaa_release(struct inode * inodp,struct file *filp)
{
return 0;
}
/**************************KERNEL RELATIVE************************/
static struct file_operations aaa_fops ={
NULL,
NULL,//llseek
aaa_read,
aaa_write,
NULL,//readdir
NULL,//poll
aaa_ioctl,
NULL,//mmap,
aaa_open,
NULL,//flush,
aaa_release,
NULL,// fsync
NULL,//fasync
NULL,//lock
NULL,//readv
NULL,//writev
NULL,//sendpage
NULL//get_unmapped_area
};
int init_module(void)
{
Major=register_chrdev(0,DEVICE_NAME,&aaa_fops);
if(Major<0)
{
printk("<1>sorry,cannot open device %s,your device number is %d\n",DEVICE_NAME,Major);
return Major;
}
printk("<1>succed in allocating a device number,which is %d\n",Major);
return 0;
}
void cleanup_module(void)
{
int ret;
ret=unregister_chrdev(Major,DEVICE_NAME);
ret<0 ? printk("Error in unregistering %s\n",DEVICE_NAME):printk("Success in unregistering %s\n",DEVICE_NAME);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -