LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Software (https://www.linuxquestions.org/questions/linux-software-2/)
-   -   Boot partition (1st partition) on flash is not getting erased in linux? (https://www.linuxquestions.org/questions/linux-software-2/boot-partition-1st-partition-on-flash-is-not-getting-erased-in-linux-4175597870/)

MSlinux 01-20-2017 02:57 AM

Boot partition (1st partition) on flash is not getting erased in linux?
 
Hi i am using the octeon CN66XX processor, with following detail's

1) EON NOR flash EN29LV640A
CFI conformant flash (16 x 16) Size: 8 MB in 135 Sectors
AMD Standard command set

2) Linux kernel 2.6.32.27

3) processor - OCTEONCN66XX (mips)

details-

1) we are making the partition for MTD flash by command line from u-boot as following
"linux=linuxboot 0x20000000 0:3;bootoctlinux 0x20000000 coremask=$(core_mask) isolcpus=2,3,4,5,6,7 mem=0xFF800000 root=/dev/msda1 mtdparts=phys_mapped_flash:1024k(bootloader),1536k(fpga),1024k(ubootbackup) console=ttyS1,57600\0"

2) in the log the partitions is created as

Bootbus flash: Setting flash for 8MB flash at 0x1fc00000
phys_mapped_flash: Found 1 x16 devices at 0x0 in 16-bit bank
Amd/Fujitsu Extended Query Table at 0x0040
phys_mapped_flash: Swapping erase regions for broken CFI table.
number of CFI chips: 1
cfi_cmdset_0002: Disabling erase-suspend-program due to code brokenness.
3 cmdlinepart partitions found on MTD device phys_mapped_flash
Creating 3 MTD partitions on "phys_mapped_flash":
0x000000000000-0x000000100000 : "bootloader"
0x000000100000-0x000000280000 : "fpga"
0x000000280000-0x000000380000 : "ubootbackup"

3) Linux shows the partitions as
bash-4.0# cat /proc/mtd
dev: size erasesize name
mtd0: 00100000 00010000 "bootloader"
mtd1: 00180000 00010000 "fpga"
mtd2: 00100000 00010000 "ubootbackup"

4) flash_eraseall /dev/mtd2 and flash_eraseall /dev/mtd1
are getting successfully erased,

but when i erase mtd0 partition it gives the following error
bash-4.0# flash_eraseall /dev/mtd0
Erasing 64 Kibyte @ 0 -- 0 % complete.
flash_eraseall: /dev/mtd0: MTD Erase failure: Input/output error
Erasing 64 Kibyte @ f0000 -- 93 % complete.

from error log observation is that the 1st block is not getting erased and remaining blocks are getting successfully erased in /dev/mtd0.

5) I tried following method's to resolve this but not helped
a) first i tried, making all the sectors of flash to un-protect in u-boot (by making changes in u-boot). Then boot Linux and tried to flash_eraseall /dev/mtd0.
b) in file kernel_2.6/linux/arch/mips/cavium-octeon/octeon_68xx.dts. Removed the bootloader as ro (readonly)
flash0: nor@0,0 {
compatible = "cfi-flash";
reg = <0 0 0x800000>;
#address-cells = <1>;
#size-cells = <1>;

partition@0 {
label = "bootloader";
reg = <0 0x200000>;
//read-only;
};
partition@200000 {
label = "kernel";
reg = <0x200000 0x200000>;
};
partition@400000 {
label = "cramfs";
reg = <0x400000 0x3fe000>;
};
partition@7fe000 {
label = "environment";
reg = <0x7fe000 0x2000>;
//read-only;
};
};

c) I cross checked for the each partition's mtd->flag it is MTD_CAP_NORFLASH (i.e. writable)

d) i debugged the file linux/kernel_2.6/linux/drivers/mtd/chips/cfi_cmdset_0002.c. In this file
after flash_eraseall /dev/mtd0
in API - static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip, unsigned long adr, int len, void *thunk)
chip_good(map, adr, datum) is failed.

e) before calling the do_erase_oneblock i invoked the API static int do_atmel_unlock(struct map_info *map, struct flchip *chip,
unsigned long adr, int len, void *thunk);
in @@ -1683,10 +1694,16 @@ static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *ins
to unlock all the sectors in the block

e) I introduced some delay before chip_good(map, adr, datum). For giving time to reflect the erase changes.

d) the diff of cfi_cmdset_0002.c as follows

--- a/OCTEON-SDK/linux/kernel_2.6/linux/drivers/mtd/chips/cfi_cmdset_0002.c
+++ b/OCTEON-SDK/linux/kernel_2.6/linux/drivers/mtd/chips/cfi_cmdset_0002.c
@@ -74,6 +74,9 @@ static void put_chip(struct map_info *map, struct flchip *chip, unsigned long ad
static int cfi_atmel_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len);
static int cfi_atmel_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len);

