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