This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
Home Products Support Community News


[Xen-devel] virtual console demo

To: xen-devel@xxxxxxxxxxxxxxxxxxxxx
Subject: [Xen-devel] virtual console demo
From: David Becker <becker@xxxxxxxxxxx>
Date: Sat, 19 Mar 2005 13:43:29 -0500
Delivery-date: Sat, 19 Mar 2005 18:46:40 +0000
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-archive: <http://sourceforge.net/mailarchive/forum.php?forum=xen-devel>
List-help: <mailto:xen-devel-request@lists.sourceforge.net?subject=help>
List-id: List for Xen developers <xen-devel.lists.sourceforge.net>
List-post: <mailto:xen-devel@lists.sourceforge.net>
List-subscribe: <https://lists.sourceforge.net/lists/listinfo/xen-devel>, <mailto:xen-devel-request@lists.sourceforge.net?subject=subscribe>
List-unsubscribe: <https://lists.sourceforge.net/lists/listinfo/xen-devel>, <mailto:xen-devel-request@lists.sourceforge.net?subject=unsubscribe>
Sender: xen-devel-admin@xxxxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.6+20040722i
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/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);

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


/* 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.
Xen-devel mailing list

<Prev in Thread] Current Thread [Next in Thread>
  • [Xen-devel] virtual console demo, David Becker <=