diff options
-rw-r--r-- | Documentation/lguest/lguest.c | 47 |
1 files changed, 22 insertions, 25 deletions
diff --git a/Documentation/lguest/lguest.c b/Documentation/lguest/lguest.c index 3949620e42fa..5bdc37f81842 100644 --- a/Documentation/lguest/lguest.c +++ b/Documentation/lguest/lguest.c | |||
@@ -52,7 +52,7 @@ typedef uint8_t u8; | |||
52 | #include "linux/virtio_blk.h" | 52 | #include "linux/virtio_blk.h" |
53 | #include "linux/virtio_console.h" | 53 | #include "linux/virtio_console.h" |
54 | #include "linux/virtio_ring.h" | 54 | #include "linux/virtio_ring.h" |
55 | #include "asm-x86/e820.h" | 55 | #include "asm-x86/bootparam.h" |
56 | /*:*/ | 56 | /*:*/ |
57 | 57 | ||
58 | #define PAGE_PRESENT 0x7 /* Present, RW, Execute */ | 58 | #define PAGE_PRESENT 0x7 /* Present, RW, Execute */ |
@@ -335,7 +335,7 @@ static unsigned long map_elf(int elf_fd, const Elf32_Ehdr *ehdr) | |||
335 | * the funky header so we know where in the file to load, and away we go! */ | 335 | * the funky header so we know where in the file to load, and away we go! */ |
336 | static unsigned long load_bzimage(int fd) | 336 | static unsigned long load_bzimage(int fd) |
337 | { | 337 | { |
338 | u8 hdr[1024]; | 338 | struct boot_params boot; |
339 | int r; | 339 | int r; |
340 | /* Modern bzImages get loaded at 1M. */ | 340 | /* Modern bzImages get loaded at 1M. */ |
341 | void *p = from_guest_phys(0x100000); | 341 | void *p = from_guest_phys(0x100000); |
@@ -343,22 +343,21 @@ static unsigned long load_bzimage(int fd) | |||
343 | /* Go back to the start of the file and read the header. It should be | 343 | /* Go back to the start of the file and read the header. It should be |
344 | * a Linux boot header (see Documentation/i386/boot.txt) */ | 344 | * a Linux boot header (see Documentation/i386/boot.txt) */ |
345 | lseek(fd, 0, SEEK_SET); | 345 | lseek(fd, 0, SEEK_SET); |
346 | read(fd, hdr, sizeof(hdr)); | 346 | read(fd, &boot, sizeof(boot)); |
347 | 347 | ||
348 | /* At offset 0x202, we expect the magic "HdrS" */ | 348 | /* Inside the setup_hdr, we expect the magic "HdrS" */ |
349 | if (memcmp(hdr + 0x202, "HdrS", 4) != 0) | 349 | if (memcmp(&boot.hdr.header, "HdrS", 4) != 0) |
350 | errx(1, "This doesn't look like a bzImage to me"); | 350 | errx(1, "This doesn't look like a bzImage to me"); |
351 | 351 | ||
352 | /* The byte at 0x1F1 tells us how many extra sectors of | 352 | /* Skip over the extra sectors of the header. */ |
353 | * header: skip over them all. */ | 353 | lseek(fd, (boot.hdr.setup_sects+1) * 512, SEEK_SET); |
354 | lseek(fd, (unsigned long)(hdr[0x1F1]+1) * 512, SEEK_SET); | ||
355 | 354 | ||
356 | /* Now read everything into memory. in nice big chunks. */ | 355 | /* Now read everything into memory. in nice big chunks. */ |
357 | while ((r = read(fd, p, 65536)) > 0) | 356 | while ((r = read(fd, p, 65536)) > 0) |
358 | p += r; | 357 | p += r; |
359 | 358 | ||
360 | /* Finally, 0x214 tells us where to start the kernel. */ | 359 | /* Finally, code32_start tells us where to enter the kernel. */ |
361 | return *(unsigned long *)&hdr[0x214]; | 360 | return boot.hdr.code32_start; |
362 | } | 361 | } |
363 | 362 | ||
364 | /*L:140 Loading the kernel is easy when it's a "vmlinux", but most kernels | 363 | /*L:140 Loading the kernel is easy when it's a "vmlinux", but most kernels |
@@ -1531,7 +1530,7 @@ int main(int argc, char *argv[]) | |||
1531 | /* A temporary and the /dev/lguest file descriptor. */ | 1530 | /* A temporary and the /dev/lguest file descriptor. */ |
1532 | int i, c, lguest_fd; | 1531 | int i, c, lguest_fd; |
1533 | /* The boot information for the Guest. */ | 1532 | /* The boot information for the Guest. */ |
1534 | void *boot; | 1533 | struct boot_params *boot; |
1535 | /* If they specify an initrd file to load. */ | 1534 | /* If they specify an initrd file to load. */ |
1536 | const char *initrd_name = NULL; | 1535 | const char *initrd_name = NULL; |
1537 | 1536 | ||
@@ -1607,10 +1606,10 @@ int main(int argc, char *argv[]) | |||
1607 | initrd_size = load_initrd(initrd_name, mem); | 1606 | initrd_size = load_initrd(initrd_name, mem); |
1608 | /* These are the location in the Linux boot header where the | 1607 | /* These are the location in the Linux boot header where the |
1609 | * start and size of the initrd are expected to be found. */ | 1608 | * start and size of the initrd are expected to be found. */ |
1610 | *(unsigned long *)(boot+0x218) = mem - initrd_size; | 1609 | boot->hdr.ramdisk_image = mem - initrd_size; |
1611 | *(unsigned long *)(boot+0x21c) = initrd_size; | 1610 | boot->hdr.ramdisk_size = initrd_size; |
1612 | /* The bootloader type 0xFF means "unknown"; that's OK. */ | 1611 | /* The bootloader type 0xFF means "unknown"; that's OK. */ |
1613 | *(unsigned char *)(boot+0x210) = 0xFF; | 1612 | boot->hdr.type_of_loader = 0xFF; |
1614 | } | 1613 | } |
1615 | 1614 | ||
1616 | /* Set up the initial linear pagetables, starting below the initrd. */ | 1615 | /* Set up the initial linear pagetables, starting below the initrd. */ |
@@ -1618,23 +1617,21 @@ int main(int argc, char *argv[]) | |||
1618 | 1617 | ||
1619 | /* The Linux boot header contains an "E820" memory map: ours is a | 1618 | /* The Linux boot header contains an "E820" memory map: ours is a |
1620 | * simple, single region. */ | 1619 | * simple, single region. */ |
1621 | *(char*)(boot+E820NR) = 1; | 1620 | boot->e820_entries = 1; |
1622 | *((struct e820entry *)(boot+E820MAP)) | 1621 | boot->e820_map[0] = ((struct e820entry) { 0, mem, E820_RAM }); |
1623 | = ((struct e820entry) { 0, mem, E820_RAM }); | ||
1624 | /* The boot header contains a command line pointer: we put the command | 1622 | /* The boot header contains a command line pointer: we put the command |
1625 | * line after the boot header (at address 4096) */ | 1623 | * line after the boot header. */ |
1626 | *(u32 *)(boot + 0x228) = 4096; | 1624 | boot->hdr.cmd_line_ptr = to_guest_phys(boot + 1); |
1627 | concat(boot + 4096, argv+optind+2); | 1625 | concat((char *)(boot + 1), argv+optind+2); |
1628 | 1626 | ||
1629 | /* Boot protocol version: 2.07 supports the fields for lguest. */ | 1627 | /* Boot protocol version: 2.07 supports the fields for lguest. */ |
1630 | *(u16 *)(boot + 0x206) = 0x207; | 1628 | boot->hdr.version = 0x207; |
1631 | 1629 | ||
1632 | /* The hardware_subarch value of "1" tells the Guest it's an lguest. */ | 1630 | /* The hardware_subarch value of "1" tells the Guest it's an lguest. */ |
1633 | *(u32 *)(boot + 0x23c) = 1; | 1631 | boot->hdr.hardware_subarch = 1; |
1634 | 1632 | ||
1635 | /* Set bit 6 of the loadflags (aka. KEEP_SEGMENTS) so the entry path | 1633 | /* Tell the entry path not to try to reload segment registers. */ |
1636 | * does not try to reload segment registers. */ | 1634 | boot->hdr.loadflags |= KEEP_SEGMENTS; |
1637 | *(u8 *)(boot + 0x211) |= (1 << 6); | ||
1638 | 1635 | ||
1639 | /* We tell the kernel to initialize the Guest: this returns the open | 1636 | /* We tell the kernel to initialize the Guest: this returns the open |
1640 | * /dev/lguest file descriptor. */ | 1637 | * /dev/lguest file descriptor. */ |