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
next 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