Skip to content

Commit 733dadf

Browse files
authored
Modernize rpi-5 build (#128)
Updates the rpi-5-blink example to link using SwiftPM and use a toolset.json.
1 parent 0531e4a commit 733dadf

File tree

17 files changed

+207
-119
lines changed

17 files changed

+207
-119
lines changed

Tools/Toolsets/rpi-5-elf.json

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"schemaVersion": "1.0",
3+
"swiftCompiler": {
4+
"extraCLIOptions": [
5+
"-Xfrontend", "-disable-stack-protector",
6+
"-Xfrontend", "-function-sections",
7+
"-enable-experimental-feature", "Embedded",
8+
"-Xfrontend", "-mergeable-symbols",
9+
"-Xclang-linker", "-fuse-ld=lld",
10+
"-Xclang-linker", "-nostdlib"
11+
]
12+
},
13+
"linker": {
14+
"extraCLIOptions": [
15+
"-T", "Sources/Support/linkerscript.ld",
16+
"--unresolved-symbols=ignore-in-object-files"
17+
]
18+
}
19+
}

rpi-4b-blink/Makefile

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,47 @@
1-
SWIFT_EXEC ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f swift; else which swift; fi)
2-
CLANG ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f clang; else which clang; fi)
3-
LLVM_OBJCOPY ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f llvm-objcopy; else which llvm-objcopy; fi)
1+
##===----------------------------------------------------------------------===##
2+
##
3+
## This source file is part of the Swift open source project
4+
##
5+
## Copyright (c) 2025 Apple Inc. and the Swift project authors.
6+
## Licensed under Apache License v2.0 with Runtime Library Exception
7+
##
8+
## See https://swift.org/LICENSE.txt for license information
9+
##
10+
##===----------------------------------------------------------------------===##
411

5-
BUILDROOT := $(shell $(SWIFT_EXEC) build --configuration release --triple aarch64-none-none-elf -Xswiftc -Xfrontend -Xswiftc -disable-stack-protector --show-bin-path)
12+
# Paths
13+
REPOROOT := $(shell git rev-parse --show-toplevel)
14+
TOOLSROOT := $(REPOROOT)/Tools
15+
TOOLSET := $(TOOLSROOT)/Toolsets/rpi-5-elf.json
16+
LLVM_OBJCOPY := llvm-objcopy
17+
SWIFT_BUILD := swift build
618

7-
.PHONY: all clean
19+
# Flags
20+
ARCH := aarch64
21+
TARGET := $(ARCH)-none-none-elf
22+
SWIFT_BUILD_ARGS := \
23+
--configuration release \
24+
--triple $(TARGET) \
25+
--toolset $(TOOLSET) \
26+
--disable-local-rpath
27+
BUILDROOT := $(shell $(SWIFT_BUILD) $(SWIFT_BUILD_ARGS) --show-bin-path)
828

9-
all: kernel8.img
29+
.PHONY: build
30+
build:
31+
@echo "building..."
32+
$(SWIFT_BUILD) \
33+
$(SWIFT_BUILD_ARGS) \
34+
--verbose
1035

11-
kernel8.img: kernel8.elf
12-
@echo "💾 Converting to binary kernel image with llvm-objcopy..."
13-
$(LLVM_OBJCOPY) -O binary kernel8.elf kernel8.img
14-
@echo ""
15-
@echo "🥳 Done! kernel8.img was saved to this directory."
36+
@echo "extracting binary..."
37+
$(LLVM_OBJCOPY) \
38+
-O binary \
39+
"$(BUILDROOT)/Application" \
40+
"$(BUILDROOT)/Application.bin" \
1641

17-
kernel8.elf: $(BUILDROOT)/libMainApp.a $(BUILDROOT)/Support.build/boot.S.o link.ld
18-
@echo "🔗 Linking with clang..."
19-
$(CLANG) --target=aarch64-elf -o kernel8.elf $< $^ -fuse-ld=lld -nostdlib -Wl,--unresolved-symbols=ignore-in-object-files -Wl,-T ./link.ld
20-
@echo ""
21-
22-
$(BUILDROOT)/libMainApp.a $(BUILDROOT)/Support.build/boot.S.o:
23-
@echo "🛠️ Building with Swift Package Manager..."
24-
$(SWIFT_EXEC) build --configuration release --triple aarch64-none-none-elf -Xswiftc -Xfrontend -Xswiftc -disable-stack-protector
25-
@echo ""
2642

43+
.PHONY: clean
2744
clean:
28-
rm -rf kernel8.elf kernel8.img .build
45+
@echo "cleaning..."
46+
@swift package clean
47+
@rm -rf .build

rpi-4b-blink/Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rpi-4b-blink/Package.swift

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,19 @@
33
import PackageDescription
44

