[PATCH] ARM: Changes to bootz.

Krzysztof Halasa khc at pm.waw.pl
Sat May 5 17:46:26 EDT 2012


Fixed bootz command to always check if the zImage fits completely
in the first 128 MB of RAM.
Allows operation with more than 128 MB RAM.
We don't try to free() memmapped zImage anymore.
Endianness swapping is now possible with memmappable zImage, too.

Signed-off-by: Krzysztof Hałasa <khc at pm.waw.pl>

diff --git a/arch/arm/lib/bootz.c b/arch/arm/lib/bootz.c
index f394a6b..c11f43a 100644
--- a/arch/arm/lib/bootz.c
+++ b/arch/arm/lib/bootz.c
@@ -21,14 +21,20 @@ struct zimage_header {
 
 #define ZIMAGE_MAGIC 0x016F2818
 
+static int valid_addr(void *zimage, u32 size, struct memory_bank *bank)
+{
+	if ((unsigned long)zimage < bank->start)
+		return 0;
+	if ((unsigned long)zimage + size >= bank->start + SZ_128M)
+		return 0;
+	return 1;
+}
+
 static int do_bootz(int argc, char *argv[])
 {
-	int fd, ret, swap = 0;
-	struct zimage_header __header, *header;
-	void *zimage;
-	void *oftree = NULL;
-	u32 end;
-	int usemap = 0;
+	int fd, swap = 0;
+	struct zimage_header header;
+	void *zimage = NULL, *oftree = NULL, *alloc = NULL;
 	struct memory_bank *bank = list_first_entry(&memory_banks, struct memory_bank, list);
 
 	if (argc != 2)
@@ -40,84 +46,93 @@ static int do_bootz(int argc, char *argv[])
 		return 1;
 	}
 
-	/*
-	 * We can save the memcpy of the zImage if it already is in
-	 * the first 128MB of SDRAM.
-	 */
-	zimage = memmap(fd, PROT_READ);
-	if (zimage && (unsigned long)zimage  >= bank->start &&
-			(unsigned long)zimage < bank->start + SZ_128M) {
-		usemap = 1;
-		header = zimage;
-	}
-
-	if (!usemap) {
-		header = &__header;
-		ret = read(fd, header, sizeof(*header));
-		if (ret < sizeof(*header)) {
-			printf("could not read %s\n", argv[1]);
-			goto err_out;
-		}
+	if (read(fd, &header, sizeof(header)) < sizeof(header)) {
+		printf("could not read %s\n", argv[1]);
+		goto err_out;
 	}
 
-	switch (header->magic) {
+	switch (header.magic) {
 #ifdef CONFIG_BOOT_ENDIANNESS_SWITCH
 	case swab32(ZIMAGE_MAGIC):
 		swap = 1;
+		header.end = swab32(header.end);
 		/* fall through */
 #endif
 	case ZIMAGE_MAGIC:
 		break;
 	default:
-		printf("invalid magic 0x%08x\n", header->magic);
+		printf("invalid magic 0x%08x\n", header.magic);
 		goto err_out;
 	}
 
-	end = header->end;
+	/*
+	 * We can save the memcpy of the zImage if it already is in
+	 * the first 128MB of SDRAM.
+	 */
+	if (!swap) {
+		zimage = memmap(fd, PROT_READ);
+		if (zimage && !valid_addr(zimage, header.end, bank))
+			zimage = NULL;
+	}
 
-	if (swap)
-		end = swab32(end);
+	if (!zimage) {
+		/* memmap approach didn't work, let's try something different */
+		void **ptr = NULL, *next;
 
-	if (!usemap) {
-		if (bank->size <= SZ_128M) {
-			zimage = xmalloc(end);
-		} else {
-			zimage = (void *)bank->start + SZ_8M;
-			if (bank->start + SZ_8M + end >= MALLOC_BASE) {
+		/* create a linked list of allocated chunks */
+		while ((zimage = malloc(header.end))) {
+			if (valid_addr(zimage, header.end, bank)) {
+				alloc = zimage; /* free on error */
+				break; /* found a good chunk */
+			}
+			*(void **)zimage = ptr;
+			ptr = zimage; /* free it later */
+		}
+
+		/* free now unneeded memory regions */
+		while (ptr) {
+			next = *ptr;
+			free(ptr);
+			ptr = next;
+		}
+
+		if (!zimage) {
+			/* malloc approach didn't work either */
+			if (bank->start + SZ_8M + header.end >= MALLOC_BASE) {
 				printf("won't overwrite malloc space with image\n");
-				goto err_out1;
+				goto err_out;
 			}
+			zimage = (void *)bank->start + SZ_8M;
 		}
 
-		memcpy(zimage, header, sizeof(*header));
+		if (lseek(fd, 0, SEEK_SET) < 0) {
+			printf("could not rewind %s\n", argv[1]);
+			goto err_out;
+		}
 
-		ret = read(fd, zimage + sizeof(*header), end - sizeof(*header));
-		if (ret < end - sizeof(*header)) {
+		if (read(fd, zimage, header.end) < header.end) {
 			printf("could not read %s\n", argv[1]);
-			goto err_out1;
+			goto err_out;
 		}
 	}
 
 	if (swap) {
 		void *ptr;
-		for (ptr = zimage; ptr < zimage + end; ptr += 4)
+		for (ptr = zimage; ptr < zimage + header.end; ptr += 4)
 			*(u32 *)ptr = swab32(*(u32 *)ptr);
 	}
 
-	printf("loaded zImage from %s with size %d\n", argv[1], end);
+	printf("loaded zImage from %s with size %d\n", argv[1], header.end);
 #ifdef CONFIG_OFTREE
 	oftree = of_get_fixed_tree();
 #endif
 
 	start_linux(zimage, swap, 0, 0, oftree);
-
 	return 0;
 
-err_out1:
-	free(zimage);
 err_out:
+	free(alloc);
 	close(fd);
-
 	return 1;
 }
 



More information about the barebox mailing list