Saturday, June 23, 2012

Xen - host Arch Linux - guest Arch Linux

This is a small guide that tries to show you how I installed Xen and run Arch Linux as a guest on my host Arch Linux.


You are expected to install Arch Linux. The wiki is your resource. And for Xen this wiki is your main resource.

But the Xen package seems to be out of date, luckely one of the comment gives a link for a more up to date source. So I download the source:

cd ~/builds
hg clone https://bitbucket.org/encbladexp/aur

Then I followed the AUR wiki installing packages to install Xen.

When it is installed, you need to make some adjustments to both Grub boot list in /boot/grub/menu.lst (I asume your using Grub) and /etc/rc.conf. The changes needed is found in the file ~/builds/aur/xen/xen.install.

But these changes didnt work for me, I needed to modify menu.lst:

# (2) Xen
title Xen with Arch Linux
root (hd0,0)
kernel /boot/xen.gz dom0_mem=512M dom0_max_vcpus=4 dom0_vcpus_pin
module /boot/vmlinuz-linux root=/dev/sdaXX ro
module /boot/initramfs-linux.img

As you can compare I changed the "root=" option (Note /dev/sdaXX is just an example. This is the parition that your HOST OS uses and not the GUEST OS see below where we format a new empty partition). Now after reboot choose "Xen with Arch Linux" from your Grub menu.
Next I tried to setup a guest Arch Linux in Xen, this is called domU (U for User). I struggeled with this step, things seems to be scattered all over the wiki page and some is out dated. So this is my attempt to organize this process.

## /dev/sdbXX is an example of a block device
$ mkfs.ext4 /dev/sdbXX    ## format partition
$ mkdir /tmp/install
$ mount /dev/sdbXX /tmp/install
$ mkdir -p /tmp/install/{dev,proc,sys} /tmp/install/var/lib/pacman /tmp/install/var/cache/pacman/pkg
$ mount -o bind /dev /tmp/install/dev
$ mount -t proc none /tmp/install/proc
$ mount -o bind /sys /tmp/install/sys
$ pacman -Sy -r /tmp/install --cachedir /tmp/install/var/cache/pacman/pkg -b /tmp/install/var/lib/pacman base
$ cp -r /etc/pacman* /tmp/install/etc
$ chroot /tmp/install /bin/bash
$ vi /etc/fstab
    /dev/xvda               /           ext4    defaults                0       1
# Find and uncomment all 6 console and add one as follows:
$ vi /etc/inittab
    c1:2345:respawn:/sbin/agetty -8 38400 hvc0 linux
    #c1:2345:respawn:/sbin/agetty -8 38400 tty1 linux
    #c2:2345:respawn:/sbin/agetty -8 38400 tty2 linux
    #c3:2345:respawn:/sbin/agetty -8 38400 tty3 linux
    #c4:2345:respawn:/sbin/agetty -8 38400 tty4 linux
    #c5:2345:respawn:/sbin/agetty -8 38400 tty5 linux
    #c6:2345:respawn:/sbin/agetty -8 38400 tty6 linux 
$ exit  ## exit chroot
$ umount /tmp/install/dev
$ umount /tmp/install/proc
$ umount /tmp/install/sys
$ umount /tmp/install
$ vi /etc/xen/dom01     ## create config file
    #  -*- mode: python; -*-
    kernel = "/boot/vmlinuz-linux"
    ramdisk = "/boot/xen-initramfs-linux.img"
    memory = 256
    name = "dom01"
    vif = [ 'mac=00:16:3e:00:01:01' ]
    disk = [ 'phy:/dev/sdaXX,xvda,w' ]
    dhcp="dhcp"
    hostname = "ooga"
    root = "/dev/xvda ro"
Now we have a working filesystem for the guest OS, usuable kernel from the host system (you can compile your own custom kernel if you like). But because we use the same kernel we need to load some Xen specific modules early on for the guest OS to boot. This is done by a tool called mkinitcpio. This tool needs some configuration files. You can modify the ones that comes with Arch Linux but I copied the files and modified them. These are the files I copied and edited:
$ cat /etc/mkinitcpio.d/xen-linux.preset
# mkinitcpio preset file for the 'linux' package
    
ALL_config="/etc/mkinitcpio.conf"
ALL_kver="/boot/vmlinuz-linux"
    
PRESETS=('default' 'fallback')

default_config="/etc/xen-mkinitcpio.conf"
default_image="/boot/xen-initramfs-linux.img"
#default_options=""
    
