From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by mx.groups.io with SMTP id smtpd.web12.12085.1613756011662407390 for ; Fri, 19 Feb 2021 09:33:31 -0800 Authentication-Results: mx.groups.io; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=B5ec2EWm; spf=pass (domain: redhat.com, ip: 170.10.133.124, mailfrom: lersek@redhat.com) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1613756010; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=hUFl7PRATi6wC+tglYJVWGXbSomdoakRMwitJ4SEFKc=; b=B5ec2EWma36QGwjdFDOFB0tM3kql2k67L2oA7d13xtZ4tM5O8SWM+19g3+XCDPYxJmB+bq 6/EHhx8jyrXH6VvH2O3o6beEQJshBrOXOsxbneO9tG6tYndEkP2xvnrt1RckPe58waG7fy kHjk6Q3xCAvfWu92/uRnTK+ENG2tSWs= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-26-uCeoZ6XHNWeANB2537OSrA-1; Fri, 19 Feb 2021 12:33:26 -0500 X-MC-Unique: uCeoZ6XHNWeANB2537OSrA-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 52B951E561; Fri, 19 Feb 2021 17:33:25 +0000 (UTC) Received: from lacos-laptop-7.usersys.redhat.com (ovpn-113-87.ams2.redhat.com [10.36.113.87]) by smtp.corp.redhat.com (Postfix) with ESMTP id 265721962E; Fri, 19 Feb 2021 17:33:23 +0000 (UTC) To: edk2-devel-groups-io , iPXE devel list Cc: Michael Brown From: "Laszlo Ersek" Subject: EfiRom vs. iPXE usability note Message-ID: Date: Fri, 19 Feb 2021 18:33:22 +0100 MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.11 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=lersek@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset=utf-8 Content-Language: en-US Content-Transfer-Encoding: 7bit Hi All, this is just a small note on the usability of the EfiRom utility from BaseTools, in particular in combination with iPXE option ROMs. The PCI Firmware Spec does not seem to specify a particular "checksum byte" in the option ROM format, it only seems to state that the bytes in the option ROM must sum to zero. This (apparently) allows option ROM providers to implement different schemes for placing the checksum byte. When talking about traditional BIOS ROMs, EfiRom considers the last byte in the image the checksum byte. The assumption is that the last byte is padding anyway, so it can be repurposed as a checksum byte. On the other hand, iPXE's "util/catrom.pl", or more precisely, "util/Option/ROM.pm", considers byte#6 -- a reserved byte -- in the PCI Expansion ROM Header the checksum byte. iPXE's choice is arguably safer, because it does not assume any particular padding at the end of the traditional ROM BIOS image that could be stolen as checksum byte. We've recently had a weird (difficult) bug [*] where, in the iPXE build, the virtio-net BIOS option ROM ended up a whole multiple of 512 bytes, *without* padding. Therefore, the "util/padimg.pl" utility, invoked by the iPXE build process, would not append any padding to the end of the BIOS ROM file. Subsequently, when we combined the BIOS option ROM and the EFI option ROM into a combined image, as follows: EfiRom -f "$vid" -i "$did" --pci23 \ -b bin/${rom}.rom \ -ec bin-x86_64-efi/${rom}.efidrv \ -o bin-combined/${rom}.rom EfiRom would *corrupt* the BIOS ROM, by changing its last byte (which was *not* a padding byte, in this rare case). EfiRom justifiedly needed to update the "last image indicator" in the BIOS ROM, but the checksum compensation for that happened in the wrong place (the last byte was not a padding byte). Consequently, iPXE's self-decompression (LZMA) and/or CRC32 check would fail during traditional BIOS boot, in the following call tree: install_prealloc [arch/x86/prefix/libprefix.S] install_block (...) install_block (...) install_block (...) install_block (.textdata) process_bytes (decompress16) install_block_death This was difficult to debug because even small changes to the assembly code (let alone enabling the existent, feature-ful, debugging infrastructure) would increase the LZMA-compressed stream's size, trigger padding during the build, and hide the corruption. [*] https://bugzilla.redhat.com/show_bug.cgi?id=1926561 We found the following solution: EfiRom -f "$vid" -i "$did" --pci23 \ -ec bin-x86_64-efi/${rom}.efidrv \ -o bin-combined/${rom}.eficrom util/catrom.pl \ bin/${rom}.rom \ bin-combined/${rom}.eficrom \ > bin-combined/${rom}.rom I.e., continue invoking EfiRom, but only for compressing the EFI driver image, stand-alone. And the combining of the BIOS and EFI ROMs is now performed with iPXE's "util/catrom.pl" program, which has the safer checksum byte placement. ( Like Michael has recommended before, it's also possible to eliminate EfiRom from the equation completely, and just build "*.efirom" in place of "*.efidrv". That would give us an EFI ROM image, passable to "catrom.pl", unlike a "naked" EFI driver executable (*.efidrv). However, iPXE's "util/efirom" tool, which converts *.efidrv to *.efirom, doesn't seem to offer "EFI compression", while EfiRom does (-ec option). For QEMU live-migration compatibility, we further pad the *combined* ROM images, currently to 256 KB. Abandoning EFI compression would eat up approx. 80KB suddenly, and nearly exhaust our current padding. Hence the above "hybrid" approach, where we retain EfiRom for the EFI compression's sake, but use "util/catrom.pl" for combining the images. ) Assuming my reading of the PCI Firmware Spec is correct, I think that not specifying a particular checksum byte, in the various headers, was a mistake in the spec. It's difficult to combine ROMs of different origins into a multi-ROM image, like this. I'm sending this note because it could prove useful to other distros that use EfiRom similarly. Thanks Laszlo