### FS LOAD ERROR<0> for vmlinuz!

Diskussionen um Bootloader, Kernel, Busybox
e46ti
Interessierter
Interessierter
Beiträge: 74
Registriert: Montag 14. Februar 2005, 10:10

### FS LOAD ERROR<0> for vmlinuz!

Beitrag von e46ti »

@Hallo,

vielleicht gibt es ja hier auch den einen oder anderen, der nach dem flashen eines neuen squashfs images, folgendes auf der Konsole zu sehen bekam:

Code: Alles auswählen

U-Boot 1.1.2 (????) (Mar  8 2005 - 16:59:39) 

CPU:   PPC823ZTnnB2 at 65.900 MHz: 2 kB I-Cache 1 kB D-Cache 
Board: DBOX2, Philips, BMon V1.0 
       Watchdog enabled 
I2C:   ready 
DRAM:  32 MB 
FLASH:  8 MB 
Scanning JFFS2 FS: .. done. 
FB:    ready 
LCD:   ready 
In:    serial 
Out:   serial 
Err:   serial 
Net:   SCC ETHERNET 
Hit any key to stop autoboot:  0 
### FS (squashfs) loading 'vmlinuz' to 0x100000 
### FS LOAD ERROR<0> for vmlinuz! 
............................................................... 
Un-Protected 63 sectors 
## Booting image at 00100000 ... 
Bad Magic Number 
=>
Außer meiner Sicht gibt es zwei Möglichkeiten, diesen Fehler zu vermeiden:

Die Datei vmlinuz in amlinuz umbenennen und diesen Eintrag auch in cmd_fs.c entsprechend ändern :o

oder :D

Code: Alles auswählen

--- squashfs.c.org	2005-03-12 03:45:52.000000000 +0100
+++ squashfs.c	2005-03-12 03:15:24.000000000 +0100
@@ -61,6 +61,7 @@
 int read_fragment_table(struct part_info *info, squashfs_super_block *sBlk, squashfs_fragment_entry **fragment_table);
 squashfs_fragment_entry *frag_table;
 
+unsigned int uncompr_size;
 
 int squashfs_read_super (struct part_info *info, squashfs_super_block *super)
 {
@@ -124,14 +125,13 @@
 	int offset;
 	unsigned char check_data;
 	short int compressed;
-	unsigned int length;
 
 	/* if this is a meta data block, the size is in the block's first 2 bytes */
 	if (!bytecount)
 	{
 		read_bytes(info, start, 2, (char *)&c_byte);
 		compressed = SQUASHFS_COMPRESSED(c_byte);
-		length = SQUASHFS_COMPRESSED_SIZE(c_byte);
+		uncompr_size = SQUASHFS_COMPRESSED_SIZE(c_byte);
 		offset = 2;
 		/* check_data needs one byte per block */
 		if(SQUASHFS_CHECK_DATA(sBlk->flags))
@@ -145,18 +145,19 @@
 	else
 	{
 		compressed = SQUASHFS_COMPRESSED_BLOCK(*bytecount);
-		length = SQUASHFS_COMPRESSED_SIZE_BLOCK(*bytecount);
-		offset = frag_size ? frag_offset : 0;
+		uncompr_size = SQUASHFS_COMPRESSED_SIZE_BLOCK(*bytecount);
+		offset = 0;
 	}
 
 	/* handle compressed block */
 	if(compressed) 
 	{
-		unsigned char buffer[SQUASHFS_FILE_SIZE];
+		unsigned char buffer[sBlk->block_size];
+	
 		/* if this is a fragment, we need a temporary decompression buffer */
-		unsigned char uncompressed_buffer[SQUASHFS_FILE_SIZE];
+		unsigned char uncompressed_buffer[sBlk->block_size];
 		int res;
-		long bytes = SQUASHFS_FILE_SIZE;
+		long bytes = sBlk->block_size;		
 
 		TRACE("compressed block @ 0x%x, compressed size %d\n", start, uncompr_size);
 		read_bytes(info, start + offset, uncompr_size, buffer);
@@ -174,26 +175,27 @@
 		/* if this is a fragment, copy only that part of the block */
 		if (frag_size)
 		{
-			memcpy(block, uncompressed_buffer, frag_size);
+			memcpy(block, uncompressed_buffer + frag_offset, frag_size);
 		}
 		/* advance buffer pointer if requested */
 		if(next && !frag_size)
 		{
-			*next = start + offset + length;
+			*next = start + offset + uncompr_size;
 		}
+	
 		return frag_size ? frag_size : res;
 	} 
 	/* handle uncompressed block */
 	else 
 	{
-		TRACE("uncompressed block @ 0x%x, size %d\n", start, frag_size ? frag_size : length);
+		TRACE("uncompressed block @ 0x%x, size %d\n", start, frag_size ? frag_size : uncompr_size);
 		/* just copy the block (or a fragment of it) from partition to destination buffer */
-		read_bytes(info, start + offset, frag_size ? frag_size : length, block);
+		read_bytes(info, start + offset, frag_size ? frag_size : uncompr_size, block);
 		if(next && !frag_size)
 		{
-			*next = start + offset + length;
+			*next = start + offset + uncompr_size;
 		}
-		return frag_size ? frag_size : length;
+		return frag_size ? frag_size : uncompr_size;
 	}
 }
 
@@ -225,50 +227,86 @@
 	return 1;
 }
 
