efivarfs, osimage: fix boot entry handling
efivarfs was updated to handle partition UUIDs in the mixed-endian
format [1], enabling it to produce correct boot entries. Its interface
was changed in the process, leading to further changes in osimage.
In addition, BootEntry.Marshal will replace any backslash with a
forward slash in the EFI executable path.
[1] https://en.wikipedia.org/wiki/Universally_unique_identifier#Encoding
Change-Id: Ib8300e01fd1664d0c08bb033b1dc36addb925b20
Reviewed-on: https://review.monogon.dev/c/monogon/+/456
Reviewed-by: Lorenz Brun <lorenz@monogon.tech>
diff --git a/metropolis/pkg/efivarfs/boot.go b/metropolis/pkg/efivarfs/boot.go
index 096ec7c..4178c8d 100644
--- a/metropolis/pkg/efivarfs/boot.go
+++ b/metropolis/pkg/efivarfs/boot.go
@@ -26,7 +26,9 @@
import (
"fmt"
"math"
+ "strings"
+ "github.com/google/uuid"
"golang.org/x/text/transform"
)
@@ -51,7 +53,7 @@
type BootEntry struct {
Description string // eg. "Linux Boot Manager"
Path string // eg. `\EFI\systemd\systemd-bootx64.efi`
- PartitionGUID string
+ PartitionGUID uuid.UUID
PartitionNumber uint32 // Starts with 1
PartitionStart uint64 // LBA
PartitionSize uint64 // LBA
@@ -63,7 +65,7 @@
// as attributes of an EFI variable) are always set to LOAD_OPTION_ACTIVE.
func (t *BootEntry) Marshal() ([]byte, error) {
if t.Description == "" ||
- t.PartitionGUID == "00000000-0000-0000-0000-000000000000" ||
+ t.PartitionGUID.String() == "00000000-0000-0000-0000-000000000000" ||
t.Path == "" ||
t.PartitionNumber == 0 ||
t.PartitionStart == 0 ||
@@ -83,7 +85,9 @@
dp = append32(dp, t.PartitionNumber)
dp = append64(dp, t.PartitionStart)
dp = append64(dp, t.PartitionSize)
- dp = append(dp, t.PartitionGUID[0:16]...) // Partition Signature
+ // Append the partition GUID in the EFI format.
+ dp = append(dp, MarshalEFIGUID(t.PartitionGUID)...)
+
dp = append(dp,
0x02, // Partition Format ("GUID Partition Table")
0x02, // Signature Type ("GUID signature")
@@ -91,7 +95,8 @@
// EFI_LOAD_OPTION.FilePathList[1]
enc := Encoding.NewEncoder()
- path, _, e := transform.Bytes(enc, []byte(t.Path))
+ bsp := strings.ReplaceAll(t.Path, "/", "\\")
+ path, _, e := transform.Bytes(enc, []byte(bsp))
if e != nil {
return nil, fmt.Errorf("while encoding Path: %v", e)
}