[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] virtual console demo



Working out how to write to the virtual console from a guest domain was
harder for me than I expected.   Once you have console output, figuring
out the rest is easy, right?

Here is the result.  It is a one file xen guest kernel, in the spirit
of mini-os, that writes a message to the Xen-2.0 virtual console.
Feel free to add it to the extras directory if it looks useful.




/*
 * hello.c - xen user domain kernel that demonstrates console output
 *
 * compile with

cc -nostdlib -Wl,-Ttext,0xc0100000 -D__KERNEL__ 
-Ixen-2.0.bk/linux-2.6.10-xenU/include 
-Ixen-2.0.bk/linux-2.6.10-xenU/include/asm-xen -o hellokernel hello.c

 * run demo with:

dom0$ xm create -c kernel=hellokernel
Using config file "/etc/xen/xmdefconfig".
Started domain xmdefconfig, console on port 9652
************ REMOTE CONSOLE: CTRL-] TO QUIT ********
hello, world
farewell cruel world
************ REMOTE CONSOLE EXITED *****************

 */

#include <asm/pgtable.h>
#include <asm-xen/ctrl_if.h>
#include <asm-xen/evtchn.h>
#include <asm-xen/hypervisor.h>

start_info_t *HYPERVISOR_start_info;
extern char shared_info[PAGE_SIZE];

/* _start is the default name ld will use as the entry point.  When xen
 * loads the domain, it will start execution at the elf entry point.
 */

void _start()
{
        /*
         * Grab start_info
         */
        /* The linux build setup_guest() put a start_info_t* into %esi.
         * =S is inline asm code for get output from reg %esi.
         */
        asm("":"=S" (HYPERVISOR_start_info));

        /*
         * Try real console
         */
        /* If the xen hypervisor was compiled with 'make verbose=y' 
         * or 'make debug=y', the emergency console IO call
         * will write to the real console (serial line or VGA)
         * from a guest domain.  Otherwise when called from domU, the
         * console_io calls will be ignored.   dom0 can always write
         * to the real console.
         */
        char realhello[] = "hello, world on the real console\n";
        HYPERVISOR_console_io(CONSOLEIO_write, sizeof(realhello), realhello);


        /*
         * Try virtual console
         */
        /* To write to the xen virtual console, we need to map in the
         * shared page used by the the domain controller interface.  The
         * HYPERVISOR_start_info struct identifies the page table and
         * shared_info pages.
         *
         * The following code maps the shared_info mfn (machine frame number)
         * into this domains address space over the shared_info[] page.
         */


        /*
         * map shared_info page
         */
        /* The pgd page (page global directory - level 2 page table) is
         * constructed by setup_guest() in tools/libxc/xc_linux_build.c
         * Lookup the machine address of ptetab in pgd to construct the
         * machine address of the pte entry for shared_info,
         * and then call mmu_update to change mapping.
         */
        pgd_t *pgd = (pgd_t*)HYPERVISOR_start_info->pt_base;
        int ptetab_ma = pgd_val(pgd[pgd_index((unsigned long)shared_info)])
                & (PAGE_MASK);
        int idx = pte_index((unsigned long)shared_info);
        int pte_ma = ptetab_ma + (idx*sizeof(pte_t));

        mmu_update_t req;
        req.ptr  = pte_ma;
        req.val  = HYPERVISOR_start_info->shared_info|7;
        HYPERVISOR_mmu_update(&req, 1, NULL);

        /*
         * Setup control interface
         */
        control_if_t *ctrl_if = ((control_if_t *)((char *)shared_info + 2048));
        int ctrl_if_evtchn = HYPERVISOR_start_info->domain_controller_evtchn;

        /*
         * Put message on the control interface ring and trigger virtual
         * console writer.
         */
        ctrl_msg_t *msg = ctrl_if->tx_ring;

        char hello[] = "hello, world\n\r";
        msg->type    = CMSG_CONSOLE;
        msg->subtype = CMSG_CONSOLE_DATA;
        msg->length  = sizeof hello;
        memcpy(msg->msg, hello, sizeof(hello)+1);
        ++ctrl_if->tx_req_prod;
        notify_via_evtchn(ctrl_if_evtchn);

        char msg2[] = "farewell cruel world\n\r";
        ++msg;
        msg->type    = CMSG_CONSOLE;
        msg->subtype = CMSG_CONSOLE_DATA;
        msg->length  = sizeof msg2;
        memcpy(msg->msg, msg2, sizeof(msg2)+1);
        ++ctrl_if->tx_req_prod;
        notify_via_evtchn(ctrl_if_evtchn);

        HYPERVISOR_shutdown();
}

/* Create shared_info page.  This page is mapped over by the real shared
 * info page
 */
asm(".align 0x1000; shared_info:;.skip 0x1000;");


/* emit the elf segment Xen builder expects in kernel image */
asm(".section __xen_guest;"
    ".ascii \"GUEST_OS=linux,GUEST_VER=2.6,XEN_VER=2.0,VIRT_BASE=0xC0000000\";"
    ".ascii \",LOADER=generic\";"
    ".ascii \",PT_MODE_WRITABLE\";"
    ".byte  0;"
    );


-------------------------------------------------------
SF email is sponsored by - The IT Product Guide
Read honest & candid reviews on hundreds of IT Products from real users.
Discover which products truly live up to the hype. Start reading now.
http://ads.osdn.com/?ad_id=6595&alloc_id=14396&op=click
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxxx
https://lists.sourceforge.net/lists/listinfo/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.