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