Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
Signed-off-by: Mario Bălănică <[email protected]>
  • Loading branch information
mariobalanica committed Jan 3, 2024
0 parents commit 99bca15
Show file tree
Hide file tree
Showing 12 changed files with 407 additions and 0 deletions.
107 changes: 107 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
name: Build
on:
push:
paths-ignore:
- '**.md'
branches:
- master
pull_request:
paths-ignore:
- '**.md'
branches:
- master
workflow_call:
workflow_dispatch:

env:
RPI_FIRMWARE_URL: https://github.com/raspberrypi/firmware/
DTB_VERSION: 1e403e23baab5673f0494a200f57cd01287d5b1a

jobs:
build:
runs-on: ubuntu-latest
strategy:
matrix:
MODEL:
- 5
CONFIGURATION: [Debug, Release]
steps:
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive

- name: Install dependencies
shell: bash
run: |
sudo apt-get update && \
sudo apt-get install -y \
acpica-tools \
binutils-aarch64-linux-gnu \
build-essential \
device-tree-compiler \
gettext \
git \
gcc-aarch64-linux-gnu \
libc6-dev-arm64-cross \
python3 \
python3-pyelftools
- name: Get version tag
id: get_version_tag
shell: bash
run: echo "version=$(git describe --tags --always)" >> $GITHUB_OUTPUT

- name: Set up Secure Boot default keys
if: ${{ false }} # Disable for now, too large for debug builds.
run: |
mkdir keys
# We don't really need a usable PK, so just generate a public key for it and discard the private key
openssl req -new -x509 -newkey rsa:2048 -subj "/CN=Rockchip Platform Key/" -keyout /dev/null -outform DER -out keys/pk.cer -days 7300 -nodes -sha256
curl -L https://go.microsoft.com/fwlink/?LinkId=321185 -o keys/ms_kek.cer
curl -L https://go.microsoft.com/fwlink/?linkid=321192 -o keys/ms_db1.cer
curl -L https://go.microsoft.com/fwlink/?linkid=321194 -o keys/ms_db2.cer
curl -L https://uefi.org/sites/default/files/resources/dbxupdate_arm64.bin -o keys/arm64_dbx.bin
- name: Build platform
shell: bash
run: |
export EDK2_SECUREBOOT_FLAGS=""
if [ -d keys ]; then
export EDK2_SECUREBOOT_FLAGS=" \
-D DEFAULT_KEYS=TRUE \
-D PK_DEFAULT_FILE=keys/pk.cer \
-D KEK_DEFAULT_FILE1=keys/ms_kek.cer \
-D DB_DEFAULT_FILE1=keys/ms_db1.cer \
-D DB_DEFAULT_FILE2=keys/ms_db2.cer \
-D DBX_DEFAULT_FILE1=keys/arm64_dbx.bin \
-D SECURE_BOOT_ENABLE=TRUE"
fi
export EDK2_BUILD_FLAGS=" \
--pcd gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVendor=L"${{ github.repository_owner }}" \
${EDK2_SECUREBOOT_FLAGS}"
./build.sh \
--model ${{ matrix.MODEL }} \
--debug ${{ matrix.CONFIGURATION == 'Debug' && 1 || 0 }} \
--edk2-flags "${EDK2_BUILD_FLAGS}"
- name: Download Raspberry Pi support files
run: |
curl -O -L ${{ env.RPI_FIRMWARE_URL }}/raw/${{ env.DTB_VERSION }}/boot/bcm2712-rpi-5-b.dtb
- name: Create firmware archive
run: |
zip -r \
RPi${{ matrix.MODEL }}_UEFI_${{ matrix.CONFIGURATION }}_${{ steps.get_version_tag.outputs.version }}.zip \
RPI_EFI.fd \
config.txt \
*.dtb
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
name: RPi${{ matrix.MODEL }}_UEFI_${{ matrix.CONFIGURATION }}_${{ steps.get_version_tag.outputs.version }}
path: ./*.zip
if-no-files-found: error
26 changes: 26 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
name: Release
on:
push:
tags:
- '*'

jobs:
build_for_release:
uses: ./.github/workflows/build.yml

release:
runs-on: ubuntu-latest
needs: build_for_release
permissions:
contents: write
steps:
- name: Download all workflow run artifacts
uses: actions/download-artifact@v3

- name: Create release
uses: softprops/action-gh-release@v1
with:
draft: true
prerelease: false
files: "*/*Release*.zip"
fail_on_unmatched_files: true
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Build/
.DS_Store
*_extdep/
*.pyc
__pycache__/
tags/
.vscode/
*.fd
16 changes: 16 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[submodule "arm-trusted-firmware"]
path = arm-trusted-firmware
url = https://github.com/worproject/arm-trusted-firmware.git
branch = rpi5
[submodule "edk2"]
path = edk2
url = https://github.com/worproject/edk2.git
branch = sdmmc-dev
[submodule "edk2-platforms"]
path = edk2-platforms
url = https://github.com/worproject/edk2-platforms.git
branch = rpi5-dev
[submodule "edk2-non-osi"]
path = edk2-non-osi
url = https://github.com/tianocore/edk2-non-osi.git
branch = master
116 changes: 116 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Raspberry Pi 5 UEFI
This repository contains a TF-A + EDK2 UEFI firmware port for Raspberry Pi 5.