fallback_config="/etc/xen-mkinitcpio.conf"
fallback_image="/boot/xen-initramfs-linux-fallback.img"
fallback_options="-S autodetect"
$ cat /etc/xen-mkinitcpio.conf
# vim:set ft=sh
# MODULES
# The following modules are loaded before any boot hooks are
# run.  Advanced users may wish to specify all system modules
# in this array.  For instance:
#     MODULES="piix ide_disk reiserfs"
MODULES="xen-blkfront xen-fbfront xenfs xen-netfront xen-kbdfront"

# BINARIES
# This setting includes any additional binaries a given user may
# wish into the CPIO image.  This is run last, so it may be used to
# override the actual binaries included by a given hook
# BINARIES are dependency parsed, so you may safely ignore libraries
BINARIES=""

# FILES
# This setting is similar to BINARIES above, however, files are added
# as-is and are not parsed in any way.  This is useful for config files.
# Some users may wish to include modprobe.conf for custom module options
# like so:
#    FILES="/etc/modprobe.d/modprobe.conf"
FILES=""

# HOOKS
# This is the most important setting in this file.  The HOOKS control the
# modules and scripts added to the image, and what happens at boot time.
# Order is important, and it is recommended that you do not change the
# order in which HOOKS are added.  Run 'mkinitcpio -H ' for
# help on a given hook.

# 'base' is _required_ unless you know precisely what you are doing.
# 'udev' is _required_ in order to automatically load modules
# 'filesystems' is _required_ unless you specify your fs modules in MODULES
# Examples:
##   This setup specifies all modules in the MODULES setting above.
##   No raid, lvm2, or encrypted root is needed.
#    HOOKS="base"
#
##   This setup will autodetect all modules for your system and should
##   work as a sane default
#    HOOKS="base udev autodetect pata scsi sata filesystems"
#
##   This is identical to the above, except the old ide subsystem is
##   used for IDE devices instead of the new pata subsystem.
#    HOOKS="base udev autodetect ide scsi sata filesystems"
#
##   This setup will generate a 'full' image which supports most systems.
##   No autodetection is done.
#    HOOKS="base udev pata scsi sata usb filesystems"
#

##   This setup assembles a pata mdadm array with an encrypted root FS.
##   Note: See 'mkinitcpio -H mdadm' for more information on raid devices.
#    HOOKS="base udev pata mdadm encrypt filesystems"
#
##   This setup loads an lvm2 volume group on a usb device.
#    HOOKS="base udev usb lvm2 filesystems"
#
##   NOTE: If you have /usr on a separate partition, you MUST include the
#    usr, fsck and shutdown hooks.
HOOKS="base udev autodetect pata scsi sata filesystems usbinput fsck"

# COMPRESSION
# Use this to compress the initramfs image. By default, gzip compression
# is used. Use 'cat' to create an uncompressed image.
#COMPRESSION="gzip"
#COMPRESSION="bzip2"
#COMPRESSION="lzma"
#COMPRESSION="xz"
#COMPRESSION="lzop"

# COMPRESSION_OPTIONS
# Additional options for the compressor
#COMPRESSION_OPTIONS=""
Then run
$ mkinitcpio -p xen-linux

This will create an initial filesystem on ram-memory that is loaded before your filesystem and makes it possible for the guest OS to boot. Now you can boot the guest OS with
$ xm create -c dom01
And you should see it boot with:
Using config file "/etc/xen/dom01".
Started domain dom01 (id=24)
                            [    0.076618] i8042: No controller found
[    0.137323] drivers/rtc/hctosys.c: unable to open rtc device (rtc0)
:: running early hook [udev]
:: running hook [udev]
:: Triggering uevents...
:: performing fsck on '/dev/xvda'
/dev/xvda: clean, 27237/2564096 files, 349439/10240000 blocks
:: mounting '/dev/xvda' on real root
:: running cleanup hook [udev]
INIT: version 2.88 booting
 
 > Arch Linux
 
 > http://www.archlinux.org


Arch Linux 3.4.3-1-ARCH (hvc0)

(none) login:
Have fun!

Tuesday, January 3, 2012

Whats with FreeBSD and cross compiling?

From the beginning me and FreeBSD didn't go along very well when I was working on RouterStation Pro. Maybe it was because of my approach to cross-compiling. In my head I want to do everything on the host computer and then "deploy" it on the target.

Now cross compiling the kernel and world did work out for me in the end, and boy do I love how it works:

make TARGET=mips TARGET_ARCH=mipseb buildworld
make TARGET=mips TARGET_ARCH=mipseb KERNCONF=AR71XX buildkernel