-
 /* reads directory header(s) and entries and looks for a given name. Returns the inode if found */
 static int squashfs_readdir(struct part_info *info, squashfs_dir_inode_header *diri,
-								char *filename, squashfs_inode *inode, squashfs_super_block *sBlk)
+			char *filename, squashfs_inode *inode, squashfs_super_block *sBlk)
 {
 	squashfs_dir_header *dirh;
 	char buffer[sizeof(squashfs_dir_entry) + SQUASHFS_NAME_LEN + 1];
 	squashfs_dir_entry *dire = (squashfs_dir_entry *) buffer;
-	int dir_count;
+	int dir_count, block_size;
 	unsigned int initial_offset = diri->offset;
+
 	int bytes = 0;
+	int tmpbytes = 0;
 
 	unsigned char *dirblock = malloc (SQUASHFS_METADATA_SIZE);
-	unsigned int start = sBlk->directory_table_start + diri->start_block;
+	unsigned char *tmpblock = malloc (SQUASHFS_METADATA_SIZE);
+	
+	unsigned int start = sBlk->directory_table_start + diri->start_block - 1;
 	unsigned int dirs=0;
 
+	TRACE("initial_offset 0x%x, table_start 0x%x\n", diri->offset, sBlk->directory_table_start - 1);
+	
 	if (!dirblock)
 	{
 		ERROR ("squashfs_readdir: out of memory\n");
 		return 0;
 	}
-	if (!read_block (info, start, NULL, dirblock, sBlk, NULL, 0, 0))
+	
+	block_size = read_block (info, start, NULL, dirblock, sBlk, NULL, 0, 0);
+	
+	if (!block_size)
 	{
 		ERROR ("squashfs_readdir: read_block\n");
 		free (dirblock);
 		return 0;
 	}
+
+	memcpy(tmpblock, dirblock + initial_offset, block_size - initial_offset);
+
+	/* check wether all entries are in the same block */
+	tmpbytes = diri->file_size - (block_size - initial_offset);
+	if(tmpbytes > 0)
+	{
+		/* check_data needs one byte more per block */
+		if(SQUASHFS_CHECK_DATA(sBlk->flags))
+		{
+		    block_size = read_block (info, start + uncompr_size + 3, NULL, tmpblock + block_size - initial_offset, sBlk, NULL, 0 , 0);
+		}
+		else
+		{
+		    block_size = read_block (info, start + uncompr_size + 2, NULL, tmpblock + block_size - initial_offset, sBlk, NULL, 0 , 0);
+		}    
+		
+		if (!block_size)
+		{
+		    ERROR ("squashfs_readdir: read_block\n");
+		    free (tmpblock);
+		    return 0;
+		}
+	}	
+
 	while (bytes<diri->file_size)
 	{
-		dirh = (squashfs_dir_header*)(dirblock + initial_offset + bytes);
+ 		dirh = (squashfs_dir_header*)(tmpblock + bytes);
 		dir_count = dirh->count + 1;
 		dirs+=dir_count;
 		bytes += sizeof(squashfs_dir_header);
+
+		TRACE("dir_count: %d file_size: %d bytes: %d\n", dir_count, diri->file_size, bytes);
+
 		while(dir_count--) 
 		{
-			memcpy((void *)dire, dirblock + initial_offset + bytes, sizeof(dire));
+			memcpy((void *)dire, tmpblock + bytes, sizeof(dire));
 			bytes += sizeof(*dire);
-			memcpy((void *)dire->name, dirblock + initial_offset + bytes, dire->size + 1);
+			memcpy((void *)dire->name, tmpblock + bytes, dire->size + 1);
 			dire->name[dire->size + 1] = '\0';
 			if (!filename)
 			{
 				printf ("entry is %s\n", dire->name);
 			}
-			else if (filename && inode && !strncmp(dire->name,filename,dire->size+1))
+			if (filename && inode && !strncmp(dire->name,filename,dire->size+1))
 			{
 				TRACE ("entry found: %s\n", dire->name);
 				*inode = SQUASHFS_MKINODE(dirh->start_block,dire->offset);
@@ -278,11 +316,13 @@
 			bytes += dire->size + 1;
 		}
 	}
+
 	if (!filename)
 	{
 		printf ("%d directory entries\n", dirs);
 	}
 	free (dirblock);
+	free (tmpblock);
 	return 0;
 }

@@ -393,6 +436,9 @@
 				case SQUASHFS_SYMLINK_TYPE:
 					/* resolve */
 					break;
+				case SQUASHFS_LDIR_TYPE:
+					/* resolve */
+					break;
 				default:
 					break;
 				}
@@ -410,21 +456,17 @@
 					int frag_bytes;
 					unsigned int *blocklist;
 					unsigned int bytes = 0;
-					int start;
+					
 					squashfs_reg_inode_header dirreg;
-
-					memcpy (&dirreg,blockbuffer + cur_offset,sizeof(dirreg));
+					memcpy (&dirreg,blockbuffer + cur_offset, sizeof(dirreg));
 					
 					blocks = dirreg.fragment == SQUASHFS_INVALID_BLK
 									? (dirreg.file_size + sBlk.block_size - 1) >> sBlk.block_log
 									: dirreg.file_size >> sBlk.block_log;
 					frag_bytes = dirreg.fragment == SQUASHFS_INVALID_BLK ? 0 : dirreg.file_size % sBlk.block_size;
-					start = dirreg.start_block;
-					
-					TRACE("regular file, size %d, blocks %d\n", dirreg.file_size, blocks);
-					TRACE("frag_bytes %d, start_block 0x%x\n", frag_bytes, start);
 
-					cur_offset += sizeof(dirreg);
+					TRACE("regular file, size %d, blocks %d, start_block 0x%x\n", dirreg.file_size, blocks, dirreg.start_block);
+					
 					blocklist=malloc (blocks*sizeof(unsigned int));
 					if (!blocklist)
 					{
@@ -432,6 +474,7 @@
 						free (blockbuffer);
 						return 0;
 					}
+					cur_offset += sizeof(dirreg);
 					memcpy (blocklist,blockbuffer+cur_offset,blocks*sizeof(unsigned int));
 					cur_ptr = dirreg.start_block;
 					for (i=0;i<blocks;i++)
@@ -441,10 +484,13 @@
 					}
 					if (frag_bytes)
 					{
-						squashfs_fragment_entry *frag_entry = frag_table + dirreg.fragment;
-						TRACE("%d bytes in fragment %d, offset %d\n", frag_bytes, dirreg.fragment, dirreg.offset);
+	    					squashfs_fragment_entry *frag_entry = frag_table + dirreg.fragment;
+						
+						TRACE("%d bytes in fragment %d, offset %d\n",
+						 frag_bytes, dirreg.fragment, dirreg.offset);
+
 						TRACE("fragment %d, start_block=0x%x, size=%d\n",
-							dirreg.fragment, frag_entry->start_block, SQUASHFS_COMPRESSED_SIZE_BLOCK(frag_entry->size));
+						 dirreg.fragment, frag_entry->start_block, SQUASHFS_COMPRESSED_SIZE_BLOCK(frag_entry->size));
 						bytes += read_block(info, frag_entry->start_block, NULL, (unsigned char*)(loadoffset+bytes), &sBlk, &(frag_entry->size), dirreg.offset, frag_bytes);
 					}
 					*size=bytes;
@@ -458,8 +504,15 @@
 					return 0;
 					break;
 				}
+				case SQUASHFS_LDIR_TYPE:
+				{
+					printf ("loading ldirs is not supported\n");
+					free (blockbuffer);
+					return 0;
+					break;
 				}
 			}
+			}
 			parsed=1;
 			break;
 		}
e46ti

PS: Das obige diff behebt auch noch andere Probleme... :wink:
doktorknow
Interessierter
Interessierter
Beiträge: 99
Registriert: Dienstag 27. November 2001, 00:00

Beitrag von doktorknow »

kannst Du bitte noch kurz sagen in welchem Ordner das Diff ausgeführt wird?

Danke im Voraus!
MfG
doktorknow
e46ti
Interessierter
Interessierter
Beiträge: 74
Registriert: Montag 14. Februar 2005, 10:10

Beitrag von e46ti »

doktorknow hat geschrieben:kannst Du bitte noch kurz sagen in welchem Ordner das Diff ausgeführt wird?

Danke im Voraus!
MfG
doktorknow
squashfs.c findest Du hier:

tuxbox-cvs/boot/u-boot-tuxbox/fs/squashfs

Gruß
e46ti

Tip: Änderungen an den u-boot sourcen nur dann selbst vornehmen, wenn einem klar ist, was man da macht. Für etwaige Briefbeschwerer kann ich keine Verantwortung übernehmen :wink:
DieMade
Oberlamer, Administrator & Supernanny
Beiträge: 10532
Registriert: Samstag 13. Juli 2002, 10:49

Beitrag von DieMade »

PS: Das obige diff behebt auch noch andere Probleme... ;)
Die da wären?
There are 10 types of people in the world: those who know binary and those who don't
e46ti
Interessierter
Interessierter
Beiträge: 74
Registriert: Montag 14. Februar 2005, 10:10

Beitrag von e46ti »

- Buffer-Speicherbedarf orientiert sich an der tatsächlichen block_size im image.

- Behandlung von fragment blocks.

Kurzum es beseitigt Fehler die vermehrt auftreten, wenn man sich Füllständen von 100 % in den verschiedenen Datenblöcken nähert.

e46ti
DieMade
Oberlamer, Administrator & Supernanny
Beiträge: 10532
Registriert: Samstag 13. Juli 2002, 10:49

Beitrag von DieMade »

Na das ist doch mal eine brauchbare Aussage :)

Wenn keine negativen Rückmeldungen kommen, check ich das im Laufe der Woche mal ein.
There are 10 types of people in the world: those who know binary and those who don't
e46ti
Interessierter
Interessierter
Beiträge: 74
Registriert: Montag 14. Februar 2005, 10:10

Beitrag von e46ti »

@all

Wenn derartige Fehler trotzdem noch auftreten sollten. Bitte mal u-boot mit folgendem Eintrag:

#define SQUASHFS_TRACE 1

in der squashfs_fs.h neu compilieren und das log dann hier posten.

e46ti
DieMade
Oberlamer, Administrator & Supernanny
Beiträge: 10532
Registriert: Samstag 13. Juli 2002, 10:49

Beitrag von DieMade »

e46ti: Gegen welche u-boot Version soll der Patch denn jetzt sein? u-boot 1.1.2 so wie im cvs funktioniert jedenfalls nicht.

Kannst Du nochmal ein aktuelles diff erstellen und irgendwo hochladen bitte? Copy & Paste (gerade bei bei überlangen Zeilen) suckt einfach.

Code: Alles auswählen

boot/u-boot-tuxbox/fs/squashfs > patch -p0 < ../../../../u-boot-sqfs.patch
patching file squashfs.c
Hunk #3 succeeded at 145 with fuzz 2.
Hunk #4 succeeded at 176 (offset 1 line).
Hunk #5 succeeded at 228 (offset 1 line).
Hunk #6 succeeded at 317 (offset 1 line).
Hunk #7 succeeded at 437 (offset 1 line).
Hunk #8 succeeded at 457 (offset 1 line).
Hunk #9 succeeded at 475 (offset 1 line).
Hunk #10 succeeded at 485 (offset 1 line).
Hunk #11 succeeded at 505 (offset 1 line).

Code: Alles auswählen

squashfs.c: In function `read_block':
squashfs.c:163: error: `length' undeclared (first use in this function)
squashfs.c:163: error: (Each undeclared identifier is reported only once
squashfs.c:163: error: for each function it appears in.)
squashfs.c: In function `read_fragment_table':
squashfs.c:225: warning: unused variable `length'

CVS erstellt passende Diffs sogar automatisch:

Code: Alles auswählen

cvs -danoncvs@cvs.tuxbox.org:/cvs/tuxbox -z3 diff --text \
--rcs --unified=3 boot/u-boot-tuxbox/fs/squashfs/squashfs.c
There are 10 types of people in the world: those who know binary and those who don't
e46ti
Interessierter
Interessierter
Beiträge: 74
Registriert: Montag 14. Februar 2005, 10:10

Beitrag von e46ti »

Hallo DieMade,

war im Urlaub, deshalb melde ich mich erst jetzt :wink:

Das patch bezieht sich auf 1.1.2. Warum dies bei Dir nicht funktioniert hat, weiß ich jetzt auch nicht.

Ich schick Dir mal meine sourcen per mail.

e46ti
DieMade
Oberlamer, Administrator & Supernanny
Beiträge: 10532
Registriert: Samstag 13. Juli 2002, 10:49

Beitrag von DieMade »

Danke, damit bauts durch - das entspr. diff sieht aber auch ganz anders aus ;)

Test folgt später.
There are 10 types of people in the world: those who know binary and those who don't
DieMade
Oberlamer, Administrator & Supernanny
Beiträge: 10532
Registriert: Samstag 13. Juli 2002, 10:49

Beitrag von DieMade »

Passt, wackelt, hat Luft. Habs gerade an einem Image getestet, das vorher den o.g. Effekt hatte (### FS LOAD ERROR<0> for vmlinuz).

Ist im cvs.
There are 10 types of people in the world: those who know binary and those who don't
e46ti
Interessierter
Interessierter
Beiträge: 74
Registriert: Montag 14. Februar 2005, 10:10

Beitrag von e46ti »

Sag ich doch... :D

e46ti