|
| 1 | +# Flashers |
| 2 | + |
| 3 | +The flasher drivers are used to flash images to DUTs via network, |
| 4 | +typically using TFTP and HTTP. It is designed to interact with |
| 5 | +the target bootloader and busybox shell to flash the DUT. |
| 6 | + |
| 7 | +All flasher drivers inherit from the `jumpstarter_driver_flashers.driver.BaseFlasher` |
| 8 | +class, referencing their own bundle of binary artifacts necessary to flash the DUT, |
| 9 | +like kernel/initram/dtbs. See the [bundle](#oci-bundles) section for more details. |
| 10 | + |
| 11 | +## Available drivers and bundles |
| 12 | + |
| 13 | +| Driver | Bundle | |
| 14 | +|-----------------|---------------------------------------------------------------| |
| 15 | +| TIJ784S4Flasher | quay.io/jumpstarter-dev/jumpstarter-flasher-ti-j784s4:latest | |
| 16 | + |
| 17 | + |
| 18 | +## Driver configuration |
| 19 | +**driver**: `jumpstarter_driver_flashers.driver.${DRIVER}` |
| 20 | + |
| 21 | +```yaml |
| 22 | +export: |
| 23 | + storage: |
| 24 | + type: "jumpstarter_driver_flashers.driver.TIJ784S4Flasher" |
| 25 | + children: |
| 26 | + serial: |
| 27 | + ref: "serial" |
| 28 | + power: |
| 29 | + ref: "power" |
| 30 | + serial: |
| 31 | + type: "jumpstarter_driver_pyserial.driver.PySerial" |
| 32 | + config: |
| 33 | + url: "/dev/serial/by-id/usb-FTDI_USB__-__Serial_Converter_112214101760A-if00-port0" |
| 34 | + baudrate: 115200 |
| 35 | + power: |
| 36 | + type: jumpstarter_driver_yepkit.driver.Ykush |
| 37 | + config: |
| 38 | + serial: "YK112233" |
| 39 | + port: "1" |
| 40 | +``` |
| 41 | +
|
| 42 | +flasher drivers require four children drivers: |
| 43 | +| Child Driver | Description | Auto-created | |
| 44 | +|--------------|-------------|--------------| |
| 45 | +| serial | To communicate with the DUT via serial and drive the bootloader and busybox shell | No | |
| 46 | +| power | To power on and off the DUT | No | |
| 47 | +| tftp | To serve binaries via TFTP | Yes | |
| 48 | +| http | To serve the images via HTTP | Yes | |
| 49 | +
|
| 50 | +In the above example we provide the serial and power children by [reference](./proxy.md), so those |
| 51 | +remain also available on the root of the exporter. |
| 52 | +
|
| 53 | +The power driver is used to control power cycling of the DUT, and the serial interface |
| 54 | +is used to communicate with the DUT bootloader via serial. TFTP and HTTP servers are |
| 55 | +used to serve images to the DUT bootloader and busybox shell. |
| 56 | +
|
| 57 | +### Config parameters |
| 58 | +
|
| 59 | +| Parameter | Description | Type | Required | Default | |
| 60 | +|-----------|-------------|------|----------|---------| |
| 61 | +| flasher_bundle | The OCI bundle to use for the flasher | str | yes | | |
| 62 | +| cache_dir | The directory to cache the images | str | no | /var/lib/jumpstarter/flasher | |
| 63 | +| tftp_dir | The directory to serve the images via TFTP | str | no | /var/lib/tftpboot | |
| 64 | +| http_dir | The directory to serve the images via HTTP | str | no | /var/www/html | |
| 65 | +
|
| 66 | +
|
| 67 | +## BaseFlasher API |
| 68 | +
|
| 69 | +The `BaseFlasher` class provides a set of methods to flash the DUT, |
| 70 | +```{eval-rst} |
| 71 | +.. autoclass:: jumpstarter_driver_flashers.client.BaseFlasherClient() |
| 72 | + :members: flash, busybox_shell, bootloader_shell, use_dtb, use_initram, use_kernel |
| 73 | +``` |
| 74 | + |
| 75 | +## CLI |
| 76 | + |
| 77 | +The flasher driver provides a CLI to perform flashing, access to busybox shell and uboot. |
| 78 | + |
| 79 | +<!-- |
| 80 | +This doesn't work with sphinx-click, so we'll just use the raw CLI |
| 81 | +``` |
| 82 | +.. click:: jumpstarter_driver_flashers.client:BaseFlasherClient.cli |
| 83 | + :prog: flasher |
| 84 | + :nested: full |
| 85 | +``` |
| 86 | +--> |
| 87 | +```bash |
| 88 | +$ jmp client shell -l board ti-03 |
| 89 | +INFO:jumpstarter.client.lease:Created lease request for labels {'board': 'ti-03'} for 0:30:00 |
| 90 | +jumpstarter ⚡remote ➤ j storage |
| 91 | +Usage: j storage [OPTIONS] COMMAND [ARGS]... |
| 92 | +
|
| 93 | + Software-defined flasher interface |
| 94 | +
|
| 95 | +Options: |
| 96 | + --help Show this message and exit. |
| 97 | +
|
| 98 | +Commands: |
| 99 | + bootloader-shell Start a uboot/bootloader interactive console |
| 100 | + busybox-shell Start a busybox shell |
| 101 | + flash Flash image to DUT from file |
| 102 | +
|
| 103 | +``` |
| 104 | + |
| 105 | +### flash |
| 106 | +```bash |
| 107 | +Usage: j storage flash [OPTIONS] FILE |
| 108 | + |
| 109 | + Flash image to DUT from file |
| 110 | + |
| 111 | +Options: |
| 112 | + --partition TEXT |
| 113 | + --os-image-checksum TEXT SHA256 checksum of OS image (direct value) |
| 114 | + --os-image-checksum-file FILE File containing SHA256 checksum of OS image |
| 115 | + --force-exporter-http Force use of exporter HTTP |
| 116 | + --force-flash-bundle TEXT Force use of a specific flasher OCI bundle |
| 117 | + --console-debug Enable console debug mode |
| 118 | + --help Show this message and exit. |
| 119 | +``` |
| 120 | + |
| 121 | +Example: |
| 122 | +``` |
| 123 | +jumpstarter ⚡remote ➤ j storage flash https://autosd.sig.centos.org/AutoSD-9/nightly/TI/auto-osbuild-am69sk-autosd9-qa-regular-aarch64-1716106242.66b4d866.raw.xz |
| 124 | +BaseFlasherClient - INFO - Writing image to storage in the background: /AutoSD-9/nightly/TI/auto-osbuild-am69sk-autosd9-qa-regular-aarch64-1716106242.66b4d866.raw.xz |
| 125 | +BaseFlasherClient - INFO - Setting up flasher bundle files in exporter |
| 126 | +BaseFlasherClient - INFO - Writing image from storage, with metadata: md5=None,size=592736176 etag="23546fb0-63045567a5b80" |
| 127 | +SNMPServerClient - INFO - Starting power cycle sequence |
| 128 | +SNMPServerClient - INFO - Waiting 2 seconds... |
| 129 | +SNMPServerClient - INFO - Power cycle sequence complete |
| 130 | +BaseFlasherClient - INFO - Waiting for U-Boot prompt... |
| 131 | +BaseFlasherClient - INFO - Running DHCP to obtain network configuration... |
| 132 | +BaseFlasherClient - INFO - Running command: dhcp |
| 133 | +BaseFlasherClient - INFO - Running command: printenv netmask |
| 134 | +BaseFlasherClient - INFO - discovered dhcp details: DhcpInfo(ip_address='x.x.x.x', gateway='x.x.x.x', netmask='255.255.255.0') |
| 135 | +BaseFlasherClient - INFO - Image written to storage: /AutoSD-9/nightly/TI/auto-osbuild-am69sk-autosd9-qa-regular-aarch64-1716106242.66b4d866.raw.xz |
| 136 | +BaseFlasherClient - INFO - Running command: setenv serverip 'x.x.x.x' |
| 137 | +BaseFlasherClient - INFO - Running command: tftpboot 0x82000000 J784S4XEVM.flasher.img |
| 138 | +BaseFlasherClient - INFO - Running command: tftpboot 0x84000000 k3-j784s4-evm.dtb |
| 139 | +BaseFlasherClient - INFO - Running boot command: booti 0x82000000 - 0x84000000 |
| 140 | +BaseFlasherClient - INFO - Using target block device: /dev/mmcblk1 |
| 141 | +BaseFlasherClient - INFO - Running preflash command: dd if=/dev/zero of=/dev/mmcblk0 bs=512 count=34 |
| 142 | +BaseFlasherClient - INFO - Running preflash command: dd if=/dev/zero of=/dev/mmcblk1 bs=512 count=34 |
| 143 | +BaseFlasherClient - INFO - Waiting until the http image preparation in storage is completed |
| 144 | +BaseFlasherClient - INFO - Flash progress: 25.00 MB, Speed: 15.78 MB/s |
| 145 | +... |
| 146 | +... |
| 147 | +BaseFlasherClient - INFO - Flash progress: 5086.12 MB, Speed: 13.77 MB/s |
| 148 | +BaseFlasherClient - INFO - Flash progress: 5102.94 MB, Speed: 12.93 MB/s |
| 149 | +BaseFlasherClient - INFO - Flushing buffers |
| 150 | +BaseFlasherClient - INFO - Flashing completed in 7:26 |
| 151 | +BaseFlasherClient - INFO - Powering off target |
| 152 | +``` |
| 153 | + |
| 154 | +### bootloader-shell |
| 155 | +```bash |
| 156 | +Usage: j storage bootloader-shell [OPTIONS] |
| 157 | + |
| 158 | + Start a uboot/bootloader interactive console |
| 159 | + |
| 160 | +Options: |
| 161 | + --console-debug Enable console debug mode |
| 162 | + --help Show this message and exit. |
| 163 | +``` |
| 164 | + |
| 165 | +Example |
| 166 | +``` |
| 167 | +jumpstarter ⚡remote ➤ j storage bootloader-shell |
| 168 | +BaseFlasherClient - INFO - Setting up flasher bundle files in exporter |
| 169 | +SNMPServerClient - INFO - Starting power cycle sequence |
| 170 | +SNMPServerClient - INFO - Waiting 2 seconds... |
| 171 | +SNMPServerClient - INFO - Power cycle sequence complete |
| 172 | +BaseFlasherClient - INFO - Waiting for U-Boot prompt... |
| 173 | +=> version |
| 174 | +U-Boot 2024.01-rc3 (Jan 09 2024 - 00:00:00 +0000) |
| 175 | +
|
| 176 | +gcc (GCC) 11.4.1 20231218 (Red Hat 11.4.1-3) |
| 177 | +GNU ld version 2.35.2-42.el9 |
| 178 | +``` |
| 179 | +### busybox-shell |
| 180 | +```bash |
| 181 | +Usage: j storage busybox-shell [OPTIONS] |
| 182 | + |
| 183 | + Start a busybox interactive console |
| 184 | + |
| 185 | +Options: |
| 186 | + --console-debug Enable console debug mode |
| 187 | + --help Show this message and exit. |
| 188 | +``` |
| 189 | + |
| 190 | +Example |
| 191 | +``` |
| 192 | +jumpstarter ⚡remote ➤ j storage busybox-shell |
| 193 | +BaseFlasherClient - INFO - Setting up flasher bundle files in exporter |
| 194 | +SNMPServerClient - INFO - Starting power cycle sequence |
| 195 | +SNMPServerClient - INFO - Waiting 2 seconds... |
| 196 | +SNMPServerClient - INFO - Power cycle sequence complete |
| 197 | +BaseFlasherClient - INFO - Waiting for U-Boot prompt... |
| 198 | +BaseFlasherClient - INFO - Running DHCP to obtain network configuration... |
| 199 | +BaseFlasherClient - INFO - Running command: dhcp |
| 200 | +BaseFlasherClient - INFO - Running command: printenv netmask |
| 201 | +BaseFlasherClient - INFO - discovered dhcp details: DhcpInfo(ip_address='10.26.28.138', gateway='10.26.28.254', netmask='255.255.255.0') |
| 202 | +BaseFlasherClient - INFO - Running command: setenv serverip '10.26.28.62' |
| 203 | +BaseFlasherClient - INFO - Running command: tftpboot 0x82000000 J784S4XEVM.flasher.img |
| 204 | +BaseFlasherClient - INFO - Running command: tftpboot 0x84000000 k3-j784s4-evm.dtb |
| 205 | +BaseFlasherClient - INFO - Running boot command: booti 0x82000000 - 0x84000000 |
| 206 | +# uname -a |
| 207 | +Linux buildroot 6.1.46-dirty #2 SMP PREEMPT Thu Mar 14 14:37:01 UTC 2024 aarch64 GNU/Linux |
| 208 | +# |
| 209 | +``` |
| 210 | + |
| 211 | +## Examples |
| 212 | + |
| 213 | +Flash the device with a specific image |
| 214 | +```python |
| 215 | +flasherclient.flash("/path/to/image.raw.xz") |
| 216 | +``` |
| 217 | + |
| 218 | +Flash the device with a specific image from a remote URL |
| 219 | +```python |
| 220 | +flasherclient.flash("https://autosd.sig.centos.org/AutoSD-9/nightly/TI/auto-osbuild-j784s4evm-autosd9-qa-regular-aarch64-1716106242.66b4d866.raw.xz") |
| 221 | +``` |
| 222 | + |
| 223 | +Flash into a specific partition |
| 224 | +```python |
| 225 | +flasherclient.flash("/path/to/image.raw.xz", partition="emmc") |
| 226 | +``` |
| 227 | + |
| 228 | + |
| 229 | +## Examples of utility consoles |
| 230 | + |
| 231 | +In addition to the flashing mechanisms, the flasher drivers also provide a way to |
| 232 | +access the DUT bootloader and busybox shell for convenience and debugging, when using |
| 233 | +the `busybox_shell` and `bootloader_shell` methods the embedded http and tftp servers |
| 234 | +will be online and serving the images from the flasher bundle. |
| 235 | + |
| 236 | +Get the busybox shell on the device |
| 237 | +```python |
| 238 | +with flasherclient.busybox_shell() as serial: |
| 239 | + serial.send("ls -la\n") |
| 240 | + serial.expect("#") |
| 241 | + print(serial.before) |
| 242 | +``` |
| 243 | + |
| 244 | +Get the bootloader shell on the device |
| 245 | +```python |
| 246 | +with flasherclient.bootloader_shell() as serial: |
| 247 | + serial.send("version\n") |
| 248 | + serial.expect("=>") |
| 249 | + print(serial.before) |
| 250 | +``` |
| 251 | + |
| 252 | +# oci-bundles |
| 253 | +The flasher drivers require some artifacts and basic information about the target device |
| 254 | +to operate. To make this easy to distribute and use, we use OCI bundles to package the |
| 255 | +artifacts and metadata. |
| 256 | + |
| 257 | +The bundle is a container that uses [oras](https://oras.land/) to transport the artifacts |
| 258 | +and metadata. It is a container that contains the following: |
| 259 | +- `manifest.yaml`: The manifest file that describes the bundle |
| 260 | +- `data/*`: The artifacts, including kernel, initram, dtbs, etc. |
| 261 | + |
| 262 | +## The format of the manifest is as follows: |
| 263 | + |
| 264 | +```{literalinclude} ../../../../packages/jumpstarter-driver-flashers/oci_bundles/test/manifest.yaml |
| 265 | +:language: yaml |
| 266 | +``` |
| 267 | +## Table with the spec fields of the manifest: |
| 268 | +| Field | Description | Default | |
| 269 | +|-------|-------------|---------| |
| 270 | +| `manufacturer` | Name of the device manufacturer | | |
| 271 | +| `link` | URL to device documentation or manufacturer website | | |
| 272 | +| `bootcmd` | Command used to boot the device (e.g. booti, bootz) | | |
| 273 | +| `default_target` | Default target device to flash to if none specified | | |
| 274 | +| `targets` | Map of target names to device paths | | |
| 275 | +| `login.type` | Type of login shell | busybox | |
| 276 | +| `login.login_prompt` | Expected login prompt string | login: | |
| 277 | +| `login.username` | Username to log in with, leave empty if not needed | | |
| 278 | +| `login.password` | Password for login, leave empty if not needed | | |
| 279 | +| `login.prompt` | Shell prompt after successful login | # | |
| 280 | +| `preflash_commands` | List of commands to run before flashing, useful to clear boot entries, etc | | |
| 281 | +| `kernel.file` | Path to kernel image within bundle | |
| 282 | +| `kernel.address` | Memory address to load kernel to | | |
| 283 | +| `initram.file` | Path to initramfs within bundle (if any)| | |
| 284 | +| `initram.address` | Memory address to load initramfs to (if any) | | |
| 285 | +| `dtb.default` | Default DTB variant to use | | |
| 286 | +| `dtb.address` | Memory address to load DTB to | | |
| 287 | +| `dtb.variants` | Map of DTB variant names to files | |
| 288 | + |
| 289 | + |
| 290 | +## Examples |
| 291 | + |
| 292 | +An example bundle for the TI J784S4XEVM looks like this: |
| 293 | + |
| 294 | +```{literalinclude} ../../../../packages/jumpstarter-driver-flashers/oci_bundles/ti_j784s4xevm/manifest.yaml |
| 295 | +:language: yaml |
| 296 | +``` |
| 297 | + |
| 298 | +You can find a script to build and push a bundle to a registry here: |
| 299 | +[oci_bundles](https://github.com/jumpstarter-dev/jumpstarter/tree/main/packages/jumpstarter-driver-flashers/oci_bundles) |
| 300 | + |
0 commit comments