lguest: the documentation, example launcher
A brief document describing how to use lguest. Because lguest doesn't have an ABI we also include an example launcher in the Documentation directory. [jmorris@namei.org: Fix up nat example in documentation] Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Cc: Andi Kleen <ak@suse.de> Signed-off-by: James Morris <jmorris@namei.org> Cc: Matias Zabaljauregui <matias.zabaljauregui@cern.ch> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Родитель
b754416bfe
Коммит
8ca47e0069
|
@ -0,0 +1,27 @@
|
||||||
|
# This creates the demonstration utility "lguest" which runs a Linux guest.
|
||||||
|
|
||||||
|
# For those people that have a separate object dir, look there for .config
|
||||||
|
KBUILD_OUTPUT := ../..
|
||||||
|
ifdef O
|
||||||
|
ifeq ("$(origin O)", "command line")
|
||||||
|
KBUILD_OUTPUT := $(O)
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
# We rely on CONFIG_PAGE_OFFSET to know where to put lguest binary.
|
||||||
|
include $(KBUILD_OUTPUT)/.config
|
||||||
|
LGUEST_GUEST_TOP := ($(CONFIG_PAGE_OFFSET) - 0x08000000)
|
||||||
|
|
||||||
|
CFLAGS:=-Wall -Wmissing-declarations -Wmissing-prototypes -O3 \
|
||||||
|
-static -DLGUEST_GUEST_TOP="$(LGUEST_GUEST_TOP)" -Wl,-T,lguest.lds
|
||||||
|
LDLIBS:=-lz
|
||||||
|
|
||||||
|
all: lguest.lds lguest
|
||||||
|
|
||||||
|
# The linker script on x86 is so complex the only way of creating one
|
||||||
|
# which will link our binary in the right place is to mangle the
|
||||||
|
# default one.
|
||||||
|
lguest.lds:
|
||||||
|
$(LD) --verbose | awk '/^==========/ { PRINT=1; next; } /SIZEOF_HEADERS/ { gsub(/0x[0-9A-F]*/, "$(LGUEST_GUEST_TOP)") } { if (PRINT) print $$0; }' > $@
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f lguest.lds lguest
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,129 @@
|
||||||
|
Rusty's Remarkably Unreliable Guide to Lguest
|
||||||
|
- or, A Young Coder's Illustrated Hypervisor
|
||||||
|
http://lguest.ozlabs.org
|
||||||
|
|
||||||
|
Lguest is designed to be a minimal hypervisor for the Linux kernel, for
|
||||||
|
Linux developers and users to experiment with virtualization with the
|
||||||
|
minimum of complexity. Nonetheless, it should have sufficient
|
||||||
|
features to make it useful for specific tasks, and, of course, you are
|
||||||
|
encouraged to fork and enhance it.
|
||||||
|
|
||||||
|
Features:
|
||||||
|
|
||||||
|
- Kernel module which runs in a normal kernel.
|
||||||
|
- Simple I/O model for communication.
|
||||||
|
- Simple program to create new guests.
|
||||||
|
- Logo contains cute puppies: http://lguest.ozlabs.org
|
||||||
|
|
||||||
|
Developer features:
|
||||||
|
|
||||||
|
- Fun to hack on.
|
||||||
|
- No ABI: being tied to a specific kernel anyway, you can change anything.
|
||||||
|
- Many opportunities for improvement or feature implementation.
|
||||||
|
|
||||||
|
Running Lguest:
|
||||||
|
|
||||||
|
- Lguest runs the same kernel as guest and host. You can configure
|
||||||
|
them differently, but usually it's easiest not to.
|
||||||
|
|
||||||
|
You will need to configure your kernel with the following options:
|
||||||
|
|
||||||
|
CONFIG_HIGHMEM64G=n ("High Memory Support" "64GB")[1]
|
||||||
|
CONFIG_TUN=y/m ("Universal TUN/TAP device driver support")
|
||||||
|
CONFIG_EXPERIMENTAL=y ("Prompt for development and/or incomplete code/drivers")
|
||||||
|
CONFIG_PARAVIRT=y ("Paravirtualization support (EXPERIMENTAL)")
|
||||||
|
CONFIG_LGUEST=y/m ("Linux hypervisor example code")
|
||||||
|
|
||||||
|
and I recommend:
|
||||||
|
CONFIG_HZ=100 ("Timer frequency")[2]
|
||||||
|
|
||||||
|
- A tool called "lguest" is available in this directory: type "make"
|
||||||
|
to build it. If you didn't build your kernel in-tree, use "make
|
||||||
|
O=<builddir>".
|
||||||
|
|
||||||
|
- Create or find a root disk image. There are several useful ones
|
||||||
|
around, such as the xm-test tiny root image at
|
||||||
|
http://xm-test.xensource.com/ramdisks/initrd-1.1-i386.img
|
||||||
|
|
||||||
|
For more serious work, I usually use a distribution ISO image and
|
||||||
|
install it under qemu, then make multiple copies:
|
||||||
|
|
||||||
|
dd if=/dev/zero of=rootfile bs=1M count=2048
|
||||||
|
qemu -cdrom image.iso -hda rootfile -net user -net nic -boot d
|
||||||
|
|
||||||
|
- "modprobe lg" if you built it as a module.
|
||||||
|
|
||||||
|
- Run an lguest as root:
|
||||||
|
|
||||||
|
Documentation/lguest/lguest 64m vmlinux --tunnet=192.168.19.1 --block=rootfile root=/dev/lgba
|
||||||
|
|
||||||
|
Explanation:
|
||||||
|
64m: the amount of memory to use.
|
||||||
|
|
||||||
|
vmlinux: the kernel image found in the top of your build directory. You
|
||||||
|
can also use a standard bzImage.
|
||||||
|
|
||||||
|
--tunnet=192.168.19.1: configures a "tap" device for networking with this
|
||||||
|
IP address.
|
||||||
|
|
||||||
|
--block=rootfile: a file or block device which becomes /dev/lgba
|
||||||
|
inside the guest.
|
||||||
|
|
||||||
|
root=/dev/lgba: this (and anything else on the command line) are
|
||||||
|
kernel boot parameters.
|
||||||
|
|
||||||
|
- Configuring networking. I usually have the host masquerade, using
|
||||||
|
"iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE" and "echo 1 >
|
||||||
|
/proc/sys/net/ipv4/ip_forward". In this example, I would configure
|
||||||
|
eth0 inside the guest at 192.168.19.2.
|
||||||
|
|
||||||
|
Another method is to bridge the tap device to an external interface
|
||||||
|
using --tunnet=bridge:<bridgename>, and perhaps run dhcp on the guest
|
||||||
|
to obtain an IP address. The bridge needs to be configured first:
|
||||||
|
this option simply adds the tap interface to it.
|
||||||
|
|
||||||
|
A simple example on my system:
|
||||||
|
|
||||||
|
ifconfig eth0 0.0.0.0
|
||||||
|
brctl addbr lg0
|
||||||
|
ifconfig lg0 up
|
||||||
|
brctl addif lg0 eth0
|
||||||
|
dhclient lg0
|
||||||
|
|
||||||
|
Then use --tunnet=bridge:lg0 when launching the guest.
|
||||||
|
|
||||||
|
See http://linux-net.osdl.org/index.php/Bridge for general information
|
||||||
|
on how to get bridging working.
|
||||||
|
|
||||||
|
- You can also create an inter-guest network using
|
||||||
|
"--sharenet=<filename>": any two guests using the same file are on
|
||||||
|
the same network. This file is created if it does not exist.
|
||||||
|
|
||||||
|
Lguest I/O model:
|
||||||
|
|
||||||
|
Lguest uses a simplified DMA model plus shared memory for I/O. Guests
|
||||||
|
can communicate with each other if they share underlying memory
|
||||||
|
(usually by the lguest program mmaping the same file), but they can
|
||||||
|
use any non-shared memory to communicate with the lguest process.
|
||||||
|
|
||||||
|
Guests can register DMA buffers at any key (must be a valid physical
|
||||||
|
address) using the LHCALL_BIND_DMA(key, dmabufs, num<<8|irq)
|
||||||
|
hypercall. "dmabufs" is the physical address of an array of "num"
|
||||||
|
"struct lguest_dma": each contains a used_len, and an array of
|
||||||
|
physical addresses and lengths. When a transfer occurs, the
|
||||||
|
"used_len" field of one of the buffers which has used_len 0 will be
|
||||||
|
set to the length transferred and the irq will fire.
|
||||||
|
|
||||||
|
Using an irq value of 0 unbinds the dma buffers.
|
||||||
|
|
||||||
|
To send DMA, the LHCALL_SEND_DMA(key, dma_physaddr) hypercall is used,
|
||||||
|
and the bytes used is written to the used_len field. This can be 0 if
|
||||||
|
noone else has bound a DMA buffer to that key or some other error.
|
||||||
|
DMA buffers bound by the same guest are ignored.
|
||||||
|
|
||||||
|
Cheers!
|
||||||
|
Rusty Russell rusty@rustcorp.com.au.
|
||||||
|
|
||||||
|
[1] These are on various places on the TODO list, waiting for you to
|
||||||
|
get annoyed enough at the limitation to fix it.
|
||||||
|
[2] Lguest is not yet tickless when idle. See [1].
|
Загрузка…
Ссылка в новой задаче