![EDK2 Setup Screen](images/edk2_setup_screen.png)

# Getting started
Check the [Supported peripherals](#supported-peripherals) and [Supported OSes](#supported-oses) sections to see what's currently possible with this firmware.

## 1. Prerequisites
* #### SD card or USB drive to store the firmware and/or operating system on

**Note:** For OS, it is highly suggested to use a quality drive with **good random I/O performance**. In SD terms this means an A1/A2-rated card.

* #### Quality power supply and cable that can provide at least 5V 3A (15 W)
Depending on the peripherals you use, more power may be needed. The recommended official power supply provides 5.1V 5A (25 W).

**Note:** Using an inadequate supply can cause all sorts of issues, from underclocking to random crashes.

* #### HDMI display

* #### Some form of cooling (fan, heatsink)
The device may thermal throttle otherwise.

Optionally, if display is not available or for debugging purposes, an UART serial adapter compatible with the special connector. Configuration is `115200 8n1`.

## 2. Download the firmware image
The latest version can be obtained from [Releases](https://github.com/worproject/rpi5-uefi/releases).

## 3. Flash the firmware
Prepare an empty boot drive by formatting the first partition as FAT32, then extract the archive downloaded above to the root of this partition.

**Note:** do not rename or delete any of the boot files.

## 4. Connect peripherals and power on the device
You should first see a QR code screen, then shortly after, a centered Raspberry Pi logo with progress bar at the bottom. This indicates that the UEFI firmware has loaded.

At this stage, you can press <kbd>Esc</kbd> to enter the firmware setup, <kbd>F1</kbd> to launch the UEFI Shell, or, provided you also have an UEFI bootloader/app on a storage device, you can let the system automatically run that, which is the default behavior if no action is taken.

Check the configuration options described below, some of which may need to be changed depending on the OS used.

# Configuration settings
The UEFI provides options that can be viewed and changed using the UI configuration menu.

Configuration through the user interface is fairly straightforward and help/navigation information is provided around the menus.

## Linux
* For maximum SD card performance, go to `Device Manager`->`Raspberry Pi Configuration`->`ACPI / Device Tree` and set `Compatibility Mode` to `Full Bay Trail`, then untick `Limit UHS-I Modes`.

**Warning:** this may affect other OSes!

* If you're getting a Synchronous Exception when booting certain distros, go to `Device Manager`->`EFI Memory Attribute Protocol` and untick `Enable Protocol`.

# Status
## Supported peripherals
Only devices relevant to the firmware are listed below.

| Device | Status | Notes |
| --- | --- | --- |
| RP1 USB | 🟢 Working | |
| RP1 Ethernet | 🔴 Not working | |
| RP1 GPIO | 🔴 Not working | |
| RP1 PWM | 🔴 Not working | Fan control |
| PCIe | 🔴 Not working | RP1 is left configured by the VPU. |
| SD | 🟢 Working | SD cards up to SDR104. eMMC support is unknown. |
| Display | 🟢 Working | HDMI, driven by the VPU firmware. |
| UART | 🟢 Working | PL011 available on the dedicated connector at 115200 8n1. |
| GPIO | 🟢 Working | GIO/AON, pin function. |
| RTC | 🟢 Working | Get/set time, wake up alarm. |
| RNG | 🔴 Not working | |
| EEPROM | 🔴 Not working | Needed for proper NVRAM. |

## Supported OSes
### In ACPI mode
ACPI support is currently under development and limited to a few devices that have existing driver bindings.

| OS | Version | Tested/supported hardware | Notes |
| --- | --- | --- | --- |
| Windows | 11 (including insider) | Display, USB, SD, SDIO | * USB may corrupt data, especially when used for booting.<br> * SD is limited to DDR50. |
| Linux | tested Ubuntu 22.04, kernel 5.15.0-75-generic | Display, USB, SD, SDIO (incl. Wi-Fi) | * SD is limited to HS by default. See [Configuration settings - Linux](#Linux).<br> * Wi-Fi may require manual firmware installation. |
| FreeBSD | 13.2 | Display, USB, SD | * SD is limited to HS. |
| NetBSD | recent daily build | Display, USB | * SD fails to communicate with the card. |
| VMware ESXi Arm Fling | 1.15 | Display, USB | * Requires compatible USB network adapter. |

## Building
This process assumes a Linux machine. On Windows, use WSL.

1. Install required packages:

For Ubuntu/Debian:
```bash
sudo apt install git gcc g++ build-essential gcc-aarch64-linux-gnu iasl python3-pyelftools uuid-dev
```
For Arch Linux:
```bash
sudo pacman -Syu
sudo pacman -S git base-devel gcc dtc aarch64-linux-gnu-binutils aarch64-linux-gnu-gcc aarch64-linux-gnu-glibc python python-pyelftools iasl --needed
```

2. Clone the repository:
```bash
git clone --recurse-submodules https://github.com/worproject/rpi5-uefi.git
cd rpi5-uefi
```

3. Build the image:
```bash
./build.sh
```
Append `--help` for more details.

If you get build errors, it is very likely that you're still missing some dependencies. The list of packages above is not complete and depending on the distro you may need to install additional ones. In most cases, looking up the error messages on the internet will point you at the right packages.

## Licenses
Most files are licensed under the default EDK2 license, [BSD-2-Clause-Patent](https://github.com/tianocore/edk2/blob/master/License.txt).

For TF-A, see: <https://github.com/ARM-software/arm-trusted-firmware/blob/master/docs/license.rst>
1 change: 1 addition & 0 deletions arm-trusted-firmware
Submodule arm-trusted-firmware added at 46fe10
112 changes: 112 additions & 0 deletions build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#!/bin/bash

#
# Default variables
#
MODEL=5
DEBUG=0
TFA_FLAGS=""
EDK2_FLAGS=""

print_usage() {
echo
echo "Build TF-A + EDK2 image for Raspberry Pi."
echo
echo "Usage: build.sh [options]"
echo
echo "Options: "
echo " --model MODEL Board family. Supported: 4, 5. Default: ${MODEL}."
echo " --debug DEBUG Build a debug version. Default: ${DEBUG}."
echo " --tfa-flags \"FLAGS\" Flags appended to TF-A build process."
echo " --edk2-flags \"FLAGS\" Flags appended to EDK2 build process."
echo " --help Show this help."
echo
exit "${1}"
}

#
# Get options
#
OPTS=$(getopt -o '' -l 'model:,debug:,tfa-flags:,edk2-flags:,help' -- "${@}") || print_usage $?
eval set -- "${OPTS}"
while true; do
case "${1}" in
--model) MODEL="${2}"; shift 2 ;;
--debug) DEBUG="${2}"; shift 2 ;;
--tfa-flags) TFA_FLAGS="${2}"; shift 2 ;;
--edk2-flags) EDK2_FLAGS="${2}"; shift 2 ;;
--help) print_usage 0; shift ;;
--) shift; break ;;
*) break;;
esac
done
if [[ -n "${@}" ]]; then
echo "Invalid additional arguments '${@}'"
print_usage 1
fi

