diff --git a/Makefile b/Makefile
index a328652f0f23..760c143049aa 100644
--- a/Makefile
+++ b/Makefile
@@ -1734,6 +1734,12 @@ else
 u-boot-keep-syms-lto :=
 endif
 
+ifeq ($(MSYS_VERSION),0)
+add_ld_script := -T u-boot.lds
+else
+add_ld_script := u-boot.lds
+endif
+
 # Rule to link u-boot
 # May be overridden by arch/$(ARCH)/config.mk
 ifeq ($(LTO_ENABLE),y)
@@ -1742,7 +1748,7 @@ quiet_cmd_u-boot__ ?= LTO     $@
 		$(CC) -nostdlib -nostartfiles					\
 		$(LTO_FINAL_LDFLAGS) $(c_flags)					\
 		$(KBUILD_LDFLAGS:%=-Wl,%) $(LDFLAGS_u-boot:%=-Wl,%) -o $@	\
-		-T u-boot.lds $(u-boot-init)					\
+		$(add_ld_script) $(u-boot-init)					\
 		-Wl,--whole-archive						\
 			$(u-boot-main)						\
 			$(u-boot-keep-syms-lto)					\
@@ -1753,7 +1759,7 @@ quiet_cmd_u-boot__ ?= LTO     $@
 else
 quiet_cmd_u-boot__ ?= LD      $@
       cmd_u-boot__ ?= $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_u-boot) -o $@		\
-		-T u-boot.lds $(u-boot-init)					\
+		$(add_ld_script) $(u-boot-init)					\
 		--whole-archive							\
 			$(u-boot-main)						\
 		--no-whole-archive						\
@@ -1905,10 +1911,11 @@ endif
 # prepare2 creates a makefile if using a separate output directory
 prepare2: prepare3 outputmakefile cfg
 
+# Allow the linker script to be generated from LDSCRIPT_IN
 prepare1: prepare2 $(version_h) $(timestamp_h) $(dt_h) $(env_h) \
-                   include/config/auto.conf
-ifeq ($(wildcard $(LDSCRIPT)),)
-	@echo >&2 "  Could not find linker script."
+                   include/config/auto.conf $(if $(LDSCRIPT_IN),$(LDSCRIPT))
+ifeq ($(wildcard $(LDSCRIPT))$(LDSCRIPT_IN),)
+	@echo >&2 "  Could not find linker script $(LDSCRIPT)"
 	@/bin/false
 endif
 
diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
index 2d184c5f652a..c97c39d4301b 100644
--- a/arch/sandbox/config.mk
+++ b/arch/sandbox/config.mk
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0+
+	# SPDX-License-Identifier: GPL-2.0+
 # Copyright (c) 2011 The Chromium OS Authors.
 
 PLATFORM_CPPFLAGS += -D__SANDBOX__ -U_FORTIFY_SOURCE
@@ -71,3 +71,20 @@ EFI_CRT0 := crt0_sandbox_efi.o
 EFI_RELOC := reloc_sandbox_efi.o
 AFLAGS_crt0_sandbox_efi.o += -DHOST_ARCH="$(HOST_ARCH)"
 CFLAGS_reloc_sandbox_efi.o += -DHOST_ARCH="$(HOST_ARCH)"
+
+ifneq ($(MSYS_VERSION),0)
+LDSCRIPT := $(objtree)/u-boot-pe.lds
+
+AWK_RDATA := ${srctree}/scripts/add_to_rdata.awk
+LDSCRIPT_IN := ${srctree}/arch/sandbox/cpu/u-boot-pe.lds.in
+
+quiet_cmd_gen_lds = GEN LDS $@
+cmd_gen_lds = echo "int main() { return 0; }" | $(CC) -x c - -Wl,-verbose | \
+		awk -f $(AWK_RDATA) -v INFILE=$< >$@
+
+# Write out the contents of INFILE immediately before the close of the .rdata
+# block
+$(LDSCRIPT): $(LDSCRIPT_IN) $(AWK_RDATA) FORCE
+	$(call if_changed,gen_lds)
+
+endif
diff --git a/arch/sandbox/cpu/u-boot-pe.lds.in b/arch/sandbox/cpu/u-boot-pe.lds.in
new file mode 100644
index 000000000000..0ec7ef3bb350
--- /dev/null
+++ b/arch/sandbox/cpu/u-boot-pe.lds.in
@@ -0,0 +1,25 @@
+	/* U-Boot additions from here on */
+	. = ALIGN(4);
+	KEEP(*(SORT(__u_boot_list*)));
+
+	*(_u_boot_sandbox_getopt_start)
+	*(_u_boot_sandbox_getopt)
+	*(_u_boot_sandbox_getopt_end)
+
+	*(___efi_runtime_start)
+	*(efi_runtime_text)
+	*(efi_runtime_data)
+	*(___efi_runtime_stop)
+
+	*(___efi_runtime_rel_start)
+	*(.relefi_runtime_text)
+	*(.relefi_runtime_data)
+	*(___efi_runtime_rel_stop)
+
+	. = ALIGN(4);
+	*(.rodata.ttf.init)
+	*(.rodata.splash.init)
+	*(.rodata.helloworld.init)
+	*(.dtb.init.rodata)
+
+	/* U-Boot additions end */
diff --git a/scripts/add_to_rdata.awk b/scripts/add_to_rdata.awk
new file mode 100644
index 000000000000..43fdfe8bb789
--- /dev/null
+++ b/scripts/add_to_rdata.awk
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2023 Google, Inc
+#
+# Awk script to extract the default link script from the linker and write out
+# the contents of INFILE immediately before the close of the .rdata section.
+
+# to a C string which can be compiled into U-Boot.
+
+# INS = 1 if we are inside the link script (delimited by ======== lines)
+# INR = 1 if we are inside the .rdata section
+
+# When we see } while in the .rdata part of the link script, insert INFILE
+/}/ { if (INS && INR) { while ((getline < INFILE) > 0) {print}; DONE=1; INR=0; $0="}"; }}
+
+# Find start and end of link script
+/===================/ { if (INS) exit; INS=1; next; }
+
+# If inside the link script, print each line
+{ if (INS) print; }
+
+# Detect the .rdata section and get ready to insert INFILE when we see the end }
+/\.rdata.*:/ {INR=1; }
+
+END { if (!DONE) { print "add_to_rdata.awk: Could not find link script in ld output" > "/dev/stderr"; exit 1;} }
