On Mon, 21 Dec 2020 at 18:28, Heinrich Schuchardt <xypron.g...@gmx.de> wrote:
> On 12/21/20 12:43 PM, Sughosh Ganu wrote: > > Add documentation highlighting the steps for using the uefi capsule > > update feature for updating the u-boot firmware image. > > > > Signed-off-by: Sughosh Ganu <sughosh.g...@linaro.org> > > --- > > > > Changes since V1: > > * Change the documentation to reflect the usage of overlays for > > embedding the public key certs at runtime > > * Fix the build for 'make htmldocs' > > > > doc/board/emulation/qemu-arm.rst | 188 +++++++++++++++++++++++++++++++ > > Why do you put the information into doc/board/emulation/qemu-arm.rst? > > Isn't the same applicable to RISC-V QEMU? > Where do you want me to put it. Currently, I do not see any common document for qemu which can be shared between qemu-arm and qemu risc-v. Or do you think a new document should be created under doc/board/emulation/ directory. Moreover, my series is adding support for capsule update feature on the qemu arm64 platform, and i have only tested this feature on the qemu arm64 platform. If someone wants to extend this on the qemu risc-v platform, that work i think needs to be done separately, with whatever changes that may be needed to get capsule updates working on qemu risc-v. If you so prefer, I can move the changes made for mtdparts and dfu(patches 4/14 and 5/14) under a common directory under board/emulation. -sughosh > > Best regards > > Heinrich > > > 1 file changed, 188 insertions(+) > > > > diff --git a/doc/board/emulation/qemu-arm.rst > b/doc/board/emulation/qemu-arm.rst > > index 8d7fda10f1..11d91811b3 100644 > > --- a/doc/board/emulation/qemu-arm.rst > > +++ b/doc/board/emulation/qemu-arm.rst > > @@ -90,3 +90,191 @@ The debug UART on the ARM virt board uses these > settings:: > > CONFIG_DEBUG_UART_PL010=y > > CONFIG_DEBUG_UART_BASE=0x9000000 > > CONFIG_DEBUG_UART_CLOCK=0 > > + > > +Enabling Uefi Capsule Update feature > > +------------------------------------ > > + > > +Support has been added for the uefi capsule update feature which > > +enables updating the u-boot image using the uefi firmware management > > +protocol (fmp). The capsules are not passed to the firmware through > > +the UpdateCapsule runtime service. Instead, capsule-on-disk > > +functionality is used for fetching the capsule from the EFI System > > +Partition (ESP). > > + > > +Currently, support has been added for updating the u-boot binary as a > > +raw image when the platform is booted in non-secure mode, i.e with > > +CONFIG_TFABOOT disabled. For this configuration, the qemu platform > > +needs to be booted with 'secure=off'. The u-boot binary placed on the > > +first bank of the Nor Flash at offset 0x0. The u-boot environment is > > +placed on the second Nor Flash bank at offset 0x4000000. > > + > > +The capsule update feature is enabled with the following configs:: > > + > > + CONFIG_MTD=y > > + CONFIG_FLASH_CFI_MTD=y > > + CONFIG_CMD_MTDPARTS=y > > + CONFIG_CMD_DFU=y > > + CONFIG_DFU_MTD=y > > + CONFIG_PCI_INIT_R=y > > + CONFIG_EFI_CAPSULE_ON_DISK=y > > + CONFIG_EFI_CAPSULE_FIRMWARE_MANAGEMENT=y > > + CONFIG_EFI_CAPSULE_FIRMWARE=y > > + CONFIG_EFI_CAPSULE_FIRMWARE_RAW=y > > + CONFIG_EFI_CAPSULE_FMP_HEADER=y > > + > > +In addition, the following config needs to be disabled:: > > + > > + CONFIG_TFABOOT > > + > > +The capsule file can be generated by using the GenerateCapsule.py > > +script in edk2:: > > + > > + $ ./BaseTools/BinWrappers/PosixLike/GenerateCapsule -e -o \ > > + <capsule_file_name> --fw-version <val> --lsv <val> --guid \ > > + e2bb9c06-70e9-4b14-97a3-5a7913176e3f --verbose --update-image-index > \ > > + <val> --verbose <u-boot.bin> > > + > > +As per the uefi specification, the capsule file needs to be placed on > > +the EFI System Partition, under the EFI/UpdateCapsule/ directory. The > > +EFI System Partition can be a virtio-blk-device. > > + > > +Before initiating the firmware update, the efi variables BootNext, > > +BootXXXX and OsIndications need to be set. The BootXXXX variable needs > > +to be pointing to the EFI System Partition which contains the capsule > > +file. The BootNext, BootXXXX and OsIndications variables can be set > > +using the following commands:: > > + > > + => efidebug boot add 0 Boot0000 virtio 0:1 <capsule_file_name> > > + => efidebug boot next 0 > > + => setenv -e -nv -bs -rt -v OsIndications =0x04 > > + => saveenv > > + > > +Finally, the capsule update can be initiated with the following > > +command:: > > + > > + => efidebug capsule disk-update > > + > > +The updated u-boot image will be booted on subsequent boot. > > + > > +Enabling Capsule Authentication > > +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ > > + > > +The uefi specification defines a way of authenticating the capsule to > > +be updated by verifying the capsule signature. The capsule signature > > +is computed and prepended to the capsule payload at the time of > > +capsule generation. This signature is then verified by using the > > +public key stored as part of the X509 certificate. This certificate is > > +in the form of an efi signature list (esl) file, which is embedded as > > +part of the platform's device tree blob using the mkeficapsule > > +utility. > > + > > +On the qemu virt platforms, the device-tree is generated on the fly > > +based on the devices configured. This device tree is then passed on to > > +the various software components booting on the platform, including > > +u-boot. Therefore, on the qemu virt platform, the signatute is > > +embedded on an overlay. This overlay is then applied at runtime to the > > +base platform device-tree. Steps needed for embedding the esl file in > > +the overlay are highlighted below. > > + > > +The capsule authentication feature can be enabled through the > > +following config, in addition to the configs listed above for capsule > > +update:: > > + > > + CONFIG_EFI_CAPSULE_AUTHENTICATE=y > > + > > +The public and private keys used for the signing process are generated > > +and used by the steps highlighted below:: > > + > > + 1. Install utility commands on your host > > + * openssl > > + * efitools > > + > > + 2. Create signing keys and certificate files on your host > > + > > + $ openssl req -x509 -sha256 -newkey rsa:2048 -subj /CN=CRT/ \ > > + -keyout CRT.key -out CRT.crt -nodes -days 365 > > + $ cert-to-efi-sig-list CRT.crt CRT.esl > > + > > + $ openssl x509 -in CRT.crt -out CRT.cer -outform DER > > + $ openssl x509 -inform DER -in CRT.cer -outform PEM -out > CRT.pub.pem > > + > > + $ openssl pkcs12 -export -out CRT.pfx -inkey CRT.key -in CRT.crt > > + $ openssl pkcs12 -in CRT.pfx -nodes -out CRT.pem > > + > > +The capsule file can be generated by using the GenerateCapsule.py > > +script in edk2:: > > + > > + $ ./BaseTools/BinWrappers/PosixLike/GenerateCapsule -e -o \ > > + <capsule_file_name> --monotonic-count <val> --fw-version \ > > + <val> --lsv <val> --guid \ > > + e2bb9c06-70e9-4b14-97a3-5a7913176e3f --verbose \ > > + --update-image-index <val> --signer-private-cert \ > > + /path/to/CRT.pem --trusted-public-cert \ > > + /path/to/CRT.pub.pem --other-public-cert /path/to/CRT.pub.pem \ > > + <u-boot.bin> > > + > > +Place the capsule generated in the above step on the EFI System > > +Partition under the EFI/UpdateCapsule directory > > + > > +For embedding the public key certificate, the following steps need to > > +be followed:: > > + > > + 1. Generate a skeleton overlay dts file, with a single fragment > > + node and an empty __overlay__ node > > + > > + 2. Convert the dts to a corresponding dtb with the following > > + command > > + ./scripts/dtc/dtc -@ -I dts -O dtb -o <ov_dtb_file_name> \ > > + <dts_file> > > + > > + 3. Run the dtb file generated above through the mkeficapsule tool > > + in u-boot > > + ./tools/mkeficapsule -O <pub_key.esl> -D <ov_dtb> > > + > > +Running the above command results in the creation of a 'signature' > > +node in the dtb, under which the public key is stored as a > > +'capsule-key' property. The '-O' option is to be used since the > > +public key certificate(esl) file is being embedded in an overlay. > > + > > +The dtb file embedded with the certificate is now to be placed on an > > +EFI System Partition. This would then be loaded and "merged" with the > > +base platform fdt at runtime. > > + > > +Build u-boot with the following steps:: > > + > > + $ make qemu_arm64_defconfig > > + $ make menuconfig > > + Disable CONFIG_TFABOOT > > + Enable CONFIG_EFI_CAPSULE_AUTHENTICATE > > + Enable all configs needed for capsule update(listed above) > > + $ make all > > + > > +Boot the platform and perform the following steps on the u-boot > > +command line:: > > + > > + 1. Enable capsule authentication by setting the following env > > + variable > > + > > + => setenv capsule_authentication_enabled 1 > > + => saveenv > > + > > + 2. Load the overlay dtb to memory and merge it with the base fdt > > + > > + => fatload virtio 0:1 <$fdtovaddr> EFI/<ov_dtb_file> > > + => fdt addr $fdtcontroladdr > > + => fdt resize <size_of_ov_dtb_file> > > + => fdt apply <$fdtovaddr> > > + > > + 3. Set the following env and efi Boot variables > > + > > + => setenv -e -nv -bs -rt -v OsIndications =0x04 > > + => efidebug boot add 0 Boot0000 virtio 0:1 <capsule_file_name> > > + => efidebug boot next 0 > > + => saveenv > > + > > + 4. Finally, the capsule update can be initiated with the following > > + command > > + > > + => efidebug capsule disk-update > > + > > +On subsequent reboot, the platform should boot the updated u-boot > binary. > > > >