Xen ARM with Virtualization Extensions/Multiboot

From Xen
Revision as of 13:59, 15 October 2013 by Ijc (talk | contribs)
Jump to navigationJump to search

Multiboot on ARM Specification

In order to boot Xen on a system it is necessary to load several binaries and pass them to the Xen kernel at boot time. These are:

  • Xen itself (primary boot image)
  • A domain 0 kernel image
  • An (optional) domain 0 ramdisk
  • A DTB describing the hardware platofrm
  • ...

On x86 this is achieved using the Multiboot Specification. However multiboot1 is very x86 specific. multiboot2 is cross platform but doesn't currently support ARM. Both are more complicated than what is needed on ARM.

FDT Based Protocol

A proposal exists for a simpler Device Tree based system.

This is described in http://xenbits.xen.org/gitweb/?p=xen.git;a=blob;f=docs/misc/arm/device-tree/booting.txt;h=08ed7751859dbe2d2c32d86d7df371057d7b45a4;hb=HEAD

Andre Przywara has proposed some modifications to the above which make it more generic, see: http://thread.gmane.org/gmane.linux.linaro.announce.boot/326

The specific compatible strings to be used need to be defined, I've used something vaguely sensible sounding below.

GrUB

Linaro is working towards using GrUB as the standard bootloader on therefore it is necessary to have some grub syntax which can be used to cause the multiboot nodes to be added to the chosen node of the DTB.

The grub syntax should be compatible with what the existing x86 tools (e.g. update-grub) generate. On my Debian x86 system such a stanza looks like:

menuentry 'Debian GNU/Linux, with Xen 4.1-amd64 and Linux 3.10-3-amd64' --class debian --class gnu-linux --class gnu --class os --class xen {
        insmod part_msdos
        insmod ext2
        set root='(hd0,msdos1)'
        search --no-floppy --fs-uuid --set=root c4291ab1-d3ad-4c70-ab97-e6c8cca0af2b
        echo    'Loading Xen 4.1-amd64 ...'
        multiboot       /xen-4.1-amd64.gz placeholder  
        echo    'Loading Linux 3.10-3-amd64 ...'
        module  /vmlinuz-3.10-3-amd64 placeholder root=/dev/mapper/disks-root ro resume=/dev/mapper/disks-swap quiet
        echo    'Loading initial ramdisk ...'
        module  /initrd.img-3.10-3-amd64
}

The relevant commands here are the "multiboot" and "module" commands.

Note: on x86 these commands relate to the x86 multiboot version 1 support. This is very x86 specific and will never be supported on ARM. multiboot2 (which supports multiple architectures, but doesn't include ARM) has it's own separate "multiboot2" command and it is reasonable to assume that any future revisions of multiboot which might incorporate ARM support will have their own unique keyword. Hence there is no concern about a clash with the multiboot command name.

 Command: multiboot [KERNEL] [COMMAND LINE...]
       Specifies a kernel to be loaded which expects to be passed a DTB
       containing a set of modules in the /chosen node as defined in
       the multiboot device tree bindings.
       
       [KERNEL] is the path to the kernel binary.
       
       All remaining arguments should be passed as the command line
       ("/chosen/bootargs") to the kernel.
       
       (NB: "placeholder" in the above example is a weird x86-ism, Xen
       will ignore it, there is no need to special case it in grub on
       ARM)
 Command: module [PATH] [COMMAND LINE...]
       Specifies a module to be loaded and passed via a module node
       under /chosen. This option may be used multiple times to pass
       multiple modules.
       [PATH] is the path to the binary to be loaded. It shall be
       loaded into RAM at an address to be referenced as described in
       the multiboot device tree bindings.
       
       The remainder of the command line shall be used as the modules
       "bootargs" property.
       
       Each module will be given a default compatibility property based
       on the order in which the modules are added.
       
       The first module specified in this way will be:
               compatible = "multiboot,linux-zimage", "boot,module"
       The second module specified in this way will be:
               compatible = "multiboot,linux-ramdisk", "boot,module"
       All subsequent modules will be:
               compatible = "boot,module"

Possible extension:

       Allow the module command to take an optional:
               --type <compatible-string>
       argument before [PATH].
       
       This would override default compatible string for this module.
       May be given multiple times, the strings will be listed in the
       compatible property in the order given. Note that this means
       that the generic "boot,module" would need to be specified
       separately if desired.
       
       Modules which are given an explicit compatibility do not
       "consume" a default. So:
               module --type foo <...>
               module <...>
               module <...>
       Would result in the modules having:
               1st: compatible = "foo" 
               2nd: compatible = "multiboot,linux-zimage",
               "boot,module"
               3rd: compatible = "multiboot,linux-ramdisk",
               "boot,module"
       and not:
       1st: compatible = "foo" 
       2nd: compatible = "multiboot,linux-ramdisk", "boot,module"
               3rd: compatible = "boot,module"
               
       In addition even if --type is used to specify something which is
       also a default it will not be consumed. Thus:
               module --type "multiboot,linux-ramdisk" --type "boot,module" <...>
               module <...>
               module <...>
       results in:
               1st: compatible = "multiboot,linux-ramdisk", "boot,module"
               2nd: compatible = "multiboot,linux-zimage", "boot,module"
               3rd: compatible = "multiboot,linux-ramdisk", "boot,module"
       and not
               1st: compatible = "multiboot,linux-ramdisk", "boot,module"
           2nd: compatible = "multiboot,linux-zimage", "boot,module"
           3rd: compatible = "boot,module"