mail archive of the barebox mailing list
 help / color / mirror / Atom feed
* [PATCH] ARM: Changes to bootz.
@ 2012-05-05 21:46 Krzysztof Halasa
  2012-05-07 13:38 ` Jean-Christophe PLAGNIOL-VILLARD
  0 siblings, 1 reply; 2+ messages in thread
From: Krzysztof Halasa @ 2012-05-05 21:46 UTC (permalink / raw)
  To: barebox

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@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;
 }
 

_______________________________________________
barebox mailing list
barebox@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/barebox

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2012-05-07 13:38 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-05-05 21:46 [PATCH] ARM: Changes to bootz Krzysztof Halasa
2012-05-07 13:38 ` Jean-Christophe PLAGNIOL-VILLARD

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox