1.. _using_grub:
2
3Using GRUB to Boot ACRN
4#######################
5
6`GRUB <http://www.gnu.org/software/grub/>`_ is a multiboot bootloader
7used by many popular Linux distributions. It also supports booting the
8ACRN hypervisor.  See
9`<http://www.gnu.org/software/grub/grub-download.html>`_ to get the
10latest GRUB source code and
11`<https://www.gnu.org/software/grub/grub-documentation.html>`_ for
12detailed documentation.
13
14The ACRN hypervisor can boot from the `multiboot protocol
15<http://www.gnu.org/software/grub/manual/multiboot/multiboot.html>`_ or
16`multiboot2 protocol
17<http://www.gnu.org/software/grub/manual/multiboot2/multiboot.html>`_. Compared
18with the multiboot protocol, the multiboot2 protocol adds UEFI support.
19
20The multiboot protocol is supported by the ACRN hypervisor natively. The
21multiboot2 protocol is supported when the :term:`Multiboot2` option is
22enabled in the scenario configuration. The :term:`Multiboot2` option is
23enabled by default. To load the hypervisor with the multiboot protocol, run the
24GRUB ``multiboot`` command. To load the hypervisor with the multiboot2 protocol,
25run the ``multiboot2`` command. To load a VM kernel or ramdisk, run the
26GRUB ``module`` command for the multiboot protocol or the ``module2`` command
27for the multiboot2 protocol.
28
29The ACRN hypervisor binary is built with two formats: ``acrn.32.out`` in
30ELF format and ``acrn.bin`` in RAW format. The GRUB ``multiboot``
31command supports ELF format only and does not support binary relocation,
32even if the :term:`Hypervisor relocation` option is set in the scenario
33configuration. The GRUB ``multiboot2`` command supports
34ELF format when the :term:`Hypervisor relocation` option is not set, or RAW
35format when the :term:`Hypervisor relocation` option is set.
36
37.. note::
38   * The :term:`Hypervisor relocation` option is set by default, so use
39     ``acrn.32.out`` in
40     the multiboot protocol and ``acrn.bin`` in the multiboot2 protocol.
41
42   * Per ACPI specification, the RSDP pointer is described in the EFI System
43     Table instead of the legacy ACPI RSDP area on a UEFI-enabled platform. To
44     make sure the ACRN hypervisor gets the correct ACPI RSDP information, we
45     recommend using ``acrn.bin`` with the multiboot2 protocol to load the
46     hypervisor on a UEFI platform.
47
48.. _pre-installed-grub:
49
50Using Pre-Installed GRUB
51************************
52
53Most Linux distributions use GRUB version 2 by default. For version
542.02 or higher, we can reuse the pre-installed GRUB to load the ACRN
55hypervisor.
56
57Here's an example using Ubuntu to load ACRN on a scenario with two
58pre-launched VMs:
59
60#. Copy the ACRN hypervisor binary ``acrn.32.out`` (or ``acrn.bin``) and the
61   pre-launched VM kernel images to ``/boot/``;
62
63#. Modify the ``/etc/default/grub`` file as follows to make the GRUB
64   menu visible when booting:
65
66   .. code-block:: none
67
68      # GRUB_HIDDEN_TIMEOUT=0
69      GRUB_HIDDEN_TIMEOUT_QUIET=false
70
71#. Append the following configuration in the ``/etc/grub.d/40_custom`` file:
72
73   Configuration template for multiboot protocol:
74
75   .. code-block:: none
76
77      menuentry 'Boot ACRN hypervisor from multiboot' {
78         insmod part_gpt
79         insmod ext2
80         echo 'Loading ACRN hypervisor ...'
81         multiboot --quirk-modules-after-kernel /boot/acrn.32.out $(HV bootargs) $(Service VM bootargs)
82         module /boot/kernel4vm0 xxxxxx $(VM0 bootargs)
83         module /boot/kernel4vm1 yyyyyy $(VM1 bootargs)
84      }
85
86   Configuration template for multiboot2 protocol:
87
88   .. code-block:: none
89
90      menuentry 'Boot ACRN hypervisor from multiboot2' {
91         insmod part_gpt
92         insmod ext2
93         echo 'Loading ACRN hypervisor ...'
94         multiboot2 /boot/acrn.bin $(HV bootargs) $(Service VM bootargs)
95         module2 /boot/kernel4vm0 xxxxxx $(VM0 bootargs)
96         module2 /boot/kernel4vm1 yyyyyy $(VM1 bootargs)
97      }
98
99
100   .. note::
101      The module ``/boot/kernel4vm0`` is the VM0 kernel file. The param
102      ``xxxxxx`` is VM0's kernel file tag and must exactly match the
103      ``kernel_mod_tag`` of VM0 configured in the
104      ``misc/vm_configs/scenarios/$(SCENARIO)/vm_configurations.c`` file. The
105      multiboot module ``/boot/kernel4vm1`` is the VM1 kernel file and the
106      param ``yyyyyy`` is its tag and must exactly match the
107      ``kernel_mod_tag`` of VM1 in the
108      ``misc/vm_configs/scenarios/$(SCENARIO)/vm_configurations.c`` file.
109
110      The VM kernel command-line arguments are configured in the
111      hypervisor source code by default if no ``$(VMx bootargs)`` is present.
112      If ``$(VMx bootargs)`` is present, the default command-line arguments
113      are overridden by the ``$(VMx bootargs)`` parameters.
114
115      The ``$(Service VM bootargs)`` parameter in the multiboot command is
116      appended to the end of the Service VM kernel command line. If a
117      command-line configuration parameter is specified more than once, the last
118      one wins and earlier ones are ignored. For example, adding
119      ``root=/dev/sda3`` will override the original root device for the Service
120      VM kernel.
121
122      All parameters after a ``#`` character are ignored since GRUB
123      treats them as comments.
124
125      ``\``, ``$``, ``#`` are special characters in GRUB. An escape character
126      ``\`` must be added before these special characters if they are included
127      in ``$(HV bootargs)`` or ``$(VM bootargs)``.  For example,
128      ``memmap=0x200000$0xE00000`` for the VM kernel command line must be
129      written as ``memmap=0x200000\$0xE00000``.
130
131
132#. Update GRUB::
133
134      sudo update-grub
135
136#. Reboot the platform. On the platform's console, select the
137   **Boot ACRN hypervisor xxx** entry to boot the ACRN hypervisor.
138   The GRUB loader will boot the hypervisor, and the hypervisor will
139   start the VMs automatically.
140
141
142Installing Self-Built GRUB
143**************************
144
145If the GRUB version on your platform is outdated or has issues booting
146the ACRN hypervisor, you can use a self-built GRUB binary. Get
147the latest GRUB code and follow the `GRUB Manual
148<https://www.gnu.org/software/grub/manual/grub/grub.html#Installing-GRUB-using-grub_002dinstall>`_
149to build and install your own GRUB, and then follow the steps described
150earlier in :ref:`pre-installed-grub`.
151
152
153Here we provide another simple method to build GRUB in EFI application format:
154
155#. Make a GRUB EFI application:
156
157   .. code-block:: none
158
159      git clone https://git.savannah.gnu.org/git/grub.git
160      cd grub
161      ./bootstrap
162      ./configure --with-platform=efi --target=x86_64
163      make
164      ./grub-mkimage -p /EFI/BOOT -d ./grub-core/ -O x86_64-efi -o grub_x86_64.efi \
165            boot efifwsetup efi_gop efinet efi_uga lsefimmap lsefi lsefisystab \
166            exfat fat multiboot2 multiboot terminal part_msdos part_gpt normal \
167            all_video aout configfile echo file fixvideo fshelp gfxterm gfxmenu \
168            gfxterm_background gfxterm_menu legacycfg video_bochs video_cirrus \
169            video_colors video_fb videoinfo video net tftp
170
171   This will build a ``grub_x86_64.efi`` binary in the current directory and
172   copy it to the ``/EFI/boot/`` directory on the EFI partition (it is typically
173   mounted under the ``/boot/efi/`` directory on rootfs).
174
175#. Create ``/EFI/boot/grub.cfg`` file containing the following:
176
177   .. code-block:: none
178
179      set default=0
180      set timeout=5
181      # set correct root device which stores acrn binary and kernel images
182      set root='hd0,gpt3'
183
184      menuentry 'Boot ACRN hypervisor from multiboot' {
185         insmod part_gpt
186         insmod ext2
187         echo 'Loading ACRN hypervisor ...'
188         multiboot --quirk-modules-after-kernel /boot/acrn.32.out $(HV bootargs) $(Service VM bootargs)
189         module /boot/kernel4vm0 xxxxxx $(VM0 bootargs)
190         module /boot/kernel4vm1 yyyyyy $(VM1 bootargs)
191      }
192
193      menuentry 'Boot ACRN hypervisor from multiboot2' {
194         insmod part_gpt
195         insmod ext2
196         echo 'Loading ACRN hypervisor ...'
197         multiboot2 /boot/acrn.bin $(HV bootargs) $(Service VM bootargs)
198         module2 /boot/kernel4vm0 xxxxxx $(VM0 bootargs)
199         module2 /boot/kernel4vm1 yyyyyy $(VM1 bootargs)
200      }
201
202#. Copy the ACRN binary and VM kernel images to the GRUB-configured
203   directory, e.g., the ``/boot/`` directory on ``/dev/sda3/``.
204
205#. Run ``/EFI/boot/grub_x86_64.efi`` in the EFI shell.
206