From: BitKeeper B. <ri...@su...> - 2004-12-24 23:18:34
|
ChangeSet 1.1550.14.81, 2004/12/24 22:08:11+00:00, ia...@la... Add plan9 builder support. libxc/Makefile | 1 libxc/plan9a.out.h | 28 + libxc/xc.h | 8 libxc/xc_plan9_build.c | 744 ++++++++++++++++++++++++++++++++++++++ python/xen/lowlevel/xc/xc.c | 35 + python/xen/xend/XendDomainInfo.py | 29 + 6 files changed, 845 insertions(+) diff -Nru a/tools/libxc/Makefile b/tools/libxc/Makefile --- a/tools/libxc/Makefile 2004-12-24 18:02:12 -05:00 +++ b/tools/libxc/Makefile 2004-12-24 18:02:12 -05:00 @@ -18,6 +18,7 @@ SRCS += xc_evtchn.c SRCS += xc_io.c SRCS += xc_linux_build.c +SRCS += xc_plan9_build.c SRCS += xc_linux_restore.c SRCS += xc_linux_save.c SRCS += xc_misc.c diff -Nru a/tools/libxc/plan9a.out.h b/tools/libxc/plan9a.out.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/tools/libxc/plan9a.out.h 2004-12-24 18:02:12 -05:00 @@ -0,0 +1,28 @@ + +typedef struct Exec +{ + long magic; /* magic number */ + long text; /* size of text segment */ + long data; /* size of initialized data */ + long bss; /* size of uninitialized data */ + long syms; /* size of symbol table */ + long entry; /* entry point */ + long spsz; /* size of pc/sp offset table */ + long pcsz; /* size of pc/line number table */ +} Exec; + +#define _MAGIC(b) ((((4*b)+0)*b)+7) +#define A_MAGIC _MAGIC(8) /* 68020 */ +#define I_MAGIC _MAGIC(11) /* intel 386 */ +#define J_MAGIC _MAGIC(12) /* intel 960 */ +#define K_MAGIC _MAGIC(13) /* sparc */ +#define V_MAGIC _MAGIC(16) /* mips 3000 */ +#define X_MAGIC _MAGIC(17) /* att dsp 3210 */ +#define M_MAGIC _MAGIC(18) /* mips 4000 */ +#define D_MAGIC _MAGIC(19) /* amd 29000 */ +#define E_MAGIC _MAGIC(20) /* arm 7-something */ +#define Q_MAGIC _MAGIC(21) /* powerpc */ +#define N_MAGIC _MAGIC(22) /* mips 4000 LE */ +#define L_MAGIC _MAGIC(23) /* dec alpha */ +#define P_MAGIC _MAGIC(24) /* mips 3000 LE */ + diff -Nru a/tools/libxc/xc.h b/tools/libxc/xc.h --- a/tools/libxc/xc.h 2004-12-24 18:02:12 -05:00 +++ b/tools/libxc/xc.h 2004-12-24 18:02:12 -05:00 @@ -97,6 +97,14 @@ unsigned int control_evtchn, unsigned long flags); +int +xc_plan9_build (int xc_handle, + u32 domid, + const char *image_name, + const char *cmdline, + unsigned int control_evtchn, + unsigned long flags); + int xc_bvtsched_global_set(int xc_handle, unsigned long ctx_allow); diff -Nru a/tools/libxc/xc_plan9_build.c b/tools/libxc/xc_plan9_build.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/tools/libxc/xc_plan9_build.c 2004-12-24 18:02:12 -05:00 @@ -0,0 +1,744 @@ +/****************************************************************************** + * xc_plan9_build.c + * derived from xc_linux_build.c + */ + +#include "xc_private.h" + +#include <zlib.h> + +#define DEBUG 1 +#ifdef DEBUG +#define DPRINTF(x) printf x; fflush(stdout); +#else +#define DPRINTF(x) +#endif + +#include "plan9a.out.h" + +/* really TOS which means stack starts at 0x2000, and uses page 1*/ +#define STACKPAGE 2 +struct Exec header, origheader; + +typedef struct page { + char data[PAGE_SIZE]; +} PAGE; + + +int +memcpy_toguest(int xc_handle, u32 dom, void *v, int size, + unsigned long *page_array, unsigned int to_page) +{ + int ret; + unsigned char *cp = v; + unsigned int whichpage; + unsigned char *vaddr; + +// DPRINTF(("memcpy_to_guest: to_page 0x%x, count %d\n", to_page, size)); + for (ret = 0, whichpage = to_page; size > 0; + whichpage++, size -= PAGE_SIZE, cp += PAGE_SIZE) { + + // DPRINTF (("map_pfn_writeable(%p, 0x%lx)\n", pm_handle, +// page_array[whichpage])); + vaddr = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ | PROT_WRITE, + page_array[whichpage]); + // DPRINTF (("vaddr is %p\n", vaddr)); + if (vaddr == NULL) { + ret = -1; + ERROR("Couldn't map guest memory"); + goto out; + } + // DPRINTF (("copy %p to %p, count 0x%x\n", cp, vaddr, 4096)); + memcpy(vaddr, cp, 4096); + munmap(vaddr, PAGE_SIZE); + // DPRINTF (("Did %ud'th pages\n", whichpage)); + } + out: + return ret; +} + +/* this is a function which can go away. It dumps a hunk of + * guest pages to a file (/tmp/dumpit); handy for debugging + * your image builder. + * Xen guys, nuke this if you wish. + */ +void +dumpit(int xc_handle, u32 dom, + int start_page, int tot, unsigned long *page_array) +{ + int i, ofd; + unsigned char *vaddr; + + ofd = open("/tmp/dumpit", O_RDWR); + for (i = start_page; i < tot; i++) { + vaddr = xc_map_foreign_range(xc_handle, dom, PAGE_SIZE, + PROT_READ | PROT_WRITE, + page_array[i]); + if (!vaddr) { + fprintf(stderr, "Page %d\n", i); + perror("shit"); + read(0, &i, 1); + return; + } + write(ofd, vaddr, 4096); + munmap(vaddr, PAGE_SIZE); + } +} +int +blah(char *b) +{ + fprintf(stderr, "Error in xc_plan9_build!\n"); + perror(b); + return errno; +} + +/* swap bytes. For plan 9 headers */ +void +swabby(unsigned long *s, char *name) +{ + unsigned long it; + it = ((*s & 0xff000000) >> 24) | ((*s & 0xff0000) >> 8) | + ((*s & 0xff00) << 8) | ((*s & 0xff) << 24); + DPRINTF(("Item %s is 0x%lx\n", name, it)); + *s = it; +} + +void +plan9header(Exec * header) +{ + /* header is big-endian */ + swabby(&header->magic, "magic"); + swabby(&header->text, "text"); + swabby(&header->data, "data"); + swabby(&header->bss, "bss"); + swabby(&header->syms, "syms"); + swabby(&header->entry, "entry"); + swabby(&header->spsz, "spsz"); + swabby(&header->pcsz, "pcsz"); + +} + +static int + loadp9image(gzFile kernel_gfd, int xc_handle, u32 dom, + unsigned long *page_array, + unsigned long tot_pages, unsigned long *virt_load_addr, + unsigned long *ksize, unsigned long *symtab_addr, + unsigned long *symtab_len, + unsigned long *first_data_page, unsigned long *pdb_page); + +#define P9ROUND (P9SIZE / 8) + +#define L1_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED) +#define L2_PROT (_PAGE_PRESENT|_PAGE_RW|_PAGE_ACCESSED|_PAGE_DIRTY|_PAGE_USER) + +static long +get_tot_pages(int xc_handle, u32 domid) +{ + dom0_op_t op; + op.cmd = DOM0_GETDOMAININFO; + op.u.getdomaininfo.domain = (domid_t) domid; + op.u.getdomaininfo.ctxt = NULL; + return (do_dom0_op(xc_handle, &op) < 0) ? + -1 : op.u.getdomaininfo.tot_pages; +} + +static int +get_pfn_list(int xc_handle, + u32 domid, unsigned long *pfn_buf, unsigned long max_pfns) +{ + dom0_op_t op; + int ret; + op.cmd = DOM0_GETMEMLIST; + op.u.getmemlist.domain = (domid_t) domid; + op.u.getmemlist.max_pfns = max_pfns; + op.u.getmemlist.buffer = pfn_buf; + + if (mlock(pfn_buf, max_pfns * sizeof (unsigned long)) != 0) + return -1; + + ret = do_dom0_op(xc_handle, &op); + + (void) munlock(pfn_buf, max_pfns * sizeof (unsigned long)); + +#if 0 +#ifdef DEBUG + DPRINTF(("Ret for get_pfn_list is %d\n", ret)); + if (ret >= 0) { + int i, j; + for (i = 0; i < op.u.getmemlist.num_pfns; i += 16) { + fprintf(stderr, "0x%x: ", i); + for (j = 0; j < 16; j++) + fprintf(stderr, "0x%lx ", pfn_buf[i + j]); + fprintf(stderr, "\n"); + } + } +#endif +#endif + return (ret < 0) ? -1 : op.u.getmemlist.num_pfns; +} + +static int +setup_guestos(int xc_handle, + u32 dom, + gzFile kernel_gfd, + unsigned long tot_pages, |