d1ceeeff6c
Much of the content here is useful only for development. Move it under that section. Signed-off-by: Simon Glass <sjg@chromium.org> Reviewed-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
185 lines
7.5 KiB
ReStructuredText
185 lines
7.5 KiB
ReStructuredText
.. SPDX-License-Identifier: GPL-2.0+
|
|
.. Copyright (c) 2018 Heinrich Schuchardt
|
|
|
|
iSCSI booting with U-Boot and iPXE
|
|
==================================
|
|
|
|
Motivation
|
|
----------
|
|
|
|
U-Boot has only a reduced set of supported network protocols. The focus for
|
|
network booting has been on UDP based protocols. A TCP stack and HTTP support
|
|
are expected to be integrated in 2018 together with a wget command.
|
|
|
|
For booting a diskless computer this leaves us with BOOTP or DHCP to get the
|
|
address of a boot script. TFTP or NFS can be used to load the boot script, the
|
|
operating system kernel and the initial file system (initrd).
|
|
|
|
These protocols are insecure. The client cannot validate the authenticity
|
|
of the contacted servers. And the server cannot verify the identity of the
|
|
client.
|
|
|
|
Furthermore the services providing the operating system loader or kernel are
|
|
not the ones that the operating system typically will use. Especially in a SAN
|
|
environment this makes updating the operating system a hassle. After installing
|
|
a new kernel version the boot files have to be copied to the TFTP server
|
|
directory.
|
|
|
|
The HTTPS protocol provides certificate based validation of servers. Sensitive
|
|
data like passwords can be securely transmitted.
|
|
|
|
The iSCSI protocol is used for connecting storage attached networks. It
|
|
provides mutual authentication using the CHAP protocol. It typically runs on
|
|
a TCP transport.
|
|
|
|
Thus a better solution than DHCP/TFTP/NFS boot would be to load a boot script
|
|
via HTTPS and to download any other files needed for booting via iSCSI from the
|
|
same target where the operating system is installed.
|
|
|
|
An alternative to implementing these protocols in U-Boot is to use an existing
|
|
software that can run on top of U-Boot. iPXE[1] is the "swiss army knife" of
|
|
network booting. It supports both HTTPS and iSCSI. It has a scripting engine for
|
|
fine grained control of the boot process and can provide a command shell.
|
|
|
|
iPXE can be built as an EFI application (named snp.efi) which can be loaded and
|
|
run by U-Boot.
|
|
|
|
Boot sequence
|
|
-------------
|
|
|
|
U-Boot loads the EFI application iPXE snp.efi using the bootefi command. This
|
|
application has network access via the simple network protocol offered by
|
|
U-Boot.
|
|
|
|
iPXE executes its internal script. This script may optionally chain load a
|
|
secondary boot script via HTTPS or open a shell.
|
|
|
|
For the further boot process iPXE connects to the iSCSI server. This includes
|
|
the mutual authentication using the CHAP protocol. After the authentication iPXE
|
|
has access to the iSCSI targets.
|
|
|
|
For a selected iSCSI target iPXE sets up a handle with the block IO protocol. It
|
|
uses the ConnectController boot service of U-Boot to request U-Boot to connect a
|
|
file system driver. U-Boot reads from the iSCSI drive via the block IO protocol
|
|
offered by iPXE. It creates the partition handles and installs the simple file
|
|
protocol. Now iPXE can call the simple file protocol to load GRUB[2]. U-Boot
|
|
uses the block IO protocol offered by iPXE to fulfill the request.
|
|
|
|
Once GRUB is started it uses the same block IO protocol to load Linux. Via
|
|
the EFI stub Linux is called as an EFI application::
|
|
|
|
+--------+ +--------+
|
|
| | Runs | |
|
|
| U-Boot |========>| iPXE |
|
|
| EFI | | snp.efi|
|
|
+--------+ | | DHCP | |
|
|
| |<===|********|<========| |
|
|
| DHCP | | | Get IP | |
|
|
| Server | | | Address | |
|
|
| |===>|********|========>| |
|
|
+--------+ | | Response| |
|
|
| | | |
|
|
| | | |
|
|
+--------+ | | HTTPS | |
|
|
| |<===|********|<========| |
|
|
| HTTPS | | | Load | |
|
|
| Server | | | Script | |
|
|
| |===>|********|========>| |
|
|
+--------+ | | | |
|
|
| | | |
|
|
| | | |
|
|
+--------+ | | iSCSI | |
|
|
| |<===|********|<========| |
|
|
| iSCSI | | | Auth | |
|
|
| Server |===>|********|========>| |
|
|
| | | | | |
|
|
| | | | Loads | |
|
|
| |<===|********|<========| | +--------+
|
|
| | | | GRUB | | Runs | |
|
|
| |===>|********|========>| |======>| GRUB |
|
|
| | | | | | | |
|
|
| | | | | | | |
|
|
| | | | | | Loads | |
|
|
| |<===|********|<========|********|<======| | +--------+
|
|
| | | | | | Linux | | Runs | |
|
|
| |===>|********|========>|********|======>| |=====>| Linux |
|
|
| | | | | | | | | |
|
|
+--------+ +--------+ +--------+ +--------+ | |
|
|
| |
|
|
| |
|
|
| ~ ~ ~ ~|
|
|
|
|
Security
|
|
--------
|
|
|
|
The iSCSI protocol is not encrypted. The traffic could be secured using IPsec
|
|
but neither U-Boot nor iPXE does support this. So we should at least separate
|
|
the iSCSI traffic from all other network traffic. This can be achieved using a
|
|
virtual local area network (VLAN).
|
|
|
|
Configuration
|
|
-------------
|
|
|
|
iPXE
|
|
~~~~
|
|
|
|
For running iPXE on arm64 the bin-arm64-efi/snp.efi build target is needed::
|
|
|
|
git clone http://git.ipxe.org/ipxe.git
|
|
cd ipxe/src
|
|
make bin-arm64-efi/snp.efi -j6 EMBED=myscript.ipxe
|
|
|
|
The available commands for the boot script are documented at:
|
|
|
|
http://ipxe.org/cmd
|
|
|
|
Credentials are managed as environment variables. These are described here:
|
|
|
|
http://ipxe.org/cfg
|
|
|
|
iPXE by default will put the CPU to rest when waiting for input. U-Boot does
|
|
not wake it up due to missing interrupt support. To avoid this behavior create
|
|
file src/config/local/nap.h:
|
|
|
|
.. code-block:: c
|
|
|
|
/* nap.h */
|
|
#undef NAP_EFIX86
|
|
#undef NAP_EFIARM
|
|
#define NAP_NULL
|
|
|
|
The supported commands in iPXE are controlled by an include, too. Putting the
|
|
following into src/config/local/general.h is sufficient for most use cases:
|
|
|
|
.. code-block:: c
|
|
|
|
/* general.h */
|
|
#define NSLOOKUP_CMD /* Name resolution command */
|
|
#define PING_CMD /* Ping command */
|
|
#define NTP_CMD /* NTP commands */
|
|
#define VLAN_CMD /* VLAN commands */
|
|
#define IMAGE_EFI /* EFI image support */
|
|
#define DOWNLOAD_PROTO_HTTPS /* Secure Hypertext Transfer Protocol */
|
|
#define DOWNLOAD_PROTO_FTP /* File Transfer Protocol */
|
|
#define DOWNLOAD_PROTO_NFS /* Network File System Protocol */
|
|
#define DOWNLOAD_PROTO_FILE /* Local file system access */
|
|
|
|
Open-iSCSI
|
|
~~~~~~~~~~
|
|
|
|
When the root file system is on an iSCSI drive you should disable pings and set
|
|
the replacement timer to a high value in the configuration file [3]::
|
|
|
|
node.conn[0].timeo.noop_out_interval = 0
|
|
node.conn[0].timeo.noop_out_timeout = 0
|
|
node.session.timeo.replacement_timeout = 86400
|
|
|
|
Links
|
|
-----
|
|
|
|
* [1] https://ipxe.org - iPXE open source boot firmware
|
|
* [2] https://www.gnu.org/software/grub/ -
|
|
GNU GRUB (Grand Unified Bootloader)
|
|
* [3] https://github.com/open-iscsi/open-iscsi/blob/master/README -
|
|
Open-iSCSI README
|