OCaml with MirageでXen/EC2上で動くOSを作る


[Mirage](http://openmirage.org)を使うと、OCamlでXenやEC2の上で動くOSを作ることができる。

スタブライブラリも用意されているので、Linux、 MacOS Xのような普通のOSで開発して、その後、Xen/EC2上で動くカーネルにコンパイルできる。

http://openmirage.org によると、通常のソフトウェアよりも、より安価に、セキュアに、より詳細な制御が利点です。

## 前提

 * Debian squeeze (x64) 
 * Xen Server 6.1

x64は必須らしい。

## OCaml 4.00.1 の インストール

 3.12.1以降がapt-getで入るなら、そちらでもOK。

まずは、依存ライブラリをインストールする。

    $ sudo apt-get build-dep ocaml
    $ sudo aptitude install git

その後、OCaml 4.00.1をインストールする。

    $ wget http://caml.inria.fr/pub/distrib/ocaml-4.00/ocaml-4.00.1.tar.gz
    $ tar xvzf ocaml-4.00.1.tar.gz
    $ cd ocaml-4.00.1
    $ ./configure
    $ make world.opt
    $ sudo make install

## OPAMのインストール

http://github.com/OCamlPro/opam からOPAMをインストールする。

    $ wget https://raw.github.com/OCamlPro/opam/master/shell/install.sh && sh ./install.sh
    $ opam init
    $ echo 'eval `opam config env`' >> ~/.profile

## Mirage-unixのインストール

    $ opam switch 4.00.1+mirage-unix
    $ eval `opam env`
    $ opam install mirage

lwt_unixが不足しているせいで、ビルドががうまくいかない場合は以下を試す。

    $ opam install ocamlfind lwt base-bigarray base-threads base-unix

## Mirage-xenのインストール

    $ opam switch 4.00.1+mirage-xen
    $ eval `opam env`
    $ opam install ocamlfind lwt
    $ opam install mirage

lwtのビルドがうまくいかない場合は以下を試す。

    $ opam remove base-threads base-unix

## Unixでの開発/実行

    $ git clone git://github.com/mirage/mirage-skeleton.git
    $ cd mirage-skelton/basic
    $ opam switch 4.00.1+mirage-unix
    $ eval `opam config env`
    $ make

実行すると、hello worldが2秒ごとに表示される。

    $ ./hello.native 
    hello
    world
    hello
    world
    …

ソースコードはこんな感じ。

    let main () =
      for_lwt i = 0 to 10 do
        print_endline "hello";
        lwt () = OS.Time.sleep 2.0 in
        print_endline "world";
        Lwt.return ()
     done

    let _ =
      OS.Main.run (main ())

## Xenでの実行

    $ opam switch 4.00.1+mirage-xen
    $ eval `opam config env`
    $ make clean

`_build/hello.xen` が生成される。これをXenでロードするために、以下のようなhello.cfg を準備する。

    name="hello"
    memory=128
    kernel="hello.xen"

起動する。

    # ls
    hello.cfg hello.xen
    # xl create hello.cfg

consoleを表示させるとhello worldが表示されているのが分かる。

    # xl console hello            
    kernel.c: Mirage OS!
    kernel.c:   start_info: 0x1136000(VA)
    kernel.c:     nr_pages: 0x8000
    kernel.c:   shared_inf: 0x23f8d000(MA)
    kernel.c:      pt_base: 0x1139000(VA)
    kernel.c: nr_pt_frames: 0xd
    kernel.c:     mfn_list: 0x10f6000(VA)
    kernel.c:    mod_start: 0x0(VA)
    kernel.c:      mod_len: 0
    kernel.c:        flags: 0x0
    kernel.c:     cmd_line: 
    x86_setup.c:   stack:      0xedc60-0x8edc60
    mm.c: MM: Init
    x86_mm.c:       _text: 0x0(VA)
    x86_mm.c:      _etext: 0x8295f(VA)
    x86_mm.c:    _erodata: 0xa0000(VA)
    x86_mm.c:      _edata: 0xd73e8(VA)
    x86_mm.c: stack start: 0xedc60(VA)
    x86_mm.c:        _end: 0x10f6000(VA)
    x86_mm.c:   start_pfn: 1149
    x86_mm.c:     max_pfn: 8000
    x86_mm.c: Mapping memory range 0x1400000 - 0x8000000
    hello
    Devices: [Xen.Blkif] provider start
    world
    hello
    world
    …

## 参考ドキュメント

 * http://openmirage.org
 * [Hello Mirage World](http://openmirage.org/wiki/hello-world)
 * [Running Mirage Xen kernels](http://openmirage.org/wiki/xen-boot)
 * [Mirage: ML kernels in the clound(ML Workshop 2010)](http://www.slideshare.net/AnilMadhavapeddy/mirage-ml-kernels-in-the-cloud-ml-workshop-2010)
 * [Exokernels(or, making the operating system just another application library)](http://pdos.csail.mit.edu/exo/exo-slides/sld001.htm)