-
Notifications
You must be signed in to change notification settings - Fork 54
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Raspberry Pi 4B & 5 baremetal examples (#67)
Provide new examples demonstrating how to run Swift Embedded on the Raspberry Pi 4B and 5 single-board computers, in a baremetal fashion, without an underlying operating system. The provided examples showcase how to blink the onboard green LED using Swift MMIO.
- Loading branch information
Showing
19 changed files
with
509 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
name: Build Raspberry Pi Baremetal Examples | ||
|
||
on: | ||
push: | ||
branches: ["main"] | ||
pull_request: | ||
branches: ["main"] | ||
schedule: | ||
# Build on Mondays at 9am PST every week | ||
- cron: '0 17 * * 1' | ||
jobs: | ||
build-rpi-baremetal: | ||
runs-on: ubuntu-24.04 | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
example: [rpi5-blink, rpi4b-blink] | ||
swift: [swift-DEVELOPMENT-SNAPSHOT-2024-12-04-a] | ||
|
||
steps: | ||
- name: Checkout repo | ||
uses: actions/checkout@v4 | ||
|
||
- name: Install apt dependencies | ||
run: sudo apt-get -qq update && sudo apt-get -qq -y install make llvm | ||
|
||
- name: Install ${{ matrix.swift }} | ||
run: | | ||
wget -q https://download.swift.org/development/ubuntu2404/${{ matrix.swift }}/${{ matrix.swift }}-ubuntu24.04.tar.gz | ||
tar xzf ${{ matrix.swift }}-ubuntu24.04.tar.gz | ||
export PATH="`pwd`/${{ matrix.swift }}-ubuntu24.04/usr/bin/:$PATH" | ||
echo "PATH=$PATH" >> $GITHUB_ENV | ||
which swiftc | ||
swiftc --version | ||
- name: Build ${{ matrix.example }} | ||
run: | | ||
cd ${{ matrix.example }} | ||
make |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
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) | ||
|
||
BUILDROOT := $(shell $(SWIFT_EXEC) build --triple aarch64-none-none-elf -Xswiftc -Xfrontend -Xswiftc -disable-stack-protector --show-bin-path) | ||
|
||
.PHONY: all clean | ||
|
||
all: kernel8.img | ||
|
||
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." | ||
|
||
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 --triple aarch64-none-none-elf -Xswiftc -Xfrontend -Xswiftc -disable-stack-protector | ||
@echo "" | ||
|
||
clean: | ||
rm -rf kernel8.elf kernel8.img .build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// swift-tools-version: 6.1 | ||
// The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "RPi4B-Blink", | ||
platforms: [ | ||
.macOS(.v14) | ||
], | ||
products: [ | ||
.library( | ||
name: "MainApp", | ||
type: .static, | ||
targets: ["MainApp"]) | ||
], | ||
dependencies: [ | ||
.package( | ||
url: "https://github.com/apple/swift-mmio.git", | ||
branch: "swift-embedded-examples") | ||
], | ||
targets: [ | ||
.target( | ||
name: "MainApp", | ||
dependencies: [ | ||
.product(name: "MMIO", package: "swift-mmio") | ||
], | ||
swiftSettings: [ | ||
.enableExperimentalFeature("Embedded"), | ||
.unsafeFlags(["-Xfrontend", "-function-sections"]), | ||
] | ||
), | ||
.target(name: "Support"), | ||
|
||
] | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
# rpi4b-blink | ||
|
||
<img src="assets/rpi4.png"> | ||
|
||
## Requirements | ||
|
||
- 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 rpi4b-blink | ||
$ export TOOLCHAINS='<toolchain-identifier>' # Your Swift nightly toolchain identifier | ||
$ make | ||
$ cp kernel8.img /Volumes/bootfs | ||
``` | ||
- 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. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift open source project | ||
// | ||
// Copyright (c) 2024 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 | ||
|
||
@Register(bitWidth: 32) | ||
struct GPSET1 { | ||
@ReadWrite(bits: 10..<11, as: Bool.self) | ||
var set: SET | ||
} | ||
|
||
@Register(bitWidth: 32) | ||
struct GPCLR1 { | ||
@ReadWrite(bits: 10..<11, as: Bool.self) | ||
var clear: CLEAR | ||
} | ||
|
||
@Register(bitWidth: 32) | ||
struct GPFSEL4 { | ||
@ReadWrite(bits: 6..<7, as: Bool.self) | ||
var fsel42b1: FSEL42b1 | ||
@ReadWrite(bits: 7..<8, as: Bool.self) | ||
var fsel42b2: FSEL42b2 | ||
@ReadWrite(bits: 8..<9, as: Bool.self) | ||
var fsel42b3: FSEL42b3 | ||
} | ||
|
||
@RegisterBlock | ||
struct GPIO { | ||
@RegisterBlock(offset: 0x200020) | ||
var gpset1: Register<GPSET1> | ||
@RegisterBlock(offset: 0x20002c) | ||
var gpclr1: Register<GPCLR1> | ||
@RegisterBlock(offset: 0x200010) | ||
var gpfsel4: Register<GPFSEL4> | ||
} | ||
|
||
let gpio = GPIO(unsafeAddress: 0xFE00_0000) | ||
|
||
func setLedOutput() { | ||
gpio.gpfsel4.modify { | ||
// setFunction Select 42 (fsel42) to 001 | ||
$0.fsel42b1 = true | ||
$0.fsel42b2 = false | ||
$0.fsel42b3 = false | ||
} | ||
} | ||
|
||
func ledOn() { | ||
gpio.gpset1.modify { | ||
$0.set = true | ||
} | ||
} | ||
|
||
func ledOff() { | ||
gpio.gpclr1.modify { | ||
$0.clear = true | ||
} | ||
} | ||
|
||
@main | ||
struct Main { | ||
|
||
static func main() { | ||
setLedOutput() | ||
|
||
while true { | ||
ledOn() | ||
for _ in 1..<100000 {} // just a delay | ||
ledOff() | ||
for _ in 1..<100000 {} // just a delay | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This source file is part of the Swift open source project | ||
// | ||
// Copyright (c) 2024 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 | ||
// | ||
//===----------------------------------------------------------------------===// | ||
|
||
.section ".text.boot" | ||
|
||
.global _start | ||
|
||
_start: | ||
// Check processor ID is zero (executing on main core), else hang | ||
mrs x1, mpidr_el1 | ||
and x1, x1, #3 | ||
cbz x1, 2f | ||
// We're not on the main core, so hang in an infinite wait loop | ||
1: wfe | ||
b 1b | ||
2: // We're on the main core! | ||
|
||
// Set stack to start below our code | ||
ldr x1, =_start | ||
mov sp, x1 | ||
|
||
// Clean the BSS section | ||
ldr x1, =__bss_start // Start address | ||
ldr w2, =__bss_size // Size of the section | ||
3: cbz w2, 4f // Quit loop if zero | ||
str xzr, [x1], #8 | ||
sub w2, w2, #1 | ||
cbnz w2, 3b // Loop if non-zero | ||
|
||
// Jump to Swift! | ||
4: bl main | ||
// Halt if Swift returns | ||
b 1b |
Empty file.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
SECTIONS | ||
{ | ||
. = 0x80000; /* Kernel load address for AArch64 */ | ||
.text : { KEEP(*(.text.boot)) *(.text .text.* .gnu.linkonce.t*) } | ||
.rodata : { *(.rodata .rodata.* .gnu.linkonce.r*) } | ||
PROVIDE(_data = .); | ||
.data : { *(.data .data.* .gnu.linkonce.d*) } | ||
.bss (NOLOAD) : { | ||
. = ALIGN(16); | ||
__bss_start = .; | ||
*(.bss .bss.*) | ||
*(COMMON) | ||
__bss_end = .; | ||
} | ||
_end = .; | ||
|
||
/DISCARD/ : { *(.comment) *(.gnu*) *(.note*) *(.eh_frame*) } | ||
} | ||
__bss_size = (__bss_end - __bss_start)>>3; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
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) | ||
|
||
BUILDROOT := $(shell $(SWIFT_EXEC) build --triple aarch64-none-none-elf -Xswiftc -Xfrontend -Xswiftc -disable-stack-protector --show-bin-path) | ||
|
||
.PHONY: all clean | ||
|
||
all: kernel8.img | ||
|
||
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." | ||
|
||
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 --triple aarch64-none-none-elf -Xswiftc -Xfrontend -Xswiftc -disable-stack-protector | ||
@echo "" | ||
|
||
clean: | ||
rm -rf kernel8.elf kernel8.img .build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"originHash" : "193ca3f107e2c8dd2da5d091f6259f64b2cbfd6776d1c26bbcfb195b3a0b5045", | ||
"pins" : [ | ||
{ | ||
"identity" : "swift-argument-parser", | ||
"kind" : "remoteSourceControl", | ||
"location" : "https://github.com/apple/swift-argument-parser.git", | ||
"state" : { | ||
"revision" : "41982a3656a71c768319979febd796c6fd111d5c", | ||
"version" : "1.5.0" | ||
} | ||
}, | ||
{ | ||
"identity" : "swift-mmio", | ||
"kind" : "remoteSourceControl", | ||
"location" : "https://github.com/apple/swift-mmio.git", | ||
"state" : { | ||
"branch" : "swift-embedded-examples", | ||
"revision" : "06d96ed4916739f2edafde87f3951b2d2a04df65" | ||
} | ||
}, | ||
{ | ||
"identity" : "swift-syntax", | ||
"kind" : "remoteSourceControl", | ||
"location" : "https://github.com/swiftlang/swift-syntax.git", | ||
"state" : { | ||
"revision" : "0687f71944021d616d34d922343dcef086855920", | ||
"version" : "600.0.1" | ||
} | ||
} | ||
], | ||
"version" : 3 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// swift-tools-version: 6.1 | ||
// The swift-tools-version declares the minimum version of Swift required to build this package. | ||
|
||
import PackageDescription | ||
|
||
let package = Package( | ||
name: "RPi5-Blink", | ||
platforms: [ | ||
.macOS(.v14) | ||
], | ||
products: [ | ||
.library( | ||
name: "MainApp", | ||
type: .static, | ||
targets: ["MainApp"]) | ||
], | ||
dependencies: [ | ||
.package( | ||
url: "https://github.com/apple/swift-mmio.git", | ||
branch: "swift-embedded-examples") | ||
], | ||
targets: [ | ||
.target( | ||
name: "MainApp", | ||
dependencies: [ | ||
.product(name: "MMIO", package: "swift-mmio") | ||
], | ||
swiftSettings: [ | ||
.enableExperimentalFeature("Embedded"), | ||
.unsafeFlags(["-Xfrontend", "-function-sections"]), | ||
] | ||
), | ||
.target(name: "Support"), | ||
|
||
] | ||
) |
Oops, something went wrong.