LQ Newbie
Registered: Jan 2017
Posts: 2
Rep:
|
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
|