mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Krzysztof Halasa <khc@pm.waw.pl>
To: barebox@lists.infradead.org
Subject: [PATCH] ARM: Changes to bootz.
Date: Sat, 05 May 2012 23:46:26 +0200	[thread overview]
Message-ID: <m37gwqmhcd.fsf@intrepid.localdomain> (raw)

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

             reply	other threads:[~2012-05-05 21:49 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-05-05 21:46 Krzysztof Halasa [this message]
2012-05-07 13:38 ` Jean-Christophe PLAGNIOL-VILLARD

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=m37gwqmhcd.fsf@intrepid.localdomain \
    --to=khc@pm.waw.pl \
    --cc=barebox@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox