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