55
let package = Package(
6-
name: "RPi4B-Blink",
7-
platforms: [
8-
.macOS(.v14)
9-
],
6+
name: "rpi-4b-blink",
107
products: [
11-
.library(
12-
name: "MainApp",
13-
type: .static,
14-
targets: ["MainApp"])
8+
.executable(name: "Application", targets: ["Application"])
159
],
1610
dependencies: [
17-
.package(
18-
url: "https://github.com/apple/swift-mmio.git",
19-
branch: "swift-embedded-examples")
11+
.package(url: "https://github.com/apple/swift-mmio.git", branch: "main")
2012
],
2113
targets: [
22-
.target(
23-
name: "MainApp",
14+
.executableTarget(
15+
name: "Application",
2416
dependencies: [
25-
.product(name: "MMIO", package: "swift-mmio")
26-
],
27-
swiftSettings: [
28-
.enableExperimentalFeature("Embedded"),
29-
.unsafeFlags(["-Xfrontend", "-function-sections"]),
30-
]
31-
),
17+
.product(name: "MMIO", package: "swift-mmio"),
18+
"Support",
19+
]),
3220
.target(name: "Support"),
33-
34-
]
35-
)
21+
])

rpi-4b-blink/README.md

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,16 @@
66

77
- A Raspberry Pi 4B board
88
- An SD Card, with a Raspberry Pi OS installed (this way, we don't need to create the configuration files from scratch). You may backup `kernel8.img` and `config.txt` if you need the Linux install later, since we will change these files.
9-
- LLVM installed (`brew install llvm`) and added to PATH. This is needed to convert the resulted ELF file to binary image format using `llvm-objcopy`.
109

1110
## How to build and run this example:
1211

1312
- Make sure you have a recent nightly Swift toolchain that has Embedded Swift support.
1413
- Build the program, then copy the kernel image to the SD card.
1514
``` console
1615
$ cd rpi-4b-blink
17-
$ export TOOLCHAINS='<toolchain-identifier>' # Your Swift nightly toolchain identifier
1816
$ make
19-
$ cp kernel8.img /Volumes/bootfs
17+
$ cp .build/release/Application.bin /Volumes/bootfs/kernel8.img
2018
```
2119
- If your original OS is not 64-bit, make sure to set `arm_64bit=1` in `config.txt`.
2220
- Place the SD card in your Raspberry Pi 4B, and connect it to power.
2321
- After the boot sequence, the green (ACT) led will start blinking in a regular pattern.
24-

rpi-4b-blink/Sources/MainApp/MainApp.swift renamed to rpi-4b-blink/Sources/Application/Application.swift

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
//
33
// This source file is part of the Swift open source project
44
//
5-
// Copyright (c) 2024 Apple Inc. and the Swift project authors.
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors.
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
99
//
1010
//===----------------------------------------------------------------------===//
1111

1212
import MMIO
13+
import Support
1314

1415
@Register(bitWidth: 32)
1516
struct GPSET1 {
@@ -66,17 +67,19 @@ func ledOff() {
6667
}
6768
}
6869

69-
@main
70-
struct Main {
70+
func delay() {
71+
for _ in 1..<1_000_000 { nop() }
72+
}
7173

74+
@main
75+
struct Application {
7276
static func main() {
7377
setLedOutput()
74-
7578
while true {
7679
ledOn()
77-
for _ in 1..<100000 {} // just a delay
80+
delay()
7881
ledOff()
79-
for _ in 1..<100000 {} // just a delay
82+
delay()
8083
}
8184
}
8285
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2025 Apple Inc. and the Swift project authors.
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
//
10+
//===----------------------------------------------------------------------===//
11+
12+
#pragma once
13+
14+
static inline __attribute((always_inline)) void nop() {
15+
asm volatile("nop");
16+
}

rpi-4b-blink/Sources/Support/include/boot.h

Whitespace-only changes.

rpi-5-blink/link.ld renamed to rpi-4b-blink/Sources/Support/linkerscript.ld

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
SECTIONS
22
{
3-
. = 0x80000; /* Kernel load address for AArch64 */
3+
/* Kernel load address for AArch64 */
4+
. = 0x80000;
45
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
56
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
67
PROVIDE(_data = .);
@@ -14,6 +15,13 @@ SECTIONS
1415
}
1516
_end = .;
1617

17-
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
18+
/DISCARD/ : {
19+
*(.comment)
20+
*(.gnu*)
21+
*(.note*)
22+
*(.eh_frame*)
23+
*(.swift_modhash)
24+
}
1825
}
19-
__bss_size = (__bss_end - __bss_start)>>3;
26+
27+
__bss_size = (__bss_end - __bss_start) >> 3;

rpi-5-blink/Makefile

Lines changed: 40 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,47 @@
1-
SWIFT_EXEC ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f swift; else which swift; fi)
2-
CLANG ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f clang; else which clang; fi)
3-
LLVM_OBJCOPY ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f llvm-objcopy; else which llvm-objcopy; fi)
1+
##===----------------------------------------------------------------------===##
2+
##
3+
## This source file is part of the Swift open source project
4+
##
5+
## Copyright (c) 2025 Apple Inc. and the Swift project authors.
6+
## Licensed under Apache License v2.0 with Runtime Library Exception
7+
##
8+
## See https://swift.org/LICENSE.txt for license information
9+
##
10+
##===----------------------------------------------------------------------===##
411

5-
BUILDROOT := $(shell $(SWIFT_EXEC) build --configuration release --triple aarch64-none-none-elf -Xswiftc -Xfrontend -Xswiftc -disable-stack-protector --show-bin-path)
12+
# Paths
13+
REPOROOT := $(shell git rev-parse --show-toplevel)
14+
TOOLSROOT := $(REPOROOT)/Tools
15+
TOOLSET := $(TOOLSROOT)/Toolsets/rpi-5-elf.json
16+
LLVM_OBJCOPY := llvm-objcopy
17+
SWIFT_BUILD := swift build
618

7-
.PHONY: all clean
19+
# Flags
20+
ARCH := aarch64
21+
TARGET := $(ARCH)-none-none-elf
22+
SWIFT_BUILD_ARGS := \
23+
--configuration release \
24+
--triple $(TARGET) \
25+
--toolset $(TOOLSET) \
26+
--disable-local-rpath
27+
BUILDROOT := $(shell $(SWIFT_BUILD) $(SWIFT_BUILD_ARGS) --show-bin-path)
828

9-
all: kernel8.img
29+
.PHONY: build
30+
build:
31+
@echo "building..."
32+
$(SWIFT_BUILD) \
33+
$(SWIFT_BUILD_ARGS) \
34+
--verbose
1035

11-
kernel8.img: kernel8.elf
12-
@echo "💾 Converting to binary kernel image with llvm-objcopy..."
13-
$(LLVM_OBJCOPY) -O binary kernel8.elf kernel8.img
14-
@echo ""
15-
@echo "🥳 Done! kernel8.img was saved to this directory."
36+
@echo "extracting binary..."
37+
$(LLVM_OBJCOPY) \
38+
-O binary \
39+
"$(BUILDROOT)/Application" \
40+
"$(BUILDROOT)/Application.bin"
1641

17-
kernel8.elf: $(BUILDROOT)/libMainApp.a $(BUILDROOT)/Support.build/boot.S.o link.ld
18-
@echo "🔗 Linking with clang..."
19-
$(CLANG) --target=aarch64-elf -o kernel8.elf $< $^ -fuse-ld=lld -nostdlib -Wl,--unresolved-symbols=ignore-in-object-files -Wl,-T ./link.ld
20-
@echo ""
21-
22-
$(BUILDROOT)/libMainApp.a $(BUILDROOT)/Support.build/boot.S.o:
23-
@echo "🛠️ Building with Swift Package Manager..."
24-
$(SWIFT_EXEC) build --configuration release --triple aarch64-none-none-elf -Xswiftc -Xfrontend -Xswiftc -disable-stack-protector
25-
@echo ""
2642

43+
.PHONY: clean
2744
clean:
28-
rm -rf kernel8.elf kernel8.img .build
45+
@echo "cleaning..."
46+
@swift package clean
47+
@rm -rf .build

rpi-5-blink/Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rpi-5-blink/Package.swift

Lines changed: 9 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,33 +3,19 @@
33
import PackageDescription
44

55
let package = Package(
6-
name: "RPi5-Blink",
7-
platforms: [
8-
.macOS(.v14)
9-
],
6+
name: "rpi-5-blink",
107
products: [
11-
.library(
12-
name: "MainApp",
13-
type: .static,
14-
targets: ["MainApp"])
8+
.executable(name: "Application", targets: ["Application"])
159
],
1610
dependencies: [
17-
.package(
18-
url: "https://github.com/apple/swift-mmio.git",
19-
branch: "swift-embedded-examples")
11+
.package(url: "https://github.com/apple/swift-mmio.git", branch: "main")
2012
],
2113
targets: [
22-
.target(
23-
name: "MainApp",
14+
.executableTarget(
15+
name: "Application",
2416
dependencies: [
25-
.product(name: "MMIO", package: "swift-mmio")
26-
],
27-
swiftSettings: [
28-
.enableExperimentalFeature("Embedded"),
29-
.unsafeFlags(["-Xfrontend", "-function-sections"]),
30-
]
31-
),
17+
.product(name: "MMIO", package: "swift-mmio"),
18+
"Support",
19+
]),
3220
.target(name: "Support"),
33-
34-
]
35-
)
21+
])

0 commit comments

Comments
 (0)