Xen ARM with Virtualization Extensions/Multiboot

From Xen
Revision as of 14:07, 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. See https://wiki.linaro.org/AndrePrzywara/Multiboot for a summary.

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

 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

Syntax:

 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 module's "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"