#
# Get machine architecture
#
MACHINE_TYPE=$(uname -m)

# Fix-up possible differences in reported arch
if [ ${MACHINE_TYPE} == 'arm64' ]; then
MACHINE_TYPE='aarch64'
elif [ ${MACHINE_TYPE} == 'amd64' ]; then
MACHINE_TYPE='x86_64'
fi

if [ ${MACHINE_TYPE} != 'aarch64' ]; then
export CROSS_COMPILE="${CROSS_COMPILE:-aarch64-linux-gnu-}"
fi

#
# Build TF-A
#
pushd arm-trusted-firmware || exit

make \
PLAT=rpi${MODEL} \
PRELOADED_BL33_BASE=0x20000 \
RPI3_PRELOADED_DTB_BASE=0x1F0000 \
SUPPORT_VFP=1 \
DEBUG=${DEBUG} \
all \
${TFA_FLAGS} \
|| exit

popd || exit

#
# Build EDK2 final image
#
GIT_COMMIT="$(git describe --tags --always)" || GIT_COMMIT="unknown"

if [ ${DEBUG} == 1 ]; then
RELEASE_TYPE="DEBUG"
else
RELEASE_TYPE="RELEASE"
fi

ATF_BUILD_DIR="${PWD}/arm-trusted-firmware/build/rpi${MODEL}/${RELEASE_TYPE,,}"

export GCC_AARCH64_PREFIX="${CROSS_COMPILE}"
export WORKSPACE=${PWD}
export PACKAGES_PATH=${WORKSPACE}/edk2:${WORKSPACE}/edk2-platforms:${WORKSPACE}/edk2-non-osi

make -C ${WORKSPACE}/edk2/BaseTools || exit

source ${WORKSPACE}/edk2/edksetup.sh || exit

build \
-a AARCH64 \
-t GCC \
-b ${RELEASE_TYPE} \
-p edk2-platforms/Platform/RaspberryPi/RPi${MODEL}/RPi${MODEL}.dsc \
-D TFA_BUILD_ARTIFACTS=${ATF_BUILD_DIR} \
--pcd gEfiMdeModulePkgTokenSpaceGuid.PcdFirmwareVersionString=L"${GIT_COMMIT}" \
${EDK2_FLAGS} \
|| exit

cp ${WORKSPACE}/Build/RPi${MODEL}/${RELEASE_TYPE}_GCC/FV/RPI_EFI.fd ${PWD}
Loading

0 comments on commit 99bca15

Please sign in to comment.