Skip to content

Modernize rpi-5 build #128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jun 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions Tools/Toolsets/rpi-5-elf.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"schemaVersion": "1.0",
"swiftCompiler": {
"extraCLIOptions": [
"-Xfrontend", "-disable-stack-protector",
"-Xfrontend", "-function-sections",
"-enable-experimental-feature", "Embedded",
"-Xfrontend", "-mergeable-symbols",
"-Xclang-linker", "-fuse-ld=lld",
"-Xclang-linker", "-nostdlib"
]
},
"linker": {
"extraCLIOptions": [
"-T", "Sources/Support/linkerscript.ld",
"--unresolved-symbols=ignore-in-object-files"
]
}
}
61 changes: 40 additions & 21 deletions rpi-4b-blink/Makefile
Original file line number Diff line number Diff line change
@@ -1,28 +1,47 @@
SWIFT_EXEC ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f swift; else which swift; fi)
CLANG ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f clang; else which clang; fi)
LLVM_OBJCOPY ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f llvm-objcopy; else which llvm-objcopy; fi)
##===----------------------------------------------------------------------===##
##
## This source file is part of the Swift open source project
##
## Copyright (c) 2025 Apple Inc. and the Swift project authors.
## Licensed under Apache License v2.0 with Runtime Library Exception
##
## See https://swift.org/LICENSE.txt for license information
##
##===----------------------------------------------------------------------===##

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

.PHONY: all clean
# Flags
ARCH := aarch64
TARGET := $(ARCH)-none-none-elf
SWIFT_BUILD_ARGS := \
--configuration release \
--triple $(TARGET) \
--toolset $(TOOLSET) \
--disable-local-rpath
BUILDROOT := $(shell $(SWIFT_BUILD) $(SWIFT_BUILD_ARGS) --show-bin-path)

all: kernel8.img
.PHONY: build
build:
@echo "building..."
$(SWIFT_BUILD) \
$(SWIFT_BUILD_ARGS) \
--verbose

kernel8.img: kernel8.elf
@echo "💾 Converting to binary kernel image with llvm-objcopy..."
$(LLVM_OBJCOPY) -O binary kernel8.elf kernel8.img
@echo ""
@echo "🥳 Done! kernel8.img was saved to this directory."
@echo "extracting binary..."
$(LLVM_OBJCOPY) \
-O binary \
"$(BUILDROOT)/Application" \
"$(BUILDROOT)/Application.bin" \

kernel8.elf: $(BUILDROOT)/libMainApp.a $(BUILDROOT)/Support.build/boot.S.o link.ld
@echo "🔗 Linking with clang..."
$(CLANG) --target=aarch64-elf -o kernel8.elf $< $^ -fuse-ld=lld -nostdlib -Wl,--unresolved-symbols=ignore-in-object-files -Wl,-T ./link.ld
@echo ""

$(BUILDROOT)/libMainApp.a $(BUILDROOT)/Support.build/boot.S.o:
@echo "🛠️ Building with Swift Package Manager..."
$(SWIFT_EXEC) build --configuration release --triple aarch64-none-none-elf -Xswiftc -Xfrontend -Xswiftc -disable-stack-protector
@echo ""

.PHONY: clean
clean:
rm -rf kernel8.elf kernel8.img .build
@echo "cleaning..."
@swift package clean
@rm -rf .build
6 changes: 3 additions & 3 deletions rpi-4b-blink/Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 9 additions & 23 deletions rpi-4b-blink/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,19 @@
import PackageDescription

let package = Package(
name: "RPi4B-Blink",
platforms: [
.macOS(.v14)
],
name: "rpi-4b-blink",
products: [
.library(
name: "MainApp",
type: .static,
targets: ["MainApp"])
.executable(name: "Application", targets: ["Application"])
],
dependencies: [
.package(
url: "https://github.com/apple/swift-mmio.git",
branch: "swift-embedded-examples")
.package(url: "https://github.com/apple/swift-mmio.git", branch: "main")
],
targets: [
.target(
name: "MainApp",
.executableTarget(
name: "Application",
dependencies: [
.product(name: "MMIO", package: "swift-mmio")
],
swiftSettings: [
.enableExperimentalFeature("Embedded"),
.unsafeFlags(["-Xfrontend", "-function-sections"]),
]
),
.product(name: "MMIO", package: "swift-mmio"),
"Support",
]),
.target(name: "Support"),

]
)
])
5 changes: 1 addition & 4 deletions rpi-4b-blink/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,16 @@