Ok, I still hate the fact that I need to tell FreeBSD explicitly to not clean-up before compiling again when I just did a small change in the kernel, added a printf for instance? So then I change the buildkernel command to:

make TARGET=mips TARGET_ARCH=mipseb KERNFAST=AR71XX buildkernel

KERNFAST will just recompile the modified folder and then link everything, so why don't FreeBSD have KERNFAST as default?

Well you will get used to that eventually, so now we have a compiled kernel and world (I am not going deep into this, how do the kernel boot? What about the boot loader? etc..). Ok, now if I want rsync on my target what is the next step?

rsync is a third-party program residing under the /usr/ports folder, and somehow its not so easy to cross-compile. Why? I don't know, there is surely good reasons and one need to study the ports framework. But hasn't that bother anyone?

One day I hope to find an easy way to cross-compile ports, something like:

cd /usr/ports/somewhere
make TARGET=mips TARGET_ARCH=mipseb install

Lets say that will install somewhere in /usr/obj/mips.mipseb/... if so then I will die a happy man =)

While we are wishful, it would be nice to have things like:

PORTS_OVERRIDE=...
WITHOUT_PORTS=...
make buildports
make installports

just things nice to have, why not add a ports configuration file? =D

Tuesday, February 16, 2010

Code rewrite!!

Hi again! I was searching the web for other people writing numerical solvers in Haskell and found this nice guy called James. His idea is to extract the tolerance test to a new function. This function takes an infinite list of approximated x values and then take the value that gives a relative error less than the specified tolerance.

Now relative error is calculated as absolute value of (x(n-1)-x(n))/x(n-1). I changed his convergence function and corrected a mistake in it, cause he forgot to take the absolute value for the whole expression of relative error. Here is my code:

module HaskNum where

converge :: (Ord a, Fractional a) => a -> [a] -> a
converge tol (old:new:xs) = if reldiff old new <= tol
then new
else converge tol (new:xs)
where reldiff old new = abs $ (old-new) / old
converge tol (x:_) = x -- to handle when some functions
-- succeed from the first time

What I did was put it in a module I call HaskNum that will grow with time. And here is the new version of my previous four functions:

bisec :: (F -> F) -> (F,F) -> [F]
bisec f (a, b)
| f(c) == 0 = [c]
| f(a)*f(c) < 0 = c : bisec f (a,c)
| otherwise = c : bisec f (c,b)
where c = (a+b)/2
fpi :: (F -> F) -> F -> [F]
fpi = iterate
newton :: (F -> F) -> (F -> F) -> F -> [F]
newton f f' = iterate xc
where xc xi = xi - f(xi)/f'(xi)
secant :: (F -> F) -> (F, F) -> [F]
secant f (x0, x1) = xc : secant f (x1, xc)
where xc = x1 - f(x1)*(x1-x0)/(f(x1)-f(x0))

Now things look really nice! And oh here how u can call one of them with a function that u define:

main = do
let answer = (converge 0.0000005 . bisec (func)) (0,1)
print answer

An interesting note is that all the methods except the Bisection Method gives the answer xc=0.6823278. The Bisection Method gives 0.682328, i.e. one digit less. Now that is a mystery for me, but I would guess its something with computer arithmetic and the intermediate operations.

Friday, January 22, 2010

Newton & Secant Methods

Been a while since I added new methods, but here comes two.

The first one is called Newton's method. Basically it will "draw" a tangent that goes through the initial guess. Then in the next iteration it will draw a second tangent for the x point where the first tangent crossed the x-axis and so on. You need to supply it an initial guess.

The formula is x = x0 - f(x0)/f'(x0).

type F = Float
newton :: (F -> F) -> (F -> F) -> F -> Integer -> [F]
newton _ _ _ 0 = []
newton f f' xi k = xc : newton f f' xc (k-1)
where xc = xi - f(xi)/f'(xi)

func :: F -> F
func x = x^3+x-1

func' :: F -> F
func' x = 3*x^2+1

