Skip to content

Commit

Permalink
add: original codes of Definitive Guide to the Xen Hypervisor
Browse files Browse the repository at this point in the history
  • Loading branch information
koukaipan committed Aug 25, 2013
1 parent cf58ddc commit 51c12ca
Show file tree
Hide file tree
Showing 60 changed files with 4,586 additions and 0 deletions.
23 changes: 23 additions & 0 deletions COPYING
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
Source files taken from the Xen distribution are governed by their original license.

Original source files in this distribution are distributed under the following license:

Copyright (c) 2007 David Chisnall

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
2 changes: 2 additions & 0 deletions chapter11/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
enumerate_vms: enumerate_vms.c
c99 $^ -lxenapi -lcurl -o $@
93 changes: 93 additions & 0 deletions chapter11/enumerate_vms.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
#include <stdio.h>

#include <curl/curl.h>
#include <xen/api/xen_all.h>

typedef struct
{
xen_result_func func;
void *handle;
} xen_comms;

static char *url;

static size_t
write_func(void *ptr, size_t size, size_t nmemb, xen_comms *comms)
{
size_t n = size * nmemb;
return comms->func(ptr, n, comms->handle) ? n : 0;
}


static int
call_func(const void *data, size_t len, void *user_handle,
void *result_handle, xen_result_func result_func)
{
(void)user_handle;

CURL *curl = curl_easy_init();
if (!curl) {
return -1;
}

xen_comms comms = {
.func = result_func,
.handle = result_handle
};

curl_easy_setopt(curl, CURLOPT_URL, url);
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, &write_func);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &comms);
curl_easy_setopt(curl, CURLOPT_POST, 1);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, len);

CURLcode result = curl_easy_perform(curl);

curl_easy_cleanup(curl);

return result;
}

int main(int argc, char **argv)
{
if (argc != 4)
{
fprintf(stderr, "Usage:\n\n%s <url> <username> <password>\n", argv[0]);
}

url = argv[1];

/* General setup */
xen_init();
curl_global_init(CURL_GLOBAL_ALL);

xen_session *session =
xen_session_login_with_password(call_func, NULL, argv[2], argv[3]);

if(session->ok)
{
/* Get the host */
xen_host host;
xen_session_get_this_host(session, &host, session);
/* Get the set of VMs */
struct xen_vm_set * VMs;
xen_host_get_resident_vms(session, &VMs, host);
/* Print the names */
for(unsigned int i=0 ; i<VMs->size ; i++)
{
char * name;
xen_host_get_name_label(session, &name, host);
printf("VM %d: %s\n", i, name);
}
}
else
{
printf(stderr, "Connection failed\n");
}
xen_session_logout(session);
curl_global_cleanup();
xen_fini();
return 0;
}
90 changes: 90 additions & 0 deletions chapter12/sched_trivial.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#include <xen/lib.h>
#include <xen/sched.h>
#include <xen/sched-if.h>


/* CPU Run Queue */
static struct vcpu * vcpu_list_head = NULL;
static struct vcpu * vcpu_list_tail = NULL;
unsigned int vcpus = 0;
#define VCPU_NEXT(_vcpu) ((struct vcpu*)_vcpu->sched_priv)

/* Add a VCPU */
int trivial_init_vcpu(struct vcpu * v)
{
if (vcpu_list_head == NULL)
{
vcpu_list_head = vcpu_list_tail = v;
}
else
{
vcpu_list_tail->sched_priv = vcpu_list_tail = v;
}
v->sched_priv = NULL;
return 0;
}

/* Remove a VCPU */
void trivial_destroy_vcpu(struct vcpu * v)
{
if(v == vcpu_list_head)
{
vcpu_list_head = VCPU_NEXT(v);
}
else
{
struct vcpu * last = NULL;
struct vcpu * current = vcpu_list_head;
while(current != v && current != NULL)
{
last = current;
current = VCPU_NEXT(current);
}
if(current != NULL)
{
last->sched_priv = VCPU_NEXT(current);
}
}
}

/* Move the front VCPU to the back */
static inline void increment_run_queue(void)
{
vcpu_list_tail->sched_priv = vcpu_list_head;
vcpu_list_tail = vcpu_list_head;
vcpu_list_head = VCPU_NEXT(vcpu_list_tail);
vcpu_list_tail->sched_priv = NULL;
}

/* Pick a VCPU to run */
struct task_slice trivial_do_schedule(s_time_t)
{
struct task_slice ret;
/* Fixed-size quantum */
ret.time = MILLISECS(10);
struct * vcpu head = vcpu_list_head;
do
{
/* Find a runnable VCPU */
increment_run_queue();
if(vcpu_runnable(vcpu_list_head))
{
ret.task = vcpu_list_head;
}
} while(head != vcpu_list_head);
/* Return the idle task if there isn't one */
ret.task = ((struct vcpu*)__get_per_cpu(schedule_data)).idle);
return ret;
}