+static int do_atmel_unlock(struct map_info *map, struct flchip *chip,
+ unsigned long adr, int len, void *thunk);
+
static struct mtd_chip_driver cfi_amdstd_chipdrv = {
.probe = NULL, /* Not usable directly */
.destroy = cfi_amdstd_destroy,
@@ -1596,12 +1599,14 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
unsigned long timeo = jiffies + HZ;
DECLARE_WAITQUEUE(wait, current);
int ret = 0;
-
+ printk(KERN_DEBUG "ENTERED in %s()",__func__);
adr += chip->start;

spin_lock(chip->mutex);
ret = get_chip(map, chip, adr, FL_ERASING);
if (ret) {
+
+ printk(KERN_DEBUG "get_chip failed in %s() at line= 1607",__func__);
spin_unlock(chip->mutex);
return ret;
}
@@ -1663,11 +1668,17 @@ static int __xipram do_erase_oneblock(struct map_info *map, struct flchip *chip,
/* Latency issues. Drop the lock, wait a while and retry */
UDELAY(map, chip, adr, 1000000/HZ);
}
+ /* MTD debug */
+ printk(KERN_DEBUG "delay for chip good");
+ UDELAY(map, chip, adr, 1000000/HZ);
+ UDELAY(map, chip, adr, 1000000/HZ);
/* Did we succeed? */
if (!chip_good(map, adr, map_word_ff(map))) {
/* reset on all failures. */
map_write( map, CMD(0xF0), chip->start );
/* FIXME - should have reset delay before continuing */
+
+ printk(KERN_DEBUG "chip_good failed in %s() at line=1675",__func__);

ret = -EIO;
}
@@ -1683,10 +1694,16 @@ static int cfi_amdstd_erase_varsize(struct mtd_info *mtd, struct erase_info *ins
{
unsigned long ofs, len;
int ret;
-
+ printk(KERN_ALERT "Entered in cfi_amdstd_erase_varsize\n");
ofs = instr->addr;
len = instr->len;
-
+
+ ret = cfi_varsize_frob(mtd, do_atmel_unlock, ofs, len, NULL);
+ if(ret)
+ {
+ printk(KERN_ALERT "Failed to do_atmel_unlock with ret = %d \n",ret);
+ }
+ printk(KERN_ALERT "Success to do_atmel_unlock with ret = %d \n",ret);
ret = cfi_varsize_frob(mtd, do_erase_oneblock, ofs, len, NULL);
if (ret)
return ret;
@@ -1765,11 +1782,18 @@ static int do_atmel_unlock(struct map_info *map, struct flchip *chip,
spin_lock(chip->mutex);
ret = get_chip(map, chip, adr + chip->start, FL_UNLOCKING);
if (ret)
+ {
+ printk(" %s(): get_chip failed ",
+ __func__);
+
goto out_unlock;
- chip->state = FL_UNLOCKING;
+ }
+ chip->state = FL_UNLOCKING;

DEBUG(MTD_DEBUG_LEVEL3, "MTD %s(): LOCK 0x%08lx len %d\n",
__func__, adr, len);
+ printk("MTD %s(): LOCK 0x%08lx len %d\n",
+ __func__, adr, len);

cfi_send_gen_cmd(0xAA, cfi->addr_unlock1, chip->start, map, cfi,
cfi->device_type, NULL);

Please help me to understand this problem and to resolve
Thank you,
MSlinux

Brains 01-20-2017 03:24 AM

Very easy fix, just refer to the EN29LV640A product data sheet, google that and you'll get lots of links.
Below is from page 18
Quote:


This Data Sheet may be revised by subsequent versions ©2004 Eon Silicon Solution, Inc.,
EN29LV640A
Rev. C, Issue Date: 2010/11/15
Write Protect / Accelerated Program (WP# / ACC)

The WP#/ACC pin provides two functions. The Write Protect (WP#) function provides a hardware method of protecting the outermost two 8K-byte Boot Sector. The ACC function allows faster manufacturing throughput at the factory, using an external high voltage. When WP#/ACC is Low, the device protects the outermost two 8K-byte Boot Sector; no matter the sectors are protected or unprotected using the method described in “Sector/Sector Group Protection & Chip Unprotection”, Program and Erase operations in these sectors are ignored. When WP#/ACC is High, the device reverts to the previous protection status of the outermost two 8Kbyte boot sector. Program and Erase operations can now modify the data in the two outermost 8K-byte Boot Sector unless the sector is protected using Sector Protection.
When WP#/ACC is raised to VHH the memory automatically enters the Accelerated Program mode, this mode permit the system to skip the normal command unlock sequences and program byte/word locations directly to reduces the time required for program operation. When WP#/ACC returns to VIH or VIL, normal operation resumes. The transitions from VIH or VIL to VHH and from VHH to VIH or VIL must be slower than tBVHHB, see Figure 11.

MSlinux 01-25-2017 12:51 AM

Hi Brains,
First thank you very much for your reply, in my board the Write Protect / Accelerated Program (WP# / ACC) pin is always connected to VCC. Can there any other way

Thank you,
MS Linux


All times are GMT -5. The time now is 01:24 PM.