1# OpenBMC Code Update 2 3Two BMC Code layouts are available: 4 5- Static, non-UBI layout 6- UBI layout - enabled via `obmc-ubi-fs` distro feature 7 8This document describes the code update that supports both layouts. 9 10### Steps to Update 11 12The following are the steps to update the BMC. 13 141. Get a BMC image tar: After building OpenBMC, you will end up with a set of 15 image files in `tmp/deploy/images/<platform>/`. 16 17- The UBI layout image is 18 `obmc-phosphor-image-<platform>-<timestamp>.ubi.mtd.tar` 19- The static layout image is 20 `obmc-phosphor-image-<platform>-<timestamp>.static.mtd.tar` 21 22The BMC tar image contains 5 files: u-boot, kernel, ro, and rw partitions and 23the MANIFEST file, which contains information about the image such as the image 24purpose, version, KeyType (Key type used for signature), HashType (SHA type used 25for key generation) and MachineName (name of machine used while building image, 26and this will be used for validation of image build). A MANIFEST file might look 27like 28 29``` 30purpose=xyz.openbmc_project.Software.Version.VersionPurpose.BMC 31version=2.7.0-dev 32KeyType=OpenBMC 33HashType=RSA-SHA256 34MachineName=tiogapass 35``` 36 372. Transfer the generated BMC image to the BMC via one of the following methods: 38 39- Method 1: Via scp: Copy the generated BMC image to the `/tmp/images/` 40 directory on the BMC. 41- Method 2: Via REST Upload: 42 https://github.com/openbmc/docs/blob/master/rest-api.md#uploading-images 43- Method 3: Via TFTP: Perform a POST request to call the `DownloadViaTFTP` 44 method of `/xyz/openbmc_project/software`. 45 463. Note the version id generated for that image file. The version id is a hash 47 value of 8 hexadecimal numbers, generated by SHA-512 hashing the version 48 string contained in the image and taking the first 8 characters. Get the 49 version id via one of the following methods: 50 51- Method 1: From the BMC command line, note the most recent directory name 52 created under `/tmp/images/`, in this example it'd be `2a1022fe`: 53 54 ``` 55 # ls -l /tmp/images/ 56 total 0 57 drwx------ 2 root root 80 Aug 22 07:54 2a1022fe 58 drwx------ 2 root root 80 Aug 22 07:53 488449a2 59 ``` 60 61- Method 2: This method _only_ works if there are no `Ready` images at the start 62 of transferring the image. Using the REST API, note the object that has its 63 Activation property set to Ready, in this example it'd be `2a1022fe`: 64 65 ``` 66 $ curl -b cjar -k https://${bmc}/xyz/openbmc_project/software/enumerate 67 { 68 "data": { 69 "/xyz/openbmc_project/software/2a1022fe": { 70 "Activation": "xyz.openbmc_project.Software.Activation.Activations.Ready", 71 ``` 72 73- Method 3: Calculate the version id beforehand from the image with: 74 75 ``` 76 tar xfO <BMC tar image> MANIFEST | sed -ne '/version=/ {s/version=//;p}' | head -n1 | tr -d '\n' | sha512sum | cut -b 1-8 77 ``` 78 794. To initiate the update, set the `RequestedActivation` property of the desired 80 image to `Active`, substitute `<id>` with the hash value noted on the 81 previous step, this will write the contents of the image to the BMC chip via 82 one of the following methods: 83 84- Method 1: From the BMC command line: 85 86 ``` 87 busctl set-property xyz.openbmc_project.Software.BMC.Updater \ 88 /xyz/openbmc_project/software/<id> \ 89 xyz.openbmc_project.Software.Activation RequestedActivation s \ 90 xyz.openbmc_project.Software.Activation.RequestedActivations.Active 91 92 ``` 93 94- Method 2: Using the REST API: 95 96 ``` 97 curl -b cjar -k -H "Content-Type: application/json" -X PUT \ 98 -d '{"data": 99 "xyz.openbmc_project.Software.Activation.RequestedActivations.Active"}' \ 100 https://${bmc}/xyz/openbmc_project/software/<id>/attr/RequestedActivation 101 ``` 102 1035. (Optional) Check the flash progress. This interface is only available during 104 the activation progress and is not present once the activation is completed 105 via one of the following: 106 107- Method 1: From the BMC command line: 108 109 ``` 110 busctl get-property xyz.openbmc_project.Software.BMC.Updater \ 111 /xyz/openbmc_project/software/<id> \ 112 xyz.openbmc_project.Software.ActivationProgress Progress 113 ``` 114 115- Method 2: Using the REST API: 116 117 ``` 118 curl -b cjar -k https://${bmc}/xyz/openbmc_project/software/<id>/attr/Progress 119 ``` 120 1216. Check that the activation is complete by verifying the "Activation" property 122 is set to "Active" via one of the following methods: 123 124- Method 1: From the BMC command line: 125 126 ``` 127 busctl get-property xyz.openbmc_project.Software.BMC.Updater \ 128 /xyz/openbmc_project/software/<id> \ 129 xyz.openbmc_project.Software.Activation Activation 130 ``` 131 132- Method 2: Using the REST API: 133 134 ``` 135 curl -b cjar -k https://${bmc}/xyz/openbmc_project/software/<id> 136 ``` 137 1387. Reboot the BMC for the image to take effect. 139 140- Method 1: From the BMC command line: 141 142 ``` 143 reboot 144 ``` 145 146- Method 2: Using the REST API: 147 148 ``` 149 curl -c cjar -b cjar -k -H "Content-Type: application/json" -X PUT \ 150 -d '{"data": "xyz.openbmc_project.State.BMC.Transition.Reboot"}' \ 151 https://${bmc}/xyz/openbmc_project/state/bmc0/attr/RequestedBMCTransition 152 ``` 153 154### Associations 155 156In addition to all software images, several associations are listed at 157`/xyz/openbmc_project/software/`: 158 159``` 160curl -c cjar -b cjar -k -H "Content-Type: application/json" -X GET \ 161 https://${bmc}/xyz/openbmc_project/software/ 162{ 163 "data": [ 164 "/xyz/openbmc_project/software/46e65782", 165 "/xyz/openbmc_project/software/493a00ad", 166 "/xyz/openbmc_project/software/88c153b1", 167 "/xyz/openbmc_project/software/active", 168 "/xyz/openbmc_project/software/functional" 169 ], 170 "message": "200 OK", 171 "status": "ok" 172} 173``` 174 1751. A "functional" association to the "running" BMC and host images 176 177There is only one functional association per BMC and one functional association 178per host. The functional/running BMC image is the BMC image with the lowest 179priority when rebooting the BMC. The functional image does not update until the 180BMC is rebooted. The functional host image behaves the same way except that it 181updates on a power on or reboot of the host. 182 183``` 184curl -c cjar -b cjar -k -H "Content-Type: application/json" -X GET \ 185 https://${bmc}/xyz/openbmc_project/software/functional 186{ 187 "data": { 188 "endpoints": [ 189 "/xyz/openbmc_project/software/46e65782", 190 "/xyz/openbmc_project/software/493a00ad" 191 ] 192 }, 193 "message": "200 OK", 194 "status": "ok" 195} 196``` 197 1982. An "active" association to the active BMC and host images 199 200Note: Several BMC images might be active, this is true for the host images as 201well. 202 203``` 204curl -c cjar -b cjar -k -H "Content-Type: application/json" -X GET \ 205 https://${bmc}/xyz/openbmc_project/software/active 206{ 207 "data": { 208 "endpoints": [ 209 "/xyz/openbmc_project/software/46e65782", 210 "/xyz/openbmc_project/software/493a00ad", 211 "/xyz/openbmc_project/software/88c153b1" 212 ] 213 }, 214 "message": "200 OK", 215 "status": "ok" 216} 217``` 218 2193. An "updateable" association to the programmable components 220 221This is used for identifying firmware components which are programmable via BMC 222OOB interfaces like Redfish/IPMI. All updateable firmware components must expose 223the updateable association so that upper applications like Redfish/IPMI will 224know about updateable firmwares. 225 226To know the updateable software components: 227 228``` 229# busctl call xyz.openbmc_project.ObjectMapper \ 230 /xyz/openbmc_project/software/updatable org.freedesktop.DBus.Properties \ 231 Get ss xyz.openbmc_project.Association endpoints 232v as 1 "/xyz/openbmc_project/software/1201fc36" 233``` 234 235Redfish interface uses 'updateable' association in SoftwareInventory schema. 236 2374. An additional association is located at 238 `/xyz/openbmc_project/software/<id>/inventory` for "associating" a software 239 image with an inventory item. 240 241``` 242curl -c cjar -b cjar -k -H "Content-Type: application/json" -X GET \ 243 https://${bmc}/xyz/openbmc_project/software/493a00ad/inventory 244{ 245 "data": { 246 "endpoints": [ 247 "/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc" 248 ] 249 }, 250 "message": "200 OK", 251 "status": "ok" 252} 253``` 254 255To get all software images associated with an inventory item: 256 257``` 258curl -c cjar -b cjar -k -H "Content-Type: application/json" -X GET \ 259 https://${bmc}/xyz/openbmc_project/inventory/system/chassis/activation 260{ 261 "data": { 262 "endpoints": [ 263 "/xyz/openbmc_project/software/46e65782" 264 ] 265 }, 266 "message": "200 OK", 267 "status": "ok" 268} 269``` 270 271### MANIFEST File 272 273A file named "MANIFEST" must be included in any image tar uploaded, downloaded 274via TFTP, or copied to the BMC. 275 276The MANIFEST file format must be key=value (e.g. version=v1.99.10). It should 277include the following fields: 278 279- version - The version of the image 280- purpose - The image's purpose (e.g. 281 xyz.openbmc_project.Software.Version.VersionPurpose.BMC or 282 xyz.openbmc_project.Software.Version.VersionPurpose.Host). Accepted purpose 283 values can be found at 284 [Version interface](https://github.com/openbmc/phosphor-dbus-interfaces/blob/6f69ae5b33ee224358cb4c2061f4ad44c6b36d70/xyz/openbmc_project/Software/Version.interface.yaml) 285 under "VersionPurpose" values. 286- MachineName - The name of machine (platform) for which this image is built 287 for. This value will be compared against OPENBMC_TARGET_MACHINE value defined 288 in os-release file of running image. Image will not be upgraded if this check 289 fails. For backward compatibility this check skips failure if MachineName is 290 not defined for current released images but it will be made mandatory field 291 from 2.9 onward releases. 292 293Other optional fields are: 294 295- extended_version - A more detailed version, which could include versions of 296 different components in the image. 297 298### Deleting an Image 299 300To delete an image: 301 302``` 303curl -c cjar -b cjar -k -H "Content-Type: application/json" \ 304 -X POST https://${bmc}/xyz/openbmc_project/software/<$id>/action/delete \ 305 -d "{\"data\": [] }" 306``` 307 308Note: The image must be non-functional ("non-running"). 309 310To delete all non-functional images, whether BMC or host images: 311 312``` 313curl -c cjar -b cjar -k -H "Content-Type: application/json" \ 314 -X POST https://${bmc}/xyz/openbmc_project/software/action/deleteAll \ 315 -d "{\"data\": [] }" 316``` 317 318### Software Field Mode 319 320Field mode is meant for systems shipped from manufacturing to a customer. Field 321mode offers a way to provide security and ensure incorrect patches don't get 322loaded on the system by accident. The software implementation of the field mode 323interface disables patching of the BMC by not mounting `/usr/local`, which in 324turn disables host patching at `/usr/local/share/pnor/`. Enabling field mode is 325intended to be a one-way operation which means that once enabled, there is no 326REST API provided to disable it. 327 328Field mode can be enabled by running the following command: 329 330``` 331curl -b cjar -k -H 'Content-Type: application/json' -X PUT -d '{"data":1}' \ 332 https://${bmc}/xyz/openbmc_project/software/attr/FieldModeEnabled 333 334``` 335 336Although field mode is meant to be a one-way operation, it can be disabled by a 337user with admin privileges by running the following commands on the BMC: 338 339``` 340fw_setenv fieldmode 341 342systemctl unmask usr-local.mount 343 344reboot 345``` 346 347More information on field mode can be found here: 348https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Control/FieldMode.interface.yaml 349 350### Software Factory Reset 351 352Software factory reset resets the BMC and host firmware to its factory state by 353clearing out any read/write data. To software factory reset run the following 354command and then reboot the BMC: 355 356``` 357curl -b cjar -k -H 'Content-Type: application/json' -X POST -d '{"data":[]}' \ 358 https://${bmc}/xyz/openbmc_project/software/action/Reset 359 360``` 361 362The factory reset on the BMC side will clear `/var`, `/home`, and `/etc`. On the 363host side, the factory reset will clear the read/write volume for each host 364image on the system, clear the shared preserve host volume, pnor-prsv, and clear 365any host patches located in `/usr/local/share/pnor/`. 366 367The factory reset interface can be found here: 368https://github.com/openbmc/phosphor-dbus-interfaces/blob/02b39246d45ea029a1652a49cc20eab7723dd63b/xyz/openbmc_project/Common/FactoryReset.interface.yaml 369 370### Image Storage Location 371 372#### Static layout 373 374When a BMC image is activated, each `image-<name>` is written to the BMC chip's 375partitions indicated by the `<name>`: 376 377- image-u-boot 378- image-kernel 379- image-rofs 380- image-rwfs 381 382#### UBI layout 383 384When a BMC image is activated (i.e. when "RequestedActivation" is set to 385"Active"), UBI volumes are created on the BMC chip for the image. The alternate 386BMC chip can also be used to store images. This is determined by "BMC_RO_MTD". 387Using both the alternate BMC chip and the BMC chip allows for multiple BMC 388images to be stored. By default, only the BMC chip is used. To use both, set 389"BMC_RO_MTD" to "alt-bmc+bmc". 390 391### Implementation 392 393More information about the implementation of the code update can be found at 394https://github.com/openbmc/phosphor-dbus-interfaces/blob/master/yaml/xyz/openbmc_project/Software 395and https://github.com/openbmc/phosphor-bmc-code-mgmt 396