| # Chromebook Netboot Setup Guide |
| |
| ## What is Netboot? |
| **Netboot firmware** is a special firmware that instead of loading kernel from |
| storage, it downloads a light weight kernel (vmlinuz) from TFTP server. And the |
| kernel will download ChromeOS images from [factory server](FACTORY_SERVER.md). |
| This is helpful when you need to re-flash ChromeOS images frequently. Also, |
| this can be used in some early phase of projects (e.g. Proto builds), when |
| images might be changed during the build, so you don't want to pre-flash it by |
| copy machine. |
| |
| ## Overview |
| The netboot imaging flow contains the following steps: |
| |
| 1. Enter netboot mode with netboot or dev firmware. |
| 2. Download `vmlinuz` kernel from TFTP server in netboot mode. |
| 3. Download images (with [cros_payload](../sh/cros_payload.sh)) from the factory |
| server in `vmlinuz` kernel. |
| |
| Therefore, you need to setup the following components to do a netboot imaging: |
| |
| * Flash the devices with netboot or dev firmware to enter netboot mode. |
| * Setup a TFTP server to deploy netboot kernel. |
| * Setup a factory server with image resources. |
| * Specify netboot settings (e.g., factory server IP). |
| |
| Details of each component can be found in corresponding sections in this |
| document. |
| |
| ## Prerequisition |
| * A Linux machine, which will be running TFTP and factory server |
| * An USB Ethernet dongle for DUT |
| * Connect DUT and Linux machine by ethernet, |
| |
| - Assume that the ethernet device on Linux machine is `eth2` |
| - Assume that `eth2` is set up `192.168.200.1/24` |
| |
| * Assume that the board we are going to use is `zork`, and the model name is |
| `morphius` |
| * Assume that the Linux machine is running Ubuntu (otherwise the network |
| config files might need to be changed according to your Linux distribution). |
| |
| ## Put Device Into Netboot Mode |
| |
| #### 1. Prepare netboot firmware |
| |
| Find firmware blob `image-${MODEL}.net.bin` which should be available in |
| firmware archive, or you can build it locally. |
| |
| Local build netboot firmware: |
| ``` |
| $ emerge-${BOARD} sys-boot/chromeos-bootimage |
| ``` |
| |
| You have to set the path to the `bootfile` and `argsfile` on local built netboot |
| firmware with the following command: |
| ``` |
| $ bin/factory_env py/tools/netboot_firmware_settings.py \ |
| -i /build/${BOARD}/firmware/image-${MODEL}.net.bin \ |
| --bootfile chrome-bot/${MODEL}/vmlinuz \ |
| --argsfile chrome-bot/${MODEL}/cmdline |
| -o image-${MODEL}.net.bin |
| ``` |
| |
| #### 2. Flash netboot firmware |
| |
| You can use Servo to flash the netboot firmware: |
| ``` |
| (chroot)$ cros ap flash -b $BOARD -i image-${MODEL}.net.bin |
| ``` |
| |
| or run `flashrom` on DUT: |
| ``` |
| (dut)$ flashrom -p internal -w image-${MODEL}.net.bin |
| ``` |
| |
| After flash netboot firmware,the device will boot into netboot mode |
| automatically. |
| |
| Alternatively, you can also install **dev firmware** (`image-${MODEL}.dev.bin`) |
| to the device, and press `Ctrl + N` in the developer screen to enter netboot |
| mode. This effectively runs the same netboot code as full netboot firmware. |
| |
| ## Setup TFTP server |
| |
| You can choose to use Dome or `dnsmasq` to setup the TFTP server. |
| |
| ### Setup TFTP server with Dome |
| |
| If your network infrastructure already has a DHCP server, you can setup the TFTP |
| server from Dome UI with the following steps: |
| |
| 1. Upload the `vmlinuz` kernel (and `netboot_cmdline` file if needed) to Umpire. |
| 2. Select the "NETBOOT" button (use this bundle's netboot resource) at the |
| bundle. |
| 3. Enable **TFTP server** in Dome config page. |
| |
| By default this will create a TFTP folder at `/cros_docker/tftp/`, and the |
| netboot kernel and cmdline files will be copied to |
| `/cros_docker/tftp/chrome-bot/${PROJECT}/`, where `${PROJECT}` is the project |
| name of the Umpire instance. So if the project name on Umpire does not match the |
| model name, you have to override the path to the netboot kernel and cmdline |
| to download them from TFTP server; see |
| [Netboot Settings](#netboot-settings) section for more details. |
| |
| ### Setup TFTP server and DHCP server with `dnsmasq` |
| Decide a folder to put TFTP files, for example, `/var/tftp` |
| |
| ``` |
| sudo mkdir /var/tftp |
| sudo chown "${USER}" /var/tftp |
| mkdir -p "/var/tftp/chrome-bot/${MODEL}" |
| ``` |
| |
| Create a [`dnsmasq`](http://www.thekelleys.org.uk/dnsmasq/doc.html) setup config |
| in TFTP root, for example, `/var/tftp/dnsmasq.conf`, with the following |
| contents: |
| |
| ``` |
| interface=eth2 |
| tftp-root=/var/tftp |
| enable-tftp |
| dhcp-leasefile=/tmp/dnsmasq.leases |
| dhcp-range=192.168.200.50,192.168.200.150,12h |
| port=0 |
| ``` |
| |
| Assuming that you are running Ubuntu, you can setup static IP for `eth2` by |
| adding a file `/etc/network/interfaces.d/eth2.conf` (you can change the name |
| `eth2.conf` to whatever you like): |
| |
| ``` |
| auto eth2 |
| allow-hotplug eth2 |
| iface eth2 inet static |
| address 192.168.200.1 |
| netmask 255.255.255.0 |
| ``` |
| |
| Reload the configuration by running: |
| |
| ``` |
| sudo ifup eth2 |
| ``` |
| |
| Then `ip addr show eth2` and check if it has inet address `192.168.200.1/24` |
| assigned. If not, reboot Linux machine and see if that works. |
| |
| Make sure you have `dnsmasq` installed on Linux machine (e.g. Ubuntu / Debian) |
| |
| ``` |
| sudo apt-get install dnsmasq |
| ``` |
| |
| In the tftp-root, create sub folder under `chrome-bot` using the model name. |
| For example, `morphius` model should be `/var/tftp/chrome-bot/morphius/`. |
| |
| Copy the netboot kernel into tftp model folder with name `vmlinuz`. |
| |
| If you are setting up with a factory zip, the netboot kernel is in path |
| `factory_shim/netboot/vmlinuz`. So you have to copy it into tftp model folder |
| manually. For example: |
| ``` |
| cp factory_shim/netboot/vmlinuz /var/tftp/chrome-bot/morphius/vmlinuz |
| ``` |
| |
| If you are setting up with a factory bundle (prepared by `finalize_bundle` |
| command and is usually a `tar.bz2` archive), the tftp folder is already prepared |
| in `netboot/tftp`. So you have to copy everything to your tftp root, |
| or start `dnsmasq` server from there. For example: |
| ``` |
| cp -r netboot/tftp/* /var/tftp/ |
| ``` |
| |
| *** note |
| **Note:** Some boards might call vmlinuz as "vmlinux.bin". |
| *** |
| |
| Start DHCP & TFTP server |
| ``` |
| sudo dnsmasq -d -C /var/tftp/dnsmasq.conf |
| ``` |
| |
| ## Prepare Images |
| You should download the recovery image, test image and factory.zip from |
| [CPFE](https://www.google.com/chromeos/partner/fe/#home) in following steps, |
| |
| - Click Image Files on the left |
| - Select board (e.g. `zork`) |
| - Select Image type |
| |
| - `RECOVERY_IMAGE` for recovery image (signed) |
| - `TEST_IMAGE_ARCHIVE` for test image |
| - `FACTORY_IMAGE_ARCHIVE` for factory.zip |
| |
| As we mentioned above, you can extract netboot firmware and vmlinuz from |
| factory.zip. Or, if you'd like to use a specific version of firmware, you can |
| download it by selecting `FIRMWARE_IMAGE_ARCHIVE` in above steps. |
| |
| If you want to build the netboot kernel from source, do this inside chroot: |
| |
| ``` |
| # You can skip the `cros-workon` and `emerge` commands if you don't have |
| # local changes. |
| cros-workon-${BOARD} factory factory_installer |
| |
| # Replace ${VER} with the kernel version used by your board, and you only need |
| # to build the kernel once. If you don't know the version number, run |
| # `emerge-${BOARD} -pv virtual/linux-sources`. |
| emerge-${BOARD} chromeos-kernel-${VER} |
| emerge-${BOARD} factory factory_installer |
| |
| cd ~/trunk/src/scripts |
| ./build_images --board "${BOARD}" |
| ./make_netboot.sh --board "${BOARD}" |
| |
| # If you need to add any USE flags while building kernel, add USE flags to |
| # environment variables: |
| USE="..." ./make_netboot.sh --board "${BOARD}" |
| ``` |
| |
| |
| And find the netboot kernel in |
| `../build/images/${BOARD}/latest/netboot/vmlinuz`. |
| |
| ## Deploy to Factory Server |
| You have to first setup a [Factory Server](FACTORY_SERVER.md) and create a |
| project. When ready, login to the [Dome](../py/dome/README.md) web interface, |
| select your project and upload the images for deployment. |
| |
| To do that, you can create a complete [Bundle](BUNDLE.md), or deploy only files |
| you need to testing and development. |
| * Required resources: |
| * `test_image`: Extracted from `TEST_IMAGE_ARCHIVE` |
| * `release_image`: `RECOVERY_IMAGE` |
| * `toolkit`: Extracted from `FACTORY_IMAGE_ARCHIVE/toolkit` |
| * `netboot_kernel`: Extracted from |
| `FACTORY_IMAGE_ARCHIVE/factory_shim/netboot` |
| * `complete`, `project_config`, `hwid`, and `firmware` are optional resources, |
| but `hwid` and `firmware` are required in typical factory scenarios. |
| |
| ## Netboot Settings |
| This section introduces the settings during the netboot process and how to |
| customize them. |
| |
| #### Factory server IP |
| The factory server (Umpire) IP (e.g., `http://192.168.200.1:8080`) for the |
| netboot kernel to download the image files. To specify this, you can do one |
| of the following approaches: |
| |
| * Append `omahaserver=http://192.168.200.1:8080` in the kernel boot options |
| (`cmdline`). |
| * Use `--factory-server-url` argument in [netboot_firmware_settings.py]( |
| ../py/tools/netboot_firmware_settings.py). This will append the argument |
| (`omahaserver=`) in kernel boot options (`cmdline`) for you. |
| * Create a `omahaserver_${BOARD}.conf` under the TFTP root (for example, |
| `${TFTP_ROOT}/omahaserver_zork.conf`), and set its content to the factory |
| server IP (for example, `http://192.168.200.1:8080`). This will override the |
| `omahaserver` settings in kernel boot options. |
| |
| Default value: `CHROMEOS_AUSERVER` (typically `http://10.0.0.1:8080`). |
| |
| **This is a required argument for netboot process.** |
| |
| #### TFTP server IP for firmware |
| |
| The TFTP server IP to download the netboot kernel and kernel boot option file |
| (`cmdline`) from. To specify this, you can do one of the following approaches: |
| |
| * Modify the siaddr field (next-server) in DHCP message. |
| * Use `--tftpserverip` argument in [netboot_firmware_settings.py]( |
| ../py/tools/netboot_firmware_settings.py). This will override the setting |
| in DHCP message. |
| |
| Default value: IP address of DHCP server. |
| |
| **This is a required argument if you have separate DHCP server and TFTP |
| server.** |
| |
| |
| #### Board name (Optional) |
| The board name of the device. This changes the path to the factory server IP |
| config file on TFTP server (`${TFTP_ROOT}/omahaserver_${BOARD}.conf`), so you can |
| override the board name to connect to different factory server. To specify this, |
| you can do one of the following approaches: |
| |
| * Append `cros_board=${BOARD}` in the kernel boot options (`cmdline`). |
| * Use `--board` argument in [netboot_firmware_settings.py]( |
| ../py/tools/netboot_firmware_settings.py). This will append the argument |
| (`cros_board=`) in kernel boot options (`cmdline`) for you. |
| |
| Default value: board name (`CHROMEOS_RELEASE_BOARD`) of the device. |
| |
| #### Netboot kernel boot options (Optional) |
| The boot options (`cmdline`) for the netboot kernel. To specify this, you can do |
| one of the following approaches: |
| |
| * Use `--kernel_arg` argument in [netboot_firmware_settings.py]( |
| ../py/tools/netboot_firmware_settings.py). |
| * Upload `netboot_cmdline` resource to the [factory server](FACTORY_SERVER.md). |
| **Note that this will override all boot options specified by |
| [netboot_firmware_settings.py](../py/tools/netboot_firmware_settings.py). |
| ** |
| |
| Default value: |
| |
| `lsm.module_locking=0 cros_netboot_ramfs cros_factory_install cros_secure |
| cros_netboot` |
| |
| See [Debugging](#debugging) and [Skip Complete Prompt](#skip-complete-prompt) |
| section for more information on kernel boot options. |
| |
| #### TFTP server IP for netboot kernel (Optional) |
| If you want to specify a different TFTP server IP for downloading |
| `omahaserver_${BOARD}.conf` in netboot kernel, you can append |
| `tftpserverip=${TFTP_SERVER_IP}` into the kernel boot options (`cmdline`). |
| |
| Default value: TFTP server IP |
| |
| #### Path to netboot kernel (Optional) |
| The path to the netboot kernel on TFTP server. To Specify this, you can do one |
| of the following approaches: |
| |
| * Modify the `file` (filename) field in DHCP message. |
| * Use `--bootfile` argument in [netboot_firmware_settings.py]( |
| ../py/tools/netboot_firmware_settings.py). This overrides the setting in |
| the DHCP message. |
| |
| Default value: `chrome-bot/{MODEL}/vmlinuz`. |
| |
| #### Path to netboot kernel boot options file (Optional) |
| The path to the netboot kernel boot options file (`cmdline`) on TFTP server. |
| You can specify this by `--argsfile` argument in [netboot_firmware_settings.py]( |
| ../py/tools/netboot_firmware_settings.py). |
| |
| Default value: `chrome-bot/{MODEL}/cmdline`. |
| |
| ## Debugging |
| Create an additional `cmdline` in TFTP model folder to override default kernel |
| boot options. For example, in `${TFTP_ROOT}/chrome-bot/morphius/cmdline`: |
| |
| ``` |
| lsm.module_locking=0 cros_netboot_ramfs cros_factory_install cros_secure |
| cros_netboot tftpserverip=192.168.200.2 console=ttyS2,115200n8 loglevel=7 |
| earlyprintk cros_debug |
| ``` |
| |
| **Note all optional must be in one line. No newline is allowed.** |
| |
| The `console` parameter might be different from board to board, if you are not |
| sure which should be used, please refer to "Care & Feeding" document for your |
| project. |
| |
| ## Skip Complete Prompt |
| By default, you'll see a big "OK" when the netboot completes, and you have to |
| press ENTER key to reboot into the factory software. |
| |
| If you want to disable the prompt, you can append `nocompleteprompt` to the |
| kernel boot options (`cmdline`). |
| |
| ## Setting GBB Flags |
| When the device boots from vmlinuz, vmlinuz will connect to factory server and |
| download images from the server. `chromeos-firmwareupdate` will be extracted |
| from recovery image, which will be used to install the real firmware. |
| `chromeos-firmwareupdate` will preserve the GBB flag from netboot firmware. |
| Therefore, you might need to change GBB flag of netboot firmware. |
| |
| If you are setting up with a factory zip, the netboot image is in path |
| `factory_shim/netboot/image-${MODEL}.net.bin`. You can change GBB flag by |
| `futility`. |
| For example, |
| |
| ``` |
| futility gbb -s --flags 0x1239 factory_shim/netboot/image-${MODEL}.net.bin |
| ``` |
| |
| If you are setting up with a factory bundle, the netboot image is in path |
| `netboot/image-${MODEL}.net.bin`. You can change GBB flag by `futility`. |
| For example, |
| |
| ``` |
| futility gbb -s --flags 0x1239 netboot/image-${MODEL}.net.bin |
| ``` |