| |
| Firmware Management |
| ------------------- |
| Copyright 2016 Google Inc. |
| Copyright 2016 Linaro Ltd. |
| |
| Interface-Manifest |
| ------------------ |
| |
| All firmware packages on the Modules or Interfaces are managed by a special |
| Firmware Management Protocol. To support Firmware Management by the AP, the |
| Interface Manifest shall at least contain the Firmware Management Bundle and a |
| Firmware Management Protocol CPort within it. |
| |
| The bundle may contain additional CPorts based on the extra functionality |
| required to manage firmware packages. |
| |
| For example, this is how the Firmware Management part of the Interface Manifest |
| may look like: |
| |
| ; Firmware Management Bundle (Bundle 1): |
| [bundle-descriptor 1] |
| class = 0x16 |
| |
| ; (Mandatory) Firmware Management Protocol on CPort 1 |
| [cport-descriptor 2] |
| bundle = 1 |
| protocol = 0x18 |
| |
| ; (Optional) Firmware Download Protocol on CPort 2 |
| [cport-descriptor 1] |
| bundle = 1 |
| protocol = 0x17 |
| |
| ; (Optional) SPI protocol on CPort 3 |
| [cport-descriptor 3] |
| bundle = 1 |
| protocol = 0x0b |
| |
| ; (Optional) Component Authentication Protocol (CAP) on CPort 4 |
| [cport-descriptor 4] |
| bundle = 1 |
| protocol = 0x19 |
| |
| |
| Sysfs Interfaces - Firmware Management |
| -------------------------------------- |
| |
| The Firmware Management Protocol interacts with Userspace using the character |
| device interface. The character device will be present in /dev/ directory |
| and will be named gb-fw-mgmt-<N>. The number <N> is assigned at runtime. |
| |
| Identifying the Character Device |
| ================================ |
| |
| There can be multiple devices present in /dev/ directory with name gb-fw-mgmt-N |
| and user first needs to identify the character device used for |
| firmware-management for a particular interface. |
| |
| The Firmware Management core creates a device of class 'gb_fw_mgmt', which shall |
| be used by the user to identify the right character device for it. The class |
| device is created within the Bundle directory for a particular Interface. |
| |
| For example this is how the class-device can be present: |
| |
| /sys/bus/greybus/devices/1-1/1-1.1/1-1.1.1/gb_fw_mgmt/gb-fw-mgmt-0 |
| |
| The last name in this path: gb-fw-mgmt-0 is precisely the name of the char |
| device and so the device in this case will be: |
| |
| /dev/gb-fw-mgmt-0. |
| |
| Operations on the Char device |
| ============================= |
| |
| The Character device (gb-fw-mgmt-0 in example) can be opened by the userspace |
| application and it can perform various 'ioctl' operations on the device. The |
| device doesn't support any read/write operations. |
| |
| Following are the IOCTLs and their data structures available to the user: |
| |
| /* IOCTL support */ |
| #define GB_FW_LOAD_METHOD_UNIPRO 0x01 |
| #define GB_FW_LOAD_METHOD_INTERNAL 0x02 |
| |
| #define GB_FW_LOAD_STATUS_FAILED 0x00 |
| #define GB_FW_LOAD_STATUS_UNVALIDATED 0x01 |
| #define GB_FW_LOAD_STATUS_VALIDATED 0x02 |
| #define GB_FW_LOAD_STATUS_VALIDATION_FAILED 0x03 |
| |
| #define GB_FW_BACKEND_FW_STATUS_SUCCESS 0x01 |
| #define GB_FW_BACKEND_FW_STATUS_FAIL_FIND 0x02 |
| #define GB_FW_BACKEND_FW_STATUS_FAIL_FETCH 0x03 |
| #define GB_FW_BACKEND_FW_STATUS_FAIL_WRITE 0x04 |
| #define GB_FW_BACKEND_FW_STATUS_INT 0x05 |
| #define GB_FW_BACKEND_FW_STATUS_RETRY 0x06 |
| #define GB_FW_BACKEND_FW_STATUS_NOT_SUPPORTED 0x07 |
| |
| #define GB_FW_BACKEND_VERSION_STATUS_SUCCESS 0x01 |
| #define GB_FW_BACKEND_VERSION_STATUS_NOT_AVAILABLE 0x02 |
| #define GB_FW_BACKEND_VERSION_STATUS_NOT_SUPPORTED 0x03 |
| #define GB_FW_BACKEND_VERSION_STATUS_RETRY 0x04 |
| #define GB_FW_BACKEND_VERSION_STATUS_FAIL_INT 0x05 |
| |
| |
| struct fw_mgmt_ioc_get_intf_version { |
| __u8 firmware_tag[GB_FIRMWARE_U_TAG_MAX_SIZE]; |
| __u16 major; |
| __u16 minor; |
| } __attribute__ ((__packed__)); |
| |
| struct fw_mgmt_ioc_get_backend_version { |
| __u8 firmware_tag[GB_FIRMWARE_U_TAG_MAX_SIZE]; |
| __u16 major; |
| __u16 minor; |
| __u8 status; |
| } __attribute__ ((__packed__)); |
| |
| struct fw_mgmt_ioc_intf_load_and_validate { |
| __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE]; |
| __u8 load_method; |
| __u8 status; |
| __u16 major; |
| __u16 minor; |
| } __packed; |
| |
| struct fw_mgmt_ioc_backend_fw_update { |
| __u8 firmware_tag[GB_FIRMWARE_TAG_MAX_SIZE]; |
| __u8 status; |
| } __packed; |
| |
| #define FW_MGMT_IOCTL_BASE 'S' |
| #define FW_MGMT_IOC_GET_INTF_FW _IOR(FW_MGMT_IOCTL_BASE, 0, struct fw_mgmt_ioc_get_intf_version) |
| #define FW_MGMT_IOC_GET_BACKEND_FW _IOWR(FW_MGMT_IOCTL_BASE, 1, struct fw_mgmt_ioc_get_backend_version) |
| #define FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE _IOWR(FW_MGMT_IOCTL_BASE, 2, struct fw_mgmt_ioc_intf_load_and_validate) |
| #define FW_MGMT_IOC_INTF_BACKEND_FW_UPDATE _IOWR(FW_MGMT_IOCTL_BASE, 3, struct fw_mgmt_ioc_backend_fw_update) |
| #define FW_MGMT_IOC_SET_TIMEOUT_MS _IOW(FW_MGMT_IOCTL_BASE, 4, unsigned int) |
| #define FW_MGMT_IOC_MODE_SWITCH _IO(FW_MGMT_IOCTL_BASE, 5) |
| |
| 1. FW_MGMT_IOC_GET_INTF_FW: |
| |
| This ioctl shall be used by the user to get the version and firmware-tag of |
| the currently running Interface Firmware. All the fields of the 'struct |
| fw_mgmt_ioc_get_fw' are filled by the kernel. |
| |
| 2. FW_MGMT_IOC_GET_BACKEND_FW: |
| |
| This ioctl shall be used by the user to get the version of a currently |
| running Backend Interface Firmware identified by a firmware-tag. The user is |
| required to fill the 'firmware_tag' field of the 'struct fw_mgmt_ioc_get_fw' |
| in this case. The 'major' and 'minor' fields are set by the kernel in |
| response. |
| |
| 3. FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE: |
| |
| This ioctl shall be used by the user to load an Interface Firmware package on |
| an Interface. The user needs to fill the 'firmware_tag' and 'load_method' |
| fields of the 'struct fw_mgmt_ioc_intf_load_and_validate'. The 'status', |
| 'major' and 'minor' fields are set by the kernel in response. |
| |
| 4. FW_MGMT_IOC_INTF_BACKEND_FW_UPDATE: |
| |
| This ioctl shall be used by the user to request an Interface to update a |
| Backend Interface Firmware. The user is required to fill the 'firmware_tag' |
| field of the 'struct fw_mgmt_ioc_get_fw' in this case. The 'status' field is |
| set by the kernel in response. |
| |
| 5. FW_MGMT_IOC_SET_TIMEOUT_MS: |
| |
| This ioctl shall be used by the user to increase the timeout interval within |
| which the firmware must get loaded by the Module. The default timeout is 1 |
| second. The user needs to pass the timeout in milliseconds. |
| |
| 6. FW_MGMT_IOC_MODE_SWITCH: |
| |
| This ioctl shall be used by the user to mode-switch the module to the |
| previously loaded interface firmware. If the interface firmware isn't loaded |
| previously, or if another unsuccessful FW_MGMT_IOC_INTF_LOAD_AND_VALIDATE |
| operation is started after loading interface firmware, then the firmware core |
| wouldn't allow mode-switch. |
| |
| |
| Sysfs Interfaces - Authentication |
| --------------------------------- |
| |
| The Component Authentication Protocol interacts with Userspace using the |
| character device interface. The character device will be present in /dev/ |
| directory and will be named gb-authenticate-<N>. The number <N> is assigned at |
| runtime. |
| |
| Identifying the Character Device |
| ================================ |
| |
| There can be multiple devices present in /dev/ directory with name |
| gb-authenticate-N and user first needs to identify the character device used for |
| authentication a of particular interface. |
| |
| The Authentication core creates a device of class 'gb_authenticate', which shall |
| be used by the user to identify the right character device for it. The class |
| device is created within the Bundle directory for a particular Interface. |
| |
| For example this is how the class-device can be present: |
| |
| /sys/bus/greybus/devices/1-1/1-1.1/1-1.1.1/gb_authenticate/gb-authenticate-0 |
| |
| The last name in this path: gb-authenticate-0 is precisely the name of the char |
| device and so the device in this case will be: |
| |
| /dev/gb-authenticate-0. |
| |
| Operations on the Char device |
| ============================= |
| |
| The Character device (/dev/gb-authenticate-0 in above example) can be opened by |
| the userspace application and it can perform various 'ioctl' operations on the |
| device. The device doesn't support any read/write operations. |
| |
| Following are the IOCTLs and their data structures available to the user: |
| |
| #define CAP_CERTIFICATE_MAX_SIZE 1600 |
| #define CAP_SIGNATURE_MAX_SIZE 320 |
| |
| /* Certificate class types */ |
| #define CAP_CERT_IMS_EAPC 0x00000001 |
| #define CAP_CERT_IMS_EASC 0x00000002 |
| #define CAP_CERT_IMS_EARC 0x00000003 |
| #define CAP_CERT_IMS_IAPC 0x00000004 |
| #define CAP_CERT_IMS_IASC 0x00000005 |
| #define CAP_CERT_IMS_IARC 0x00000006 |
| |
| /* IMS Certificate response result codes */ |
| #define CAP_IMS_RESULT_CERT_FOUND 0x00 |
| #define CAP_IMS_RESULT_CERT_CLASS_INVAL 0x01 |
| #define CAP_IMS_RESULT_CERT_CORRUPT 0x02 |
| #define CAP_IMS_RESULT_CERT_NOT_FOUND 0x03 |
| |
| /* Authentication types */ |
| #define CAP_AUTH_IMS_PRI 0x00000001 |
| #define CAP_AUTH_IMS_SEC 0x00000002 |
| #define CAP_AUTH_IMS_RSA 0x00000003 |
| |
| /* Authenticate response result codes */ |
| #define CAP_AUTH_RESULT_CR_SUCCESS 0x00 |
| #define CAP_AUTH_RESULT_CR_BAD_TYPE 0x01 |
| #define CAP_AUTH_RESULT_CR_WRONG_EP 0x02 |
| #define CAP_AUTH_RESULT_CR_NO_KEY 0x03 |
| #define CAP_AUTH_RESULT_CR_SIG_FAIL 0x04 |
| |
| |
| /* IOCTL support */ |
| struct cap_ioc_get_endpoint_uid { |
| __u8 uid[8]; |
| } __attribute__ ((__packed__)); |
| |
| struct cap_ioc_get_ims_certificate { |
| __u32 certificate_class; |
| __u32 certificate_id; |
| |
| __u8 result_code; |
| __u32 cert_size; |
| __u8 certificate[CAP_CERTIFICATE_MAX_SIZE]; |
| } __attribute__ ((__packed__)); |
| |
| struct cap_ioc_authenticate { |
| __u32 auth_type; |
| __u8 uid[8]; |
| __u8 challenge[32]; |
| |
| __u8 result_code; |
| __u8 response[64]; |
| __u32 signature_size; |
| __u8 signature[CAP_SIGNATURE_MAX_SIZE]; |
| } __attribute__ ((__packed__)); |
| |
| #define CAP_IOCTL_BASE 'C' |
| #define CAP_IOC_GET_ENDPOINT_UID _IOR(CAP_IOCTL_BASE, 0, struct cap_ioc_get_endpoint_uid) |
| #define CAP_IOC_GET_IMS_CERTIFICATE _IOWR(CAP_IOCTL_BASE, 1, struct cap_ioc_get_ims_certificate) |
| #define CAP_IOC_AUTHENTICATE _IOWR(CAP_IOCTL_BASE, 2, struct cap_ioc_authenticate) |
| |
| |
| 1. CAP_IOC_GET_ENDPOINT_UID: |
| |
| This ioctl shall be used by the user to get the endpoint UID associated with |
| the Interface. All the fields of the 'struct cap_ioc_get_endpoint_uid' are |
| filled by the kernel. |
| |
| 2. CAP_IOC_GET_IMS_CERTIFICATE: |
| |
| This ioctl shall be used by the user to retrieve one of the available |
| cryptographic certificates held by the Interface for use in Component |
| Authentication. The user is required to fill the 'certificate_class' and |
| 'certificate_id' field of the 'struct cap_ioc_get_ims_certificate' in this |
| case. The other fields will be set by the kernel in response. The first |
| 'cert_size' bytes of the 'certificate' shall be read by the user and others |
| must be discarded. |
| |
| 3. CAP_IOC_AUTHENTICATE: |
| |
| This ioctl shall be used by the user to authenticate the Module attached to |
| an Interface. The user needs to fill the 'auth_type', 'uid', and 'challenge' |
| fields of the 'struct cap_ioc_authenticate'. The other fields will be set by |
| the kernel in response. The first 'signature_size' bytes of the 'signature' |
| shall be read by the user and others must be discarded. |
| |
| |
| Sysfs Interfaces - Firmware Download |
| ------------------------------------ |
| |
| The Firmware Download Protocol uses the existing Linux Kernel's Firmware class |
| and the interface provided to userspace are described in: |
| Documentation/firmware_class/. |
| |
| |
| Sysfs Interfaces - SPI Flash |
| ---------------------------- |
| |
| The SPI flash is exposed in userspace as a MTD device and is created |
| within the Bundle directory. For example, this is how the path may look like: |
| |
| $ ls /sys/bus/greybus/devices/1-1/1-1.1/1-1.1.1/spi_master/spi32766/spi32766.0/mtd |
| mtd0 mtd0ro |
| |
| |
| Sample Applications |
| ------------------- |
| |
| The current directory also provides a firmware.c test application, which can be |
| referenced while developing userspace application to talk to firmware-management |
| protocol. |
| |
| The current directory also provides a authenticate.c test application, which can |
| be referenced while developing userspace application to talk to |
| component authentication protocol. |