diff options
author | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-11-12 10:52:17 +0000 |
---|---|---|
committer | kaf24@scramble.cl.cam.ac.uk <kaf24@scramble.cl.cam.ac.uk> | 2003-11-12 10:52:17 +0000 |
commit | a7cee9a0630ce7bee570237018f16b9844214fe9 (patch) | |
tree | b93cab86b35f22417318133a2f7c60900a285458 /tools/internal/xi_build.c | |
parent | 534df3bba622b5698d4339a219854ef52bb91c48 (diff) | |
download | xen-a7cee9a0630ce7bee570237018f16b9844214fe9.tar.gz xen-a7cee9a0630ce7bee570237018f16b9844214fe9.tar.bz2 xen-a7cee9a0630ce7bee570237018f16b9844214fe9.zip |
bitkeeper revision 1.594 (3fb210e1h9kxCYdiaHlo-5FLn1jxLg)
xi_build.c, Makefile:
xi_build will now accept a gzipped kernel image.
Diffstat (limited to 'tools/internal/xi_build.c')
-rw-r--r-- | tools/internal/xi_build.c | 107 |
1 files changed, 50 insertions, 57 deletions
diff --git a/tools/internal/xi_build.c b/tools/internal/xi_build.c index 0685d723bf..3a97cad80e 100644 --- a/tools/internal/xi_build.c +++ b/tools/internal/xi_build.c @@ -2,6 +2,8 @@ #include "dom0_defs.h" #include "mem_defs.h" +#include <zlib.h> + /* This string is written to the head of every guest kernel image. */ #define GUEST_SIG "XenoGues" #define SIG_LEN 8 @@ -69,29 +71,12 @@ static int send_pgupdates(mmu_update_t *updates, int nr_updates) } /* Read the kernel header, extracting the image size and load address. */ -static int read_kernel_header(int fd, long dom_size, - unsigned long * load_addr, size_t * ksize) +static int read_kernel_header(gzFile gfd, long dom_size, + unsigned long *load_addr) { - char signature[8]; - char status[1024]; - struct stat stat; - - if ( fstat(fd, &stat) < 0 ) - { - PERROR("Cannot stat the kernel image"); - return -1; - } + char signature[SIG_LEN]; - /* Double the kernel image size to account for dynamic memory usage etc. */ - if ( (stat.st_size * 2) > (dom_size << 10) ) - { - sprintf(status, "Kernel image size %ld larger than requested " - "domain size %ld\n Terminated.\n", stat.st_size, dom_size); - ERROR(status); - return -1; - } - - read(fd, signature, SIG_LEN); + gzread(gfd, signature, SIG_LEN); if ( strncmp(signature, GUEST_SIG, SIG_LEN) ) { ERROR("Kernel image does not contain required signature.\n" @@ -100,21 +85,7 @@ static int read_kernel_header(int fd, long dom_size, } /* Read the load address which immediately follows the Xeno signature. */ - read(fd, load_addr, sizeof(unsigned long)); - - if ( (*load_addr & (PAGE_SIZE-1)) != 0 ) - { - ERROR("We can only deal with page-aligned load addresses"); - return -1; - } - - if ( (*load_addr + (dom_size << 10)) > HYPERVISOR_VIRT_START ) - { - ERROR("Cannot map all domain memory without hitting Xen space"); - return -1; - } - - *ksize = stat.st_size - SIG_LEN - sizeof(unsigned long); + gzread(gfd, load_addr, sizeof(unsigned long)); return 0; } @@ -159,8 +130,8 @@ static int copy_to_domain_page(unsigned long dst_pfn, void *src_page) } static int setup_guestos( - int dom, int kernel_fd, int initrd_fd, unsigned long tot_pages, - unsigned long virt_load_addr, size_t ksize, + int dom, gzFile kernel_gfd, int initrd_fd, unsigned long tot_pages, + unsigned long virt_load_addr, dom0_builddomain_t *builddomain, int argc, char **argv, int args_start, unsigned long shared_info_frame) { @@ -177,6 +148,7 @@ static int setup_guestos( start_info_t *start_info; shared_info_t *shared_info; int cmd_len; + unsigned long ksize; memset(builddomain, 0, sizeof(*builddomain)); @@ -198,19 +170,27 @@ static int setup_guestos( goto error_out; } - /* Load the guest OS image. */ - for ( i = 0; i < ksize; i += PAGE_SIZE ) + /* Load the guest OS image. Let it take no more than 1/2 memory.*/ + for ( i = 0; i < ((tot_pages/2)*PAGE_SIZE); i += PAGE_SIZE ) { char page[PAGE_SIZE]; - int size = ((ksize-i) < PAGE_SIZE) ? (ksize-i) : PAGE_SIZE; - if ( read(kernel_fd, page, size) != size ) + int size; + if ( (size = gzread(kernel_gfd, page, PAGE_SIZE)) == -1 ) { PERROR("Error reading kernel image, could not" " read the whole image."); goto error_out; - } + } + if ( size == 0 ) + goto kernel_copied; copy_to_domain_page(page_array[i>>PAGE_SHIFT], page); } + ERROR("Kernel too big to safely fit in domain memory"); + goto error_out; + + kernel_copied: + /* ksize is kernel-image size rounded up to a page boundary. */ + ksize = i; /* Load the initial ramdisk image. */ if ( initrd_fd >= 0 ) @@ -224,17 +204,16 @@ static int setup_guestos( goto error_out; } isize = stat.st_size; - if ( ((isize + ksize) * 2) > (tot_pages << PAGE_SHIFT) ) + if ( (isize + ksize) > ((tot_pages/2) * PAGE_SIZE) ) { ERROR("Kernel + initrd too big to safely fit in domain memory"); goto error_out; } - /* 'i' is 'ksize' rounded up to a page boundary. */ - initrd_addr = virt_load_addr + i; + initrd_addr = virt_load_addr + ksize; initrd_len = isize; - for ( j = 0; j < isize; j += PAGE_SIZE, i += PAGE_SIZE ) + for ( j = 0, i = ksize; j < isize; j += PAGE_SIZE, i += PAGE_SIZE ) { char page[PAGE_SIZE]; int size = ((isize-j) < PAGE_SIZE) ? (isize-j) : PAGE_SIZE; @@ -376,15 +355,11 @@ static int setup_guestos( int main(int argc, char **argv) { - /* - * NB. 'ksize' is the size in bytes of the main kernel image. It excludes - * the 8-byte signature and 4-byte load address. - */ - size_t ksize; dom0_op_t launch_op, op; unsigned long load_addr; long tot_pages; int kernel_fd, initrd_fd = -1; + gzFile kernel_gfd; int args_start = 4; char initrd_name[1024]; int domain_id; @@ -421,12 +396,30 @@ int main(int argc, char **argv) return 1; } - rc = read_kernel_header(kernel_fd, + if ( (kernel_gfd = gzdopen(kernel_fd, "rb")) == NULL ) + { + PERROR("Could not allocate decompression state for state file"); + return 1; + } + + rc = read_kernel_header(kernel_gfd, tot_pages << (PAGE_SHIFT - 10), - &load_addr, &ksize); + &load_addr); if ( rc < 0 ) return 1; + if ( (load_addr & (PAGE_SIZE-1)) != 0 ) + { + ERROR("We can only deal with page-aligned load addresses"); + return -1; + } + + if ( (load_addr + (tot_pages << PAGE_SHIFT)) > HYPERVISOR_VIRT_START ) + { + ERROR("Cannot map all domain memory without hitting Xen space"); + return -1; + } + if( (argc > args_start) && (strncmp("initrd=", argv[args_start], 7) == 0) ) { @@ -457,8 +450,8 @@ int main(int argc, char **argv) return 1; } - if ( setup_guestos(domain_id, kernel_fd, initrd_fd, tot_pages, - load_addr, ksize, &launch_op.u.builddomain, + if ( setup_guestos(domain_id, kernel_gfd, initrd_fd, tot_pages, + load_addr, &launch_op.u.builddomain, argc, argv, args_start, op.u.getdomaininfo.shared_info_frame) < 0 ) { @@ -468,7 +461,7 @@ int main(int argc, char **argv) if ( initrd_fd >= 0 ) close(initrd_fd); - close(kernel_fd); + gzclose(kernel_gfd); ctxt = &launch_op.u.builddomain.ctxt; |