From 99d8c7598e140e87217b375e0a4f4c4a8a630e71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mika=C3=ABl=20Cluseau?= Date: Wed, 17 Jun 2026 11:37:52 +0200 Subject: [PATCH] format ESP using mformat --- Dockerfile | 8 +-- cmd/dkl-local-server/boot-img.go | 116 +++++++++++++++++++------------ 2 files changed, 75 insertions(+), 49 deletions(-) diff --git a/Dockerfile b/Dockerfile index 58def4d..f142434 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,7 +1,7 @@ from novit.tech/direktil/dkl:v1.2.0 as dkl # ------------------------------------------------------------------------ -from golang:1.26.1-trixie as build +from golang:1.26.4-trixie as build run apt-get update && apt-get install -y git @@ -27,11 +27,11 @@ from debian:trixie entrypoint ["/bin/dkl-local-server"] env _uncache=1 -run apt update \ +run --mount=type=cache,id=debian-trixie-apt,target=/var/cache/apt \ + apt update \ && yes |apt install -y genisoimage gdisk dosfstools util-linux udev binutils systemd \ grub2 grub-pc-bin grub-efi-amd64-bin ca-certificates curl openssh-client qemu-utils wireguard-tools \ - erofs-utils erofsfuse cryptsetup systemd-boot-efi \ - && apt clean + erofs-utils erofsfuse cryptsetup systemd-boot-efi mtools copy --from=dkl /bin/dkl /bin/dls /bin/ copy --from=build /src/dist/ /bin/ diff --git a/cmd/dkl-local-server/boot-img.go b/cmd/dkl-local-server/boot-img.go index 5f54ac3..6bf73f3 100644 --- a/cmd/dkl-local-server/boot-img.go +++ b/cmd/dkl-local-server/boot-img.go @@ -2,6 +2,7 @@ package main import ( "archive/tar" + "bytes" "compress/gzip" "flag" "fmt" @@ -93,47 +94,11 @@ func qemuImgBootImg(format string, uki bool, cmdline string) func(out io.Writer, } } -var grubSupportVersion = flag.String("grub-support", "1.1.0", "GRUB support version") - func setupBootImage(bootImg *os.File, ctx *renderContext, uki bool, cmdline string) (err error) { if uki { - err = bootImg.Truncate(192 << 20) - if err != nil { - return - } - err = bootImg.Sync() - if err != nil { - return - } - - err = run("sgdisk", bootImg.Name(), "--clear", "--largest-new=1", "--typecode=1:EF00", "--change-name=1:ESP") - if err != nil { - return - } - + err = baseDiskUki(bootImg, 192) } else { - err = func() (err error) { - path, err := distFetch("grub-support", *grubSupportVersion) - if err != nil { - return - } - - baseImage, err := os.Open(path) - if err != nil { - return - } - - defer baseImage.Close() - - baseImageGz, err := gzip.NewReader(baseImage) - if err != nil { - return - } - - defer baseImageGz.Close() - _, err = io.Copy(bootImg, baseImageGz) - return - }() + err = baseDiskGrub(bootImg) } if err != nil { return err @@ -170,13 +135,6 @@ func setupBootImage(bootImg *os.File, ctx *renderContext, uki bool, cmdline stri devp1 := dev + "p1" - if uki { - err = run("mkfs.vfat", "-F", "32", devp1) - if err != nil { - return fmt.Errorf("mkfs.vfat: %w", err) - } - } - err = syscall.Mount(devp1, tempDir, "vfat", 0, "") if err != nil { return fmt.Errorf("failed to mount %s to %s: %v", devp1, tempDir, err) @@ -231,6 +189,74 @@ func setupBootImage(bootImg *os.File, ctx *renderContext, uki bool, cmdline stri return } +func baseDiskUki(image *os.File, sizeMB int16) (err error) { + err = image.Truncate(0) + if err != nil { + return + } + + size := int64(sizeMB) << 20 + + err = image.Truncate(size) + if err != nil { + return + } + err = image.Sync() + if err != nil { + return + } + + err = run("sgdisk", "--zap", "--new=1:2048:", "--typecode=1:EF00", "--change-name=1:ESP", image.Name()) + if err != nil { + return + } + + const ( + espOffset = 2048 * 512 + gptBackupSectors = 34 // real world data + ) + espSectors := (size-espOffset)/512 - gptBackupSectors + + cfg := fmt.Sprintf("drive d: file=%q offset=%d\n", image.Name(), espOffset) + err = mtool(cfg, "mformat", "-F", "-T", fmt.Sprint(espSectors), "d:") + + return +} + +var grubSupportVersion = flag.String("grub-support", "1.1.1", "GRUB support version") + +func baseDiskGrub(image *os.File) (err error) { + path, err := distFetch("grub-support", *grubSupportVersion) + if err != nil { + return + } + + baseImage, err := os.Open(path) + if err != nil { + return + } + + defer baseImage.Close() + + baseImageGz, err := gzip.NewReader(baseImage) + if err != nil { + return + } + + defer baseImageGz.Close() + _, err = io.Copy(image, baseImageGz) + return +} + +func mtool(config string, program string, args ...string) (err error) { + cmd := exec.Command(program, args...) + cmd.Env = append(os.Environ(), "MTOOLSRC=/dev/stdin") + cmd.Stdin = bytes.NewBufferString(config) + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + return cmd.Run() +} + func run(program string, args ...string) (err error) { cmd := exec.Command(program, args...) cmd.Stdout = os.Stdout