main = do
let answer = newton (func) (func') 1 4
print answer

The second method is called the Secant method. Instead of using a tangent it uses a secant line, which is a line intersecting two points on the function curve. In the next iteration the next secant line will go through the last two x values. In this method like in the Bisection Method we need to choose the two initial guesses around the true solution! In other words for the two initial guesses x0, x1 the following must be true f(x0)*f(x1)<0 to guarantee a solution for a continues function.

The formula is x = x1 - f(x1)(x1-x0)/(f(x1)-f(x0)).


type F = Float
secant :: (F -> F) -> F -> F -> Integer -> [F]
secant _ _ _ 0 = []
secant f x0 x1 k = xc : secant f x1 xc (k-1)
where xc = x1 - f(x1)*(x1-x0)/(f(x1)-f(x0))

func :: F -> F
func x = x^3+x-1

main = do
let answer = secant (func) 0.5 1 4
print answer

Saturday, January 9, 2010

Bisection Method vs Fixed-Point Iteration

How much faster is FPI compared to the Bisection Method? For that we need to think about accuracy. Or the error compared to the true solution. Now I know we don't know the true solution otherwise we would not be needing these numeric methods! But we can enclose the true solution inside an interval where we know that it lies in it (well for a continuous functions in the interval of interest).

Starting from The Bisection Method we know for each step the interval [a,b] is cut in half! After n steps our new interval [an, bn] have the length (b-a)/2^n. But choosing the solution to be the midpoint of the n-interval we know the true solution (if it is not the midpoint) is within an interval of length (b-a)/2^(n+1).

A solution is correct within p decimal places if the error |xc-r|<0.5*10^-p.

How many times do we need to cut the interval [0,1] in half to get an approximation with 6 correct digits for the problem f(x)=x^3+x-1 using the Bisection Method?

Solving (b-a)/2^(n+1) < 0.5*10^(-6) => n = 19.9. Which means The Bisection method will need 20 steps for 6 correct digits. The approximated solution with 6 correct digits is xc=0.682327.

Using FPI with g(x)=(1+2x^3)/(1+3x^2) and an initial guess x0=1. After 4 steps we get the same solution. A major improvement of number of steps by using FPI with a "nice" g(x)!

Fixed-Point Iteration

Fixed-Point Iteration, FPI for short, is another equation solving method. But! Unlike The Bisection Method you have to exercise more caution.

First we need to rewrite the initial problem from f(x)=0 to g(x)=x and iterate until the solution stabilizes. Here is the code for FPI:

fpi :: (F -> F) -> F -> Integer -> [F]
fpi _ _ 0 = []
fpi g x0 k = xc : fpi g xc (k-1)
where xc = g(x0)

The code is simple and the method returns a list with the intermediate approximated solutions. The best solution is in the end of the list.

Let us try to solve the same equation as the one presented in The Bisection Method, f(x)=x^3+x-1. Re-writing it we would get the equation: x=1-x^3 thus g(x)=1-x^3 (remember it should be of the form g(x)=x). But FPI will fail and the list returned would look like:

[0.0,1.0,0.0,1.0,0.0,1.0,0.0,1.0,0.0,1.0,0.0,...]

That is no good! But if we happen to add 2x^3 to both sides of the equation, and rearrange things we get: x = (1+2x^3)/(1+3x^2). So using g(x)=(1+2x^3)/(1+3x^2) we will have a good approximation in just 6 steps!

[0.75,0.68604654,0.68233955,0.68232775,0.6823278,
0.6823278]

Why? Well because there is a theorem that says: Assume g(x) is continuously differentiable, and g(r)=r, and |g'(r)|<1. Then FPI converges to the fixed point r for sufficiently close initial guess to r.

Checking |g'(r)| (r≃0.68) for the first attempt we can see that it is larger than 1, but not the second attempt.

FPI can converge to a solution faster than The Bisection Method, but we need to re-write the original solution. Because we dont now the solution r beforehand we can test re-writing it differently until FPI succeeds.

Bisection Method

Hi fellow internet user,

I am a computer engineering student in my last year (not quite true but its a long story!). I have recently learned Haskell which I quite fancy for the moment. I was wondering how I can find the motivation to dwell into this particulate programming language more than just passing my course assignments! Fortunate or not I have not passed my Numerical Analysis course. So while waiting for the re-exam in late August I will rewrite some of the numerical methods presented to me in the course in Haskell instead of as Matlab scripts.

And I start with an easy one, a bracketing method called The Bisection Method. Without further ado here is my code:

type F = Float

bisec :: (F -> F) -> (F,F) -> F -> F
bisec f (a, b) tol
| (b-a)/2 < tol = (a+b)/2
| f(c) == 0 = c
| f(a)*f(c) < 0 = bisec f (a,c) tol
| otherwise = bisec f (c,b) tol
where c = (a+b)/2

func :: F -> F
func x = x^3+x-1

main = do
let answer = bisec (func) (0, 2) 0.0000005
print answer