[PATCH 5/5] lguest: loading bzImage directly

!MAILaRCHIVE_VOTE_RePLACE
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]
To: lkml - Kernel Mailing List <linux-kernel@...>
Cc: Jeremy Fitzhardinge <jeremy@...>, H. Peter Anvin <hpa@...>, Vivek Goyal <vgoyal@...>, lguest <lguest@...>, Eric W. Biederman <ebiederm@...>, James Bottomley <James.Bottomley@...>
Date: Tuesday, October 2, 2007 - 7:40 pm

Now arch/i386/boot/compressed/head.S understands the hardware_platform field,
we can directly execute bzImages.  No more horrific unpacking code.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
---
 Documentation/lguest/lguest.c    |   97 ++++++++++++--------------------------
 arch/i386/boot/compressed/head.S |    6 ++
 drivers/lguest/lguest.c          |    5 +
 3 files changed, 42 insertions(+), 66 deletions(-)

diff -r b0480fd71a72 Documentation/lguest/lguest.c
--- a/Documentation/lguest/lguest.c	Tue Oct 02 22:28:13 2007 +1000
+++ b/Documentation/lguest/lguest.c	Tue Oct 02 22:52:07 2007 +1000
@@ -326,74 +326,39 @@ static unsigned long map_elf(int elf_fd,
 	return ehdr->e_entry;
 }
 
