diff --git a/src/cmd/dist/buildtool.go b/src/cmd/dist/buildtool.go
index 1eeb32afd3b4d202217aa1127f82c04355e0f55f..f2228df33de7f57932b6c90e580d72e8a128addc 100644
--- a/src/cmd/dist/buildtool.go
+++ b/src/cmd/dist/buildtool.go
@@ -68,10 +68,11 @@ var bootstrapDirs = []string{
 	"internal/goroot",
 	"internal/goversion",
 	"internal/pkgbits",
+	"internal/platform",
 	"internal/profile",
 	"internal/race",
 	"internal/saferio",
-	"internal/platform",
+	"internal/syscall/unix",
 	"internal/types/errors",
 	"internal/unsafeheader",
 	"internal/xcoff",
diff --git a/src/cmd/link/internal/ld/fallocate_test.go b/src/cmd/link/internal/ld/fallocate_test.go
index 1ed0eb2ca74f9d5ca9a9c483085b9b7acdabc902..ad77be536fc834322c2812ed339458cba02a93c7 100644
--- a/src/cmd/link/internal/ld/fallocate_test.go
+++ b/src/cmd/link/internal/ld/fallocate_test.go
@@ -2,8 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build darwin || linux
-// +build darwin linux
+//go:build darwin || (freebsd && go1.21) || linux
 
 package ld
 
diff --git a/src/cmd/link/internal/ld/outbuf_freebsd.go b/src/cmd/link/internal/ld/outbuf_freebsd.go
new file mode 100644
index 0000000000000000000000000000000000000000..5ff17300c19686fffdccc2f25fed0dad17515148
--- /dev/null
+++ b/src/cmd/link/internal/ld/outbuf_freebsd.go
@@ -0,0 +1,13 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build freebsd && go1.21
+
+package ld
+
+import "internal/syscall/unix"
+
+func (out *OutBuf) fallocate(size uint64) error {
+	return unix.PosixFallocate(int(out.f.Fd()), 0, int64(size))
+}
diff --git a/src/cmd/link/internal/ld/outbuf_nofallocate.go b/src/cmd/link/internal/ld/outbuf_nofallocate.go
index dd5afc61db92803e7ee004e0515fc7dc870c1938..435be5e09fe5b950c0a33ffce3d70d0fd9a31363 100644
--- a/src/cmd/link/internal/ld/outbuf_nofallocate.go
+++ b/src/cmd/link/internal/ld/outbuf_nofallocate.go
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style
 // license that can be found in the LICENSE file.
 
-//go:build !darwin && !linux
+//go:build !darwin && !(freebsd && go1.21) && !linux
 
 package ld
 
diff --git a/src/cmd/link/internal/ld/outbuf_notdarwin.go b/src/cmd/link/internal/ld/outbuf_notdarwin.go
index f9caa413e3c3c198a906d362e2a0e4aa7e5d8b99..3e5c67a5c25ce74cef232bdfb3e6dbe0a4c43dbf 100644
--- a/src/cmd/link/internal/ld/outbuf_notdarwin.go
+++ b/src/cmd/link/internal/ld/outbuf_notdarwin.go
@@ -3,7 +3,6 @@
 // license that can be found in the LICENSE file.
 
 //go:build !darwin
-// +build !darwin
 
 package ld
 
diff --git a/src/internal/syscall/unix/fallocate_freebsd.go b/src/internal/syscall/unix/fallocate_freebsd.go
new file mode 100644
index 0000000000000000000000000000000000000000..6c3e80118b099d9073b8612471899d97a43f2626
--- /dev/null
+++ b/src/internal/syscall/unix/fallocate_freebsd.go
@@ -0,0 +1,18 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package unix
+
+import "syscall"
+
+// FreeBSD posix_fallocate system call number.
+const posixFallocateTrap uintptr = 530
+
+func PosixFallocate(fd int, off int64, size int64) error {
+	_, _, errno := syscall.Syscall(posixFallocateTrap, uintptr(fd), uintptr(off), uintptr(size))
+	if errno != 0 {
+		return errno
+	}
+	return nil
+}