Ich beschäftige mich nun auch schon ein gewisse Zeit mit der dbox und mir ist aufgefallen, daß hin und wieder nach der Erstellung von images - das gilt sowohl für die alten cramfs als auch für die neuen squashfs images - die Box nicht mehr bootet.
Es kommt dann im LCD die Meldung 'Kein System' und im log der Hinweis 'superblock not ok: invalid argument'.
Anfänglich habe ich gedacht, na gut da ist beim flashen etwas schief gelaufen und habe weiter probiert bzw. am image etwas geändert bis es irgendwann wieder ging. Das ist natürlich auf die Dauer etwas unbefriedigend und so habe ich mich mal daran gemacht, die Sache genauer zu analysieren. Nach vielen Versuchen habe ich jetzt eine Systematik entdeckt, die für diesen Fehler verantwortlich ist:
Es ist offensichtlich so, das der BR bootloader nach dem Einschalten der box den flash komplett scanned. Wird dabei ein zusammenhängender Block im flash endeckt, der größer als 5767168 bytes (entspricht 44 * 131072 bytes) ist, kommt es immer dann zu diesem Fehler wenn der Quotient aus realer Partitionsgröße / 131072 gerade vor dem Komma ist.
Anders ausgedrückt bedeutet das:
Der Fehler tritt nie auf, solange die root Partition real - ohne padding - kleiner als 44 * 128 KB ist. Oberhalb dieses Werts tritt der Fehler immer dann nicht auf, wenn die reale Größe der root Partition / 131072 eine ungerade Zahl vor dem Komma ergibt.
Danach gibt es zwei Lösungsansätze für dieses Problem:
Sollten 5767168 bytes für das root nicht ausreichen teilt man das root auf zwei Partionen auf oder man stellt durch ein dummy file sicher, daß bei einer Partition der Ouotient vor dem Komma immer eine ungerade Zahl ergibt.
Im Zuge dieser Tests habe ich auch noch eine Ungereimtheit in den u-boot sourcen bei der Zuordnung/offset Ermittlung der verschiedenen flash Typen festgestellt:
Code: Alles auswählen
--- flash.c.old 2005-02-04 09:31:48.000000000 +0100
+++ flash.c 2005-02-07 13:01:41.000000000 +0100
@@ -34,7 +34,6 @@
*/
#ifndef CONFIG_DBOX2_FLASH_FAKE
static ulong flash_get_size (vu_long *addr, flash_info_t *info);
-static void flash_get_offsets (ulong base, flash_info_t *info);
static void flash_get_protect (flash_info_t *info);
static int write_word (flash_info_t *info, ulong dest, ulong data);
#endif /* CONFIG_DBOX2_FLASH_FAKE */
@@ -100,11 +99,10 @@
flash_info[i].flash_id = FLASH_UNKNOWN;
flash_info[0].portwidth = FLASH_CFI_32BIT;
-
size = flash_get_size ((vu_long *) FLASH_BASE_PRELIM, &flash_info[0]);
if (flash_info[0].flash_id == FLASH_UNKNOWN)
- {
+ {
flash_info[0].portwidth = FLASH_CFI_16BIT;
size = flash_get_size ((vu_long *) FLASH_BASE_PRELIM, &flash_info[0]);
}
@@ -115,8 +113,6 @@
return 0;
}
- flash_get_offsets (FLASH_BASE_PRELIM, &flash_info[0]);
-
#ifdef CFG_FLASH_PROTECTION
flash_get_protect (&flash_info[0]);
#endif
@@ -138,10 +134,13 @@
volatile immap_t *immap = (immap_t *) CFG_IMMR;
volatile memctl8xx_t *memctl = &immap->im_memctl;
ulong value;
+ ulong base = (ulong)addr;
+ short i;
flash_put (info, addr, 0x0555, 0x00AA00AA);
flash_put (info, addr, 0x02AA, 0x00550055);
flash_put (info, addr, 0x0555, 0x00900090);
+
value = flash_get (info, addr, 0);
if (info->portwidth == FLASH_CFI_16BIT)
@@ -176,31 +175,32 @@
switch (value)
{
case AMD_ID_DL323B:
- info->flash_id |= FLASH_AMDL323B;
+ info->flash_id += FLASH_AMDL323B;
info->sector_count = 63 + 8;
info->size = 0x00800000;
break;
case STM_ID_28W320CB:
- info->flash_id |= FLASH_BTYPE;
- info->flash_id |= FLASH_STM320CB;
+ info->flash_id += FLASH_STM320CB;
info->sector_count = 63 + 8;
info->size = 0x00800000;
break;
case INTEL_ID_28F320C3B:
- info->flash_id |= FLASH_BTYPE;
+ info->flash_id += FLASH_INTEL320B;
+ info->sector_count = 63 + 8;
+ info->size = 0x00800000;
+ break;
case INTEL_ID_28F320C3T:
- info->flash_id |= FLASH_INTEL320T;
+ info->flash_id += FLASH_INTEL320T;
info->sector_count = 63 + 8;
info->size = 0x00800000;
break;
case INTEL_ID_28F640J3A:
- info->flash_id |= FLASH_28F640J3A;
+ info->flash_id += FLASH_28F640J3A;
info->sector_count = 64;
info->size = 0x00800000;
break;
case INTEL_ID_28F640C3B:
- info->flash_id |= FLASH_BTYPE;
- info->flash_id |= FLASH_28F640C3B;
+ info->flash_id += FLASH_28F640C3B;
info->sector_count = 127 + 8;
info->size = 0x01000000;
memctl->memc_or0 = memctl->memc_or0 & 0xff00ffff; // reset mask in OR0 to 16MB
@@ -210,37 +210,27 @@
return 0;
}
- flash_put (info, addr, 0, 0x00F000F0);
- return info -> size;
-}
-
-static void flash_get_offsets (ulong base, flash_info_t *info)
-{
- int i;
-
- if (info->flash_id & FLASH_BTYPE)
- {
- /* set sector offsets for bottom boot block type */
- if ((info->flash_id & FLASH_TYPEMASK) != FLASH_28F640J3A)
- {
- info->start[0] = base;
- info->start[1] = base + 0x4000;
- info->start[2] = base + 0x8000;
- info->start[3] = base + 0xC000;
- info->start[4] = base + 0x10000;
- info->start[5] = base + 0x14000;
- info->start[6] = base + 0x18000;
- info->start[7] = base + 0x1C000;
- for (i = 8; i < info->sector_count; i++)
- info->start[i] = base + ((i - 7) * 0x20000);
- }
- else
- for (i = 0; i < info->sector_count; i++)
- info->start[i] = base + (i * 0x20000);
- }
- else
+ /* set up sector start address table */
+ switch (value)
{
- /* set sector offsets for top boot block type */
+ case AMD_ID_DL323B:
+ case STM_ID_28W320CB:
+ case INTEL_ID_28F320C3B:
+ case INTEL_ID_28F640C3B:
+ /* set sector offsets for bottom boot block type */
+ info->start[0] = base;
+ info->start[1] = base + 0x4000;
+ info->start[2] = base + 0x8000;
+ info->start[3] = base + 0xC000;
+ info->start[4] = base + 0x10000;
+ info->start[5] = base + 0x14000;
+ info->start[6] = base + 0x18000;
+ info->start[7] = base + 0x1C000;
+ for (i = 8; i < info->sector_count; i++)
+ info->start[i] = base + ((i - 7) * 0x20000);
+ break;
+ case INTEL_ID_28F320C3T:
+ /* set sector offsets for top boot block type */
i = info->sector_count - 1;
info->start[i--] = base + info->size - 0x4000;
info->start[i--] = base + info->size - 0x8000;
@@ -251,7 +241,19 @@
info->start[i--] = base + info->size - 0x1C000;
for (; i >= 0; i--)
info->start[i] = base + info->size - ((i - 6) * 0x20000);
+ break;
+ case INTEL_ID_28F640J3A:
+ for (i = 0; i < info->sector_count; i++)
+ info->start[i] = base + (i * 0x20000);
+ break;
+
+ default:
+ return 0;
+ break;
}
+
+ flash_put (info, addr, 0, 0x00F000F0);
+ return info -> size;
}
#ifdef CFG_FLASH_PROTECTION
@@ -311,7 +313,7 @@
default:
printf ("Unknown Vendor Unknown Chip Type\n");
}
-#else /* CONFIG_DBOX2_FLASH_FAKE */
+#else /* CONFIG_DBOX2_FLASH_FAKE */
switch (info->flash_id & FLASH_VENDMASK)
{
case FLASH_MAN_AMD:
@@ -365,7 +367,7 @@
default:
printf ("\n");
}
-#endif /* CONFIG_DBOX2_FLASH_FAKE */
+#endif /* CONFIG_DBOX2_FLASH_FAKE */
printf ("\n Size: %ld kB in %d Sectors\n",
info->size >> 10, info->sector_count);
Viele Grüße,
e46ti