-/*L:160 Unfortunately the entire ELF image isn't compressed: the segments
- * which need loading are extracted and compressed raw.  This denies us the
- * information we need to make a fully-general loader. */
-static unsigned long unpack_bzimage(int fd)
-{
-	gzFile f;
-	int ret, len = 0;
-	/* A bzImage always gets loaded at physical address 1M.  This is
-	 * actually configurable as CONFIG_PHYSICAL_START, but as the comment
-	 * there says, "Don't change this unless you know what you are doing".
-	 * Indeed. */
-	void *img = from_guest_phys(0x100000);
-
-	/* gzdopen takes our file descriptor (carefully placed at the start of
-	 * the GZIP header we found) and returns a gzFile. */
-	f = gzdopen(fd, "rb");
-	/* We read it into memory in 64k chunks until we hit the end. */
-	while ((ret = gzread(f, img + len, 65536)) > 0)
-		len += ret;
-	if (ret < 0)
-		err(1, "reading image from bzImage");
-
-	verbose("Unpacked size %i addr %p\n", len, img);
-
-	/* The entry point for a bzImage is always the first byte */
-	return (unsigned long)img;
-}
-
 /*L:150 A bzImage, unlike an ELF file, is not meant to be loaded.  You're
- * supposed to jump into it and it will unpack itself.  We can't do that
- * because the Guest can't run the unpacking code, and adding features to
- * lguest kills puppies, so we don't want to.
- *
- * The bzImage is formed by putting the decompressing code in front of the
- * compressed kernel code.  So we can simple scan through it looking for the
- * first "gzip" header, and start decompressing from there. */
+ * supposed to jump into it and it will unpack itself.  We used to have to
+ * perform some hairy magic because the unpacking code scared me.
+ *
+ * Fortunately, Jeremy Fitzhardinge convinced me it wasn't that hard and wrote
+ * a small patch to jump over the tricky bits in the guest, so now we just read
+ * the funky header so we know where in the file to load, and away we go! */
 static unsigned long load_bzimage(int fd)
 {
-	unsigned char c;
-	int state = 0;
-
-	/* GZIP header is 0x1F 0x8B <method> <flags>... <compressed-by>. */
-	while (read(fd, &c, 1) == 1) {
-		switch (state) {
-		case 0:
-			if (c == 0x1F)
-				state++;
-			break;
-		case 1:
-			if (c == 0x8B)
-				state++;
-			else
-				state = 0;
-			break;
-		case 2 ... 8:
-			state++;
-			break;
-		case 9:
-			/* Seek back to the start of the gzip header. */
-			lseek(fd, -10, SEEK_CUR);
-			/* One final check: "compressed under UNIX". */
-			if (c != 0x03)
-				state = -1;
-			else
-				return unpack_bzimage(fd);
-		}
-	}
-	errx(1, "Could not find kernel in bzImage");
+	u8 hdr[1024];
+	int r;
+	/* Modern bzImages get loaded at 1M. */
+	void *p = from_guest_phys(0x100000);
+
+	/* Go back to the start of the file and read the header.  It should be
+	 * a Linux boot header (see Documentation/i386/boot.txt) */
+	lseek(fd, 0, SEEK_SET);
+	read(fd, hdr, sizeof(hdr));
+
+	/* At offset 0x202, we expect the magic "HdrS" */
+	if (memcmp(hdr + 0x202, "HdrS", 4) != 0)
+		errx(1, "This doesn't look like a bzImage to me");
+
+	/* The byte at 0x1F1 tells us how many extra sectors of
+	 * header: skip over them all. */
+	lseek(fd, (unsigned long)(hdr[0x1F1]+1) * 512, SEEK_SET);
+
+	/* Now read everything into memory. in nice big chunks. */
+	while ((r = read(fd, p, 65536)) > 0)
+		p += r;
+
+	/* Finally, 0x214 tells us where to start the kernel. */
+	return *(unsigned long *)&hdr[0x214];
 }
 
 /*L:140 Loading the kernel is easy when it's a "vmlinux", but most kernels


-
Previous message: [thread] [date] [author]
Next message: [thread] [date] [author]

Messages in current thread:
[PATCH 0/5] Boot protocol changes, Rusty Russell, (Tue Oct 2, 7:34 pm)
Re: [PATCH 0/5] Boot protocol changes, Jeremy Fitzhardinge, (Tue Oct 2, 7:46 pm)
Re: [PATCH 0/5] Boot protocol changes, H. Peter Anvin, (Tue Oct 2, 7:53 pm)
Re: [PATCH 0/5] Boot protocol changes, Jeremy Fitzhardinge, (Tue Oct 2, 7:56 pm)
Re: [PATCH 0/5] Boot protocol changes, H. Peter Anvin, (Tue Oct 2, 8:43 pm)
Re: [PATCH 0/5] Boot protocol changes, Jeremy Fitzhardinge, (Tue Oct 2, 8:58 pm)
Re: [PATCH 0/5] Boot protocol changes, H. Peter Anvin, (Tue Oct 2, 9:03 pm)
Re: [PATCH 0/5] Boot protocol changes, H. Peter Anvin, (Tue Oct 2, 8:46 pm)
Re: [PATCH 0/5] Boot protocol changes, H. Peter Anvin, (Tue Oct 2, 7:44 pm)
[PATCH 1/5] update boot spec to 2.07, Rusty Russell, (Tue Oct 2, 7:35 pm)
Re: [PATCH 1/5] update boot spec to 2.07, rae l, (Tue Oct 30, 2:38 am)
[PATCH 2/5] add WEAK() for creating weak asm labels, Rusty Russell, (Tue Oct 2, 7:35 pm)
[PATCH 3/5] i386: paravirt boot sequence, Rusty Russell, (Tue Oct 2, 7:36 pm)
[PATCH 4/5] Revert lguest magic and use hook in head.S, Rusty Russell, (Tue Oct 2, 7:39 pm)
[PATCH 5/5] lguest: loading bzImage directly, Rusty Russell, (Tue Oct 2, 7:40 pm)
Re: [PATCH 5/5] lguest: loading bzImage directly, Chris Malley, (Wed Oct 3, 5:37 am)
Re: [PATCH 5/5] lguest: loading bzImage directly, Rusty Russell, (Wed Oct 3, 8:02 pm)
Re: [PATCH 5/5] lguest: loading bzImage directly, Kjartan Maraas, (Sat Nov 24, 5:54 pm)
Re: [PATCH 5/5] lguest: loading bzImage directly, H. Peter Anvin, (Sat Nov 24, 6:14 pm)
Re: [PATCH 5/5] lguest: loading bzImage directly, Kjartan Maraas, (Sun Nov 25, 8:32 am)
Re: [PATCH 5/5] lguest: loading bzImage directly, H. Peter Anvin, (Wed Oct 3, 8:26 pm)
Re: [PATCH 5/5] lguest: loading bzImage directly, H. Peter Anvin, (Wed Oct 3, 1:12 pm)