📄 j_flash.cpp
字号:
D(printk("Flash: verify error 0x%p. "
"(flash_write() 1)\n",
programAddress));
D(printk("*programAddress = 0x%04x, "
"*theData = 0x%04x\n",
*programAddress, *theData));
} while(++retries < 2);
if(retries >= 2) {
D(printk("FATAL FLASH ERROR (1)\n"));
return -EIO; /* we failed... */
}
programAddress++;
theData++;
}
/* We should write one extra byte to the flash. */
if (odd_size) {
unsigned char last_byte[2];
int retries = 0;
last_byte[0] = *(unsigned char *)theData;
last_byte[1] = ((unsigned char *)programAddress)[1];
do {
int timeout = PROGRAM_TIMEOUT;
#ifdef IRQ_LOCKS
unsigned long flags;
save_flags(flags);
cli();
#endif
if( (unsigned long)programAddress < JFFS_ADDR_START || (unsigned long)programAddress >= JFFS_ADDR_END ){ //!!!
D(printk("flash_write: illegal3 ptr 0x%p in flash_write.\n", programAddress));
return -EINVAL;
}
flashStart[unlockAddress1] = unlockData1;
flashStart[unlockAddress2] = unlockData2;
flashStart[unlockAddress1] = programUnlockData;
*programAddress = *(flashptr) last_byte;
for(n=0; n<DELAY_90NS_LOOP; n++);
/* Wait for programming to finish */
while (timeout-- &&
(*flashStart & D6_MASK)
!= (*flashStart & D6_MASK))
/* nothing */;
#ifdef IRQ_LOCKS
restore_flags(flags);
#endif
if(!timeout)
D(printk("flash: write timeout 0x%p\n",
programAddress));
if(*programAddress
== *(flashptr)last_byte)
break;
D(printk("Flash: verify error 0x%p. "
"(flash_write() 2)\n",
programAddress));
} while(++retries < 2);
if(retries >= 2) {
D(printk("FATAL FLASH ERROR (2)\n"));
return -EIO; /* we failed... */
}
}
}
return 0;
}
int
flash_safe_write(void *_part, unsigned char *fptr,
const unsigned char *buf, int count)
{
struct flashpartition *part = (struct flashpartition *)_part;
int err;
/* Check so it's not totally out of bounds. */
if(fptr + count > part->start + part->size) {
D(printk("flash: write operation past "
"end of device (address: 0x%p, size: %d)\n",
fptr, count));
return -EINVAL;
}
FDEBUG(printk("flash_safe_write: %d bytes from 0x%p to 0x%p\n",
count, buf, fptr));
/* Actually do something, but get a lock on the chip first. */
flash_safe_acquire(part);
if ((err = flash_write(fptr, buf, count)) < 0) {
count = err;
}
/* Release the lock. */
flash_safe_release(part);
return count; /* success */
}
void *flash_getpart(kdev_t dev)
{
struct flashpartition *part;
/*if (MINOR(dev) < FLASH_MINOR) {
return 0;
}
part = &partitions[MINOR(dev) - FLASH_MINOR];*/
part = &partitions[0]; /*!!!hard code*/
if (!part->start) {
return 0;
}
return (void *)part;
}
/*自己编写: 只有一个分区JFFS_ADDR_START-JFFS_ADDR_END*/
static void flash_init_partitions(void)
{
if (chips[0].isValid) {
partitions[0].chip = &chips[0];
partitions[0].start = (unsigned char *)JFFS_ADDR_START;
partitions[0].size = JFFS_ADDR_END - JFFS_ADDR_START;
}
}
/* "Memset" a chunk of memory on the flash.
* do this by flash_write()'ing a pattern chunk.
*/
int flash_memset(unsigned char *ptr, const __u8 c, unsigned long size)
{
static unsigned char pattern[16];
int i;/*livefall@163.com 2005.01.09*/
/* fill up pattern */
for(i = 0; i < 16; i++) pattern[i] = c; /*livefall@163.com 2005.01.09*/
/* write as many 16-byte chunks as we can */
while(size >= 16) {
flash_write(ptr, pattern, 16);
ptr += 16; size -= 16;
}
/* and the rest */
if(size) flash_write(ptr, pattern, size);
return 0;
}
/* start erasing flash-memory at ptr of a certain size
* this does not wait until the erasing is done
*/
void flash_init_erase(unsigned char *ptr, unsigned int size)
{
struct flashchip *chip;
int bootSectorCounter = 0;
unsigned int erasedSize = 0;
flashptr flashStart;
#ifdef IRQ_LOCKS
unsigned long flags;
#endif
int n;
/*ptr = (unsigned char *)((unsigned long)ptr | MEM_NON_CACHEABLE);*/
chip = getchip(ptr);
flashStart = (flashptr)chip->start;
FDEBUG(safe_printk("Flash: erasing memory at 0x%p, size 0x%x.\n", ptr, size));
/* need to disable interrupts, to avoid possible delays between the
* unlocking and erase-init
*/
#ifdef IRQ_LOCKS
save_flags(flags);
cli();
#endif
/* Init erasing of the number of sectors needed */
flashStart[unlockAddress1] = unlockData1;
flashStart[unlockAddress2] = unlockData2;
flashStart[unlockAddress1] = sectorEraseUnlockData;
flashStart[unlockAddress1] = unlockData1;
flashStart[unlockAddress2] = unlockData2;
while (erasedSize < size) {
*(flashptr)ptr = sectorEraseUnlockData2;
/* make sure we erase the individual bootsectors if in that area */
/* TODO this BREAKS if we start erasing in the middle of the bootblock! */
if (ptr < chip->bootsector || ptr >= (chip->bootsector +
chip->sectorsize)) {
erasedSize += chip->sectorsize;
ptr += chip->sectorsize;
}
else {
erasedSize += chip->bootsectorsize[bootSectorCounter];
ptr += chip->bootsectorsize[bootSectorCounter++];
}
}
#ifdef IRQ_LOCKS
restore_flags(flags);
#endif
for(n=0; n<DELAY_90NS_LOOP; n++);
}
int flash_erase_region(kdev_t dev, __u32 offset, __u32 size)
{
struct flashpartition *part;
unsigned char *erase_start;
short retries = 2;
short success;
int count,blocks,i;
/*part = &partitions[minor - FLASH_MINOR];*/
part = &partitions[0];
if (!part->start) {
return -EINVAL;
}
/* Start the erasure, then sleep and wake up now and then to see
* if it's done.
*/
erase_start = part->start + offset;
flash_safe_acquire(part);
do {
flash_init_erase(erase_start, size);
count = 0; /*livefall@163.com 2005.01.09*/
blocks = size/(part->chip->sectorsize)+1; /*livefall@163.com 2005.01.09*/
while (flash_is_busy((flashptr)part->chip->start)) {
if(sys_init_done == 0){
for(i=0; i<100*FOR_1_MS; i++); /*livefall@163.com 2005.01.09*/
clearHW();
}
else NU_Sleep(10);
if(count++ > S_ERASE_TIMEOUT/100*blocks) break;
}
/*!!!0xffff->0xff*/
success = ((flashptr)erase_start)[0] == 0xff
&& ((flashptr)erase_start)[1] == 0xff
&& ((flashptr)erase_start)[2] == 0xff
&& ((flashptr)erase_start)[3] == 0xff;
if (!success) {
printk("flash: erase of region "
"[0x%p, 0x%p] failed once\n",
erase_start, erase_start + size);
}
} while (retries-- && !success);
flash_safe_release(part);
if (retries == 0 && !success) {
printk("flash: erase of region "
"[0x%p, 0x%p] totally failed\n",
erase_start, erase_start + size);
return -1;
}
return 0;
}
static int flash_is_busy(flashptr flashStart)
{
/* this should probably be protected! */
return ((*flashStart & D6_MASK) != (*flashStart & D6_MASK));
}
/* check if it's possible to erase the wanted range, and if not, return
* the range that IS erasable, or a negative error code.
*/
long flash_erasable_size(void *_part, __u32 offset, __u32 size)
{
struct flashpartition *part = (struct flashpartition *)_part;
int ssize;
if (!part->start) {
return -EINVAL;
}
/* assume that sector size for a partition is constant even
* if it spans more than one chip (you usually put the same
* type of chips in a system)
*/
ssize = part->chip->sectorsize;
if (offset % ssize) {
/* The offset is not sector size aligned. */
return -1;
}
else if (offset > part->size) {
return -2;
}
else if (offset + size > part->size) {
return -3;
}
return (size / ssize) * ssize;
}
int mgetchar();
int formatCmd(int argc,char *argv[])
{
int ret;/*livefall@163.com 2005.01.09*/
//printf("确认格式化Flash盘[y/n]?\n");
//char c = mgetchar();
//if(c == 'y' || c == 'Y'){
printf("擦除Flash存储器开始...\n");
ret = flash_erase_region(0,0,(JFFS_ADDR_END-JFFS_ADDR_START)); //!!!/*livefall@163.com 2005.01.09*/
if(ret < 0)
printf("擦除Flash存储器失败!\n");
else
printf("擦除Flash存储器成功!\n");
//}
//else{
// printf("操作取消!\n");
//}
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -