@all,
ich habe ja den thread hier eröffnet, um zu erforschen woher dieser Fehler kommt und ob es Möglichkeiten gibt diesen zu vermeiden.
Anfänglich bin ich dabei von einem falschen Ansatz ausgegangen
Inzwischen haben sich aber doch andere Lösungsansätze ergeben, die dazu geeignet sind, den Fehler zu umgehen
Um dies jetzt richtig nutzen zu können, bedarf es einiger Änderungen an den vorhandenen sourcen. Die Idee ist ja, mit verschieden block_sizes zu arbeiten. Mit den folgenden Änderungen arbeitet mksquashsf standardmäßig mit einer block_size=131072 und führt am Ende einen magic bytes check durch:
Code: Alles auswählen
--- squashfs_fs.h.org 2005-03-03 10:34:52.000000000 +0100
+++ squashfs_fs.h 2005-03-01 13:12:21.000000000 +0100
@@ -33,10 +33,10 @@
#define SQUASHFS_METADATA_LOG 13
/* default size of data blocks */
-#define SQUASHFS_FILE_SIZE 65536
-#define SQUASHFS_FILE_LOG 16
+#define SQUASHFS_FILE_SIZE 131072
+#define SQUASHFS_FILE_LOG 17
-#define SQUASHFS_FILE_MAX_SIZE 65536
+#define SQUASHFS_FILE_MAX_SIZE 131072
/* Max number of uids and gids */
#define SQUASHFS_UIDS 256
--- mksquashfs.c.org 2005-03-03 10:34:51.000000000 +0100
+++ mksquashfs.c 2005-03-01 13:43:45.000000000 +0100
@@ -1509,7 +1509,7 @@
{
int i;
- for(i = 9; i <= 16; i++)
+ for(i = 9; i <= 17; i++)
if(block == (1 << i))
return i;
return 0;
@@ -2076,11 +2076,64 @@
}
printf("Number of gids %d\n", guid_count);
-
for(i = 0; i < guid_count; i++) {
struct group *group = getgrgid(guids[i]);
printf("\t%s (%d)\n", group == NULL ? "unknown" : group->gr_name, guids[i]);
}
+
+
+ int x, y, z;
+ unsigned char value[23];
+
+ printf("\n");
+ printf("*** Checking for magic bytes at 128 KB sector ends ***\n");
+
+ z = (int) (bytes / 131072);
+
+ printf("%d sectors must be checked...\n", z);
+
+
+ for(y = 1; y <= z; y++) {
+
+ x = (y * 131072) - 23;
+
+ if(lseek(fd, x, SEEK_SET) == -1) {
+ perror("Lseek on destination failed");
+ EXIT_MKSQUASHFS();
+ }
+ if(read(fd, value, 23) == -1) {
+ perror("Read on destination failed");
+ EXIT_MKSQUASHFS();
+ }
+
+ if (value[1] <= 0xFE && (value[21] >= 0xc0 && value[21] <=0xc4) && ((value[22] &0x0f) == 0x06 || (value[22] &0x0f) == 0x0e))
+ {
+ printf("0x%06x | %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", x, value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], value[8], value[9], value[10], value[11], value[12], value[13], value[14], value[15], value[16], value[17], value[18], value[19], value[20], value[21], value[22]);
+ printf(" -> bad magic in flash #1\n");
+ goto err;
+ }
+
+ if (value[0] <= 0xFE && (value[19] >= 0xc0 && value[19] <=0xc4) && ((value[20] &0x0f) == 0x06 || (value[20] &0x0f) == 0x0e))
+ {
+ printf("0x%06x | %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", x, value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], value[8], value[9], value[10], value[11], value[12], value[13], value[14], value[15], value[16], value[17], value[18], value[19], value[20], value[21], value[22]);
+ printf(" -> bad magic in flash #2\n");
+ goto err;
+ }
+
+ if (value[11] <= 0xFE && (value[21] >= 0xc0 && value[21] <=0xc4) && ((value[22] &0x0f) == 0x06 || (value[22] &0x0f) == 0x0e))
+ {
+ printf("0x%06x | %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x", x, value[0], value[1], value[2], value[3], value[4], value[5], value[6], value[7], value[8], value[9], value[10], value[11], value[12], value[13], value[14], value[15], value[16], value[17], value[18], value[19], value[20], value[21], value[22]);
+ printf(" -> bad magic\n");
+ goto err;
+ }
+ }
+
+ printf("*** No magic bytes found ***\n");
close(fd);
return 0;
+
+ err:
+ printf("*** If you flash this image these bytes cause 'no system' ***\n");
+ close(fd);
+ return 0;
}
Werden andere block_sizes als 65536 verwendet hat u-boot u.U. Schwierigkeiten mit fragment blocks. Auch hierfür gibt es eine Lösung
Code: Alles auswählen
--- squashfs.c.org 2005-03-03 10:48:19.000000000 +0100
+++ squashfs.c 2005-02-24 10:55:55.000000000 +0100
@@ -121,7 +121,7 @@
)
{
unsigned short int c_byte;
- int offset;
+ int offset, i;
unsigned char check_data;
short int compressed;
unsigned int length;
@@ -146,42 +146,44 @@
{
compressed = SQUASHFS_COMPRESSED_BLOCK(*bytecount);
length = SQUASHFS_COMPRESSED_SIZE_BLOCK(*bytecount);
- offset = frag_size ? frag_offset : 0;
+ 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, length);
+
read_bytes(info, start + offset, length, buffer);
squashfs_uncompress_init();
/* inflate the block (to temporary buffer if we only need a fragment) */
res = squashfs_uncompress_block(frag_size ? uncompressed_buffer : block, bytes, buffer, length);
+
TRACE("compressed block @ 0x%x, uncompressed size %d\n", start, res);
- if(!res)
- {
- ERROR("zlib::uncompress failed\n");
- squashfs_uncompress_exit();
- return 0;
- }
+
squashfs_uncompress_exit();
+
+ if(!res)
+ return 0;
+
/* 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;
}
+
return frag_size ? frag_size : res;
}
/* handle uncompressed block */
@@ -394,6 +400,9 @@
case SQUASHFS_SYMLINK_TYPE:
/* resolve */
break;
+ case SQUASHFS_LDIR_TYPE:
+ /* resolve */
+ break;
default:
break;
}
@@ -411,21 +420,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)
{
@@ -433,6 +438,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++)
@@ -442,10 +448,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;
@@ -459,8 +468,15 @@
return 0;
break;
}
+ case SQUASHFS_LDIR_TYPE:
+ {
+ printf ("loading ldirs is not supported\n");
+ free (blockbuffer);
+ return 0;
+ break;
}
}
+ }
parsed=1;
break;
}
--- uncompress.c.org 2005-03-03 11:00:50.000000000 +0100
+++ uncompress.c 2005-02-23 16:32:03.000000000 +0100
@@ -42,7 +42,6 @@
int squashfs_uncompress_block (void *dst, int dstlen, void *src, int srclen)
{
int err;
- inflateReset (&stream);
stream.next_in = src;
stream.avail_in = srclen;
@@ -50,11 +49,13 @@
stream.next_out = dst;
stream.avail_out = dstlen;
- err = inflate (&stream, Z_FINISH);
- if ((err==Z_OK)||(err==Z_STREAM_END))
- return dstlen-stream.avail_out;
- else
+ if (((err = inflate(&stream, Z_FINISH)) != Z_STREAM_END)||((err = inflateEnd(&stream)) != Z_OK))
+ {
+ printf("SQUASHFS error: zlib returned unexspected result %d\n", err);
return 0;
+ }
+ else
+ return stream.total_out;
}
int squashfs_uncompress_init (void)
@@ -74,7 +75,7 @@
err = inflateInit (&stream);
if (err != Z_OK) {
- printf ("Error: inflateInit() returned %d\n", err);
+ printf("SQUASHFS error: zlib returned returned unexspected result %d\n", err);
return -1;
}
Der kernel patch bleibt hiervon unberührt, da der Parameter block_size im image gespeichert wird und immer jeweils aktuell ausgelesen wird.
So viel Spaß beim Testen...
e46ti