struct scheduler sched_trivial_def = {
.name = "Trivial Round Robin Scheduler",
.opt_name = "trivial",
.sched_id = XEN_SCHEDULER_SEDF,

.init_vcpu = trivial_init_vcpu,
.destroy_vcpu = trivial_destroy_vcpu,

.do_schedule = trivial_do_schedule,
};

30 changes: 30 additions & 0 deletions chapter13/isXen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#include <stdio.h>
#include <sys/types.h>
#include <string.h>

typedef union
{
uint32_t r[3];
char string[12];
} cpuid_t;

#define CPUID(command, result) \
__asm __volatile(\
"CPUID"\
: "=b" (result.r[0]), "=c" (cpu.r[1]), "=d" (cpu.r[2])\
: "a" (command));

int main(void)
{
cpuid_t cpu;
CPUID(0,cpu);
if(strncmp(cpu.string, "XenVMMXenVMM", 12) == 0)
{
printf("Running as a Xen HVM guest\n");
}
else
{
printf("Running on native hardware or a non-Xen hypervisor.\n");
}
return 0;
}
15 changes: 15 additions & 0 deletions chapter2/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
CPPFLAGS += -I../xen/xen/include/public
LDFLAGS += -nostdlib -T example.lds
CFLAGS += -std=c99
ASFLAGS = -D__ASSEMBLY__

.PHONY: all

all: testkernel

testkernel: bootstrap.x86_32.o kernel.o
$(CC) $(LDFLAGS) $^ -o testkernel

clean:
rm -f *.o
rm -f testkernel
38 changes: 38 additions & 0 deletions chapter2/bootstrap.x86_32.S
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
#include <arch-x86_32.h>


.section __xen_guest
.ascii "GUEST_OS=Hacking_Xen_Example"
.ascii ",XEN_VER=xen-3.0"
.ascii ",VIRT_BASE=0x0"
.ascii ",ELF_PADDR_OFFSET=0x0"
.ascii ",HYPERCALL_PAGE=0x2"
.ascii ",PAE=no"
.ascii ",LOADER=generic"
.byte 0
.text

.globl _start, shared_info, hypercall_page

_start:
cld
lss stack_start,%esp
push %esi
call start_kernel

stack_start:
.long stack+8192, FLAT_KERNEL_SS

/* Unpleasant -- the PTE that maps this page is actually overwritten */
/* to map the real shared-info page! :-) */
.org 0x1000
shared_info:
.org 0x2000

hypercall_page:
.org 0x3000

ES = 0x20
ORIG_EAX = 0x24
EIP = 0x28
CS = 0x2C
25 changes: 25 additions & 0 deletions chapter2/debug.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <stdint.h>
#include <xen.h>

#define __STR(x) #x
#define STR(x) __STR(x)

#define _hypercall3(type, name, a1, a2, a3) \
({ \
long __res, __ign1, __ign2, __ign3; \
__asm volatile ( \
"call hypercall_page + ("STR(__HYPERVISOR_##name)" * 32)"\
: "=a" (__res), "=b" (__ign1), "=c" (__ign2), \
"=d" (__ign3) \
: "1" ((long)(a1)), "2" ((long)(a2)), \
"3" ((long)(a3)) \
: "memory" ); \
(type)__res; \
})

static inline int
HYPERVISOR_console_io(
int cmd, int count, char *str)
{
return _hypercall3(int, console_io, cmd, count, str);
}
18 changes: 18 additions & 0 deletions chapter2/domain_config
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# -*- mode: python; -*-
#====================================================
#Python configuration setup for 'xm create'. This
#script sets the parameters used when a domain is
#created using 'xm create'. You use a separate script
#for each domain you want to create, or you can set the
#parameters for the domain on the xm command line.
#====================================================
#Kernel image file.
kernel = "testkernel"
# Initial memory allocation (in megabytes) for the new
# domain.
memory = 32
# A name for your domain. All domains must have
# different names.
name = "Simplest_Kernel"

on_crash = 'destroy'
27 changes: 27 additions & 0 deletions chapter2/example.lds
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
OUTPUT_FORMAT("elf32-i386", "elf32-i386", "elf32-i386")
OUTPUT_ARCH(i386)
ENTRY(_start)
SECTIONS
{
. = 0x0; /* Start of the output file */

_text = .; /* Text and read-only data */

.text : {
*(.text)
} = 0x9090

_etext = .; /* End of text section */

.rodata : { /* Read only data section */
*(.rodata)
*(.rodata.*)
}

.data : { /* Data */
*(.data)
}

_edata = .; /* End of data section */

}
13 changes: 13 additions & 0 deletions chapter2/kernel.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#include <stdint.h>
#include <xen.h>
#include "debug.h"

/* Some static space for the stack */
char stack[8192];

/* Main kernel entry point, called by trampoline */
void start_kernel(start_info_t * start_info)
{
HYPERVISOR_console_io(CONSOLEIO_write,12,"Hello World\n");
while(1);
}
Loading

0 comments on commit 51c12ca

Please sign in to comment.