- A Raspberry Pi 4B board
- 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.
- 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`.

## How to build and run this example:

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

Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2024 Apple Inc. and the Swift project authors.
// Copyright (c) 2025 Apple Inc. and the Swift project authors.
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//

import MMIO
import Support

@Register(bitWidth: 32)
struct GPSET1 {
Expand Down Expand Up @@ -66,17 +67,19 @@ func ledOff() {
}
}

@main
struct Main {
func delay() {
for _ in 1..<1_000_000 { nop() }
}

@main
struct Application {
static func main() {
setLedOutput()

while true {
ledOn()
for _ in 1..<100000 {} // just a delay
delay()
ledOff()
for _ in 1..<100000 {} // just a delay
delay()
}
}
}
16 changes: 16 additions & 0 deletions rpi-4b-blink/Sources/Support/include/Support.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift project authors.
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
//
//===----------------------------------------------------------------------===//

#pragma once

static inline __attribute((always_inline)) void nop() {
asm volatile("nop");
}
Empty file.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
SECTIONS
{
. = 0x80000; /* Kernel load address for AArch64 */
/* Kernel load address for AArch64 */
. = 0x80000;
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) }
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) }
PROVIDE(_data = .);
Expand All @@ -14,6 +15,13 @@ SECTIONS
}
_end = .;

/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) }
/DISCARD/ : {
*(.comment)
*(.gnu*)
*(.note*)
*(.eh_frame*)
*(.swift_modhash)
}
}
__bss_size = (__bss_end - __bss_start)>>3;

__bss_size = (__bss_end - __bss_start) >> 3;
61 changes: 40 additions & 21 deletions rpi-5-blink/Makefile
Original file line number Diff line number Diff line change
@@ -1,28 +1,47 @@
SWIFT_EXEC ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f swift; else which swift; fi)
CLANG ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f clang; else which clang; fi)
LLVM_OBJCOPY ?= $(shell if [ "$(shell uname)" = "Darwin" ]; then xcrun -f llvm-objcopy; else which llvm-objcopy; fi)
##===----------------------------------------------------------------------===##
##
## This source file is part of the Swift open source project
##
## Copyright (c) 2025 Apple Inc. and the Swift project authors.
## Licensed under Apache License v2.0 with Runtime Library Exception
##
## See https://swift.org/LICENSE.txt for license information
##
##===----------------------------------------------------------------------===##

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

.PHONY: all clean
# Flags
ARCH := aarch64
TARGET := $(ARCH)-none-none-elf
SWIFT_BUILD_ARGS := \
--configuration release \
--triple $(TARGET) \
--toolset $(TOOLSET) \
--disable-local-rpath
BUILDROOT := $(shell $(SWIFT_BUILD) $(SWIFT_BUILD_ARGS) --show-bin-path)

all: kernel8.img
.PHONY: build
build:
@echo "building..."
$(SWIFT_BUILD) \
$(SWIFT_BUILD_ARGS) \
--verbose

kernel8.img: kernel8.elf
@echo "💾 Converting to binary kernel image with llvm-objcopy..."
$(LLVM_OBJCOPY) -O binary kernel8.elf kernel8.img
@echo ""
@echo "🥳 Done! kernel8.img was saved to this directory."
@echo "extracting binary..."
$(LLVM_OBJCOPY) \
-O binary \
"$(BUILDROOT)/Application" \
"$(BUILDROOT)/Application.bin"

kernel8.elf: $(BUILDROOT)/libMainApp.a $(BUILDROOT)/Support.build/boot.S.o link.ld
@echo "🔗 Linking with clang..."
$(CLANG) --target=aarch64-elf -o kernel8.elf $< $^ -fuse-ld=lld -nostdlib -Wl,--unresolved-symbols=ignore-in-object-files -Wl,-T ./link.ld
@echo ""

$(BUILDROOT)/libMainApp.a $(BUILDROOT)/Support.build/boot.S.o:
@echo "🛠️ Building with Swift Package Manager..."
$(SWIFT_EXEC) build --configuration release --triple aarch64-none-none-elf -Xswiftc -Xfrontend -Xswiftc -disable-stack-protector
@echo ""

.PHONY: clean
clean:
rm -rf kernel8.elf kernel8.img .build
@echo "cleaning..."
@swift package clean
@rm -rf .build
6 changes: 3 additions & 3 deletions rpi-5-blink/Package.resolved

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 9 additions & 23 deletions rpi-5-blink/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,33 +3,19 @@
import PackageDescription

let package = Package(
name: "RPi5-Blink",
platforms: [
.macOS(.v14)
],
name: "rpi-5-blink",
products: [
.library(
name: "MainApp",
type: .static,
targets: ["MainApp"])
.executable(name: "Application", targets: ["Application"])
],
dependencies: [
.package(
url: "https://github.com/apple/swift-mmio.git",
branch: "swift-embedded-examples")
.package(url: "https://github.com/apple/swift-mmio.git", branch: "main")
],
targets: [
.target(
name: "MainApp",
.executableTarget(
name: "Application",
dependencies: [
.product(name: "MMIO", package: "swift-mmio")
],
swiftSettings: [
.enableExperimentalFeature("Embedded"),
.unsafeFlags(["-Xfrontend", "-function-sections"]),
]
),
.product(name: "MMIO", package: "swift-mmio"),
"Support",
]),
.target(name: "Support"),

]
)
])
Loading
Loading