Merge pull request #1240 from kernelkit/bananapi-emmc

Bananapi eMMC support
This commit is contained in:
Joachim Wiberg
2025-11-14 06:02:05 +01:00
committed by GitHub
16 changed files with 589 additions and 100 deletions
+2 -1
View File
@@ -17,7 +17,8 @@ jobs:
matrix: matrix:
defconfig: defconfig:
- aarch64_qemu_boot - aarch64_qemu_boot
- bpi_r3_boot - bpi_r3_sd_boot
- bpi_r3_emmc_boot
- cn9130_crb_boot - cn9130_crb_boot
- fireant_boot - fireant_boot
- nanopi_r2s_boot - nanopi_r2s_boot
+219 -61
View File
@@ -1,4 +1,4 @@
name: Create SD Card Images name: Create SD Card & eMMC Images
on: on:
workflow_dispatch: workflow_dispatch:
@@ -56,21 +56,33 @@ jobs:
raspberrypi-rpi64) raspberrypi-rpi64)
echo "BOOTLOADER=rpi64_boot" >> $GITHUB_ENV echo "BOOTLOADER=rpi64_boot" >> $GITHUB_ENV
echo "TARGET=aarch64" >> $GITHUB_ENV echo "TARGET=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=false" >> $GITHUB_ENV
;; ;;
bananapi-bpi-r3) bananapi-bpi-r3)
echo "BOOTLOADER=bpi_r3_boot" >> $GITHUB_ENV echo "BOOTLOADER_SD=bpi_r3_sd_boot" >> $GITHUB_ENV
echo "BOOTLOADER_EMMC=bpi_r3_emmc_boot" >> $GITHUB_ENV
echo "TARGET=aarch64" >> $GITHUB_ENV echo "TARGET=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=true" >> $GITHUB_ENV
;; ;;
friendlyarm-nanopi-r2s) friendlyarm-nanopi-r2s)
echo "BOOTLOADER=nanopi_r2s_boot" >> $GITHUB_ENV echo "BOOTLOADER=nanopi_r2s_boot" >> $GITHUB_ENV
echo "TARGET=aarch64" >> $GITHUB_ENV echo "TARGET=aarch64" >> $GITHUB_ENV
echo "BUILD_EMMC=false" >> $GITHUB_ENV
;; ;;
*) *)
echo "Error: Unknown board ${{ inputs.board }}" echo "Error: Unknown board ${{ inputs.board }}"
exit 1 exit 1
;; ;;
esac esac
echo "Using bootloader: $BOOTLOADER and target: $TARGET for board: ${{ inputs.board }}" echo "Target: $TARGET for board: ${{ inputs.board }}"
if [ "$BUILD_EMMC" = "true" ]; then
echo "Building both SD and eMMC images"
echo "SD Bootloader: $BOOTLOADER_SD"
echo "eMMC Bootloader: $BOOTLOADER_EMMC"
else
echo "Building SD image only"
echo "Bootloader: $BOOTLOADER"
fi
- name: Download bootloader artifacts - name: Download bootloader artifacts
if: ${{ !inputs.use_latest_release }} if: ${{ !inputs.use_latest_release }}
@@ -79,16 +91,41 @@ jobs:
gh run list --workflow=build-boot.yml --branch=main --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_boot_run_id gh run list --workflow=build-boot.yml --branch=main --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_boot_run_id
BOOT_RUN_ID=$(cat latest_boot_run_id) BOOT_RUN_ID=$(cat latest_boot_run_id)
gh run download ${BOOT_RUN_ID} --name artifact-${BOOTLOADER} --dir temp_bootloader/ if [ "$BUILD_EMMC" = "true" ]; then
# Download both SD and eMMC bootloaders for boards that support both
echo "Downloading SD bootloader: ${BOOTLOADER_SD}"
gh run download ${BOOT_RUN_ID} --name artifact-${BOOTLOADER_SD} --dir temp_bootloader_sd/
mkdir -p output_sd/images
cd temp_bootloader_sd/
tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
cd ../
rm -rf temp_bootloader_sd/
# Extract bootloader directly to output/images echo "Downloading eMMC bootloader: ${BOOTLOADER_EMMC}"
cd temp_bootloader/ gh run download ${BOOT_RUN_ID} --name artifact-${BOOTLOADER_EMMC} --dir temp_bootloader_emmc/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/ mkdir -p output_emmc/images
cd ../ cd temp_bootloader_emmc/
rm -rf temp_bootloader/ tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../
rm -rf temp_bootloader_emmc/
echo "Bootloader files extracted to output/images:" echo "SD bootloader files:"
ls -la output/images/ ls -la output_sd/images/
echo "eMMC bootloader files:"
ls -la output_emmc/images/
else
# Single bootloader for boards that only support SD
gh run download ${BOOT_RUN_ID} --name artifact-${BOOTLOADER} --dir temp_bootloader/
# Extract bootloader directly to output/images
cd temp_bootloader/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_bootloader/
echo "Bootloader files extracted to output/images:"
ls -la output/images/
fi
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
@@ -99,90 +136,193 @@ jobs:
gh run list --workflow=164295764 --branch=main --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_infix_run_id gh run list --workflow=164295764 --branch=main --limit=1 --status=success --json databaseId --jq '.[0].databaseId' > latest_infix_run_id
INFIX_RUN_ID=$(cat latest_infix_run_id) INFIX_RUN_ID=$(cat latest_infix_run_id)
gh run download ${INFIX_RUN_ID} --name artifact-${TARGET} --dir temp_infix/ if [ "$BUILD_EMMC" = "true" ]; then
# Copy Infix artifacts to both SD and eMMC output directories
gh run download ${INFIX_RUN_ID} --name artifact-${TARGET} --dir temp_infix/
# Extract Infix directly to output/images cd temp_infix/
cd temp_infix/ tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/ tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../ cd ../
rm -rf temp_infix/ rm -rf temp_infix/
echo "Infix files extracted to output/images:" echo "Infix files extracted to output_sd/images:"
ls -la output/images/ ls -la output_sd/images/
echo "Infix files extracted to output_emmc/images:"
ls -la output_emmc/images/
else
# Single output directory for SD-only boards
gh run download ${INFIX_RUN_ID} --name artifact-${TARGET} --dir temp_infix/
# Extract Infix directly to output/images
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_infix/
echo "Infix files extracted to output/images:"
ls -la output/images/
fi
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Download from latest releases - name: Download from latest releases
if: ${{ inputs.use_latest_release }} if: ${{ inputs.use_latest_release }}
run: | run: |
# Download latest bootloader release if [ "$BUILD_EMMC" = "true" ]; then
gh release download latest-boot --pattern "*${BOOTLOADER}*" --dir temp_bootloader/ # Download both SD and eMMC bootloaders
cd temp_bootloader/ gh release download latest-boot --pattern "*${BOOTLOADER_SD}*" --dir temp_bootloader_sd/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/ mkdir -p output_sd/images
cd ../ cd temp_bootloader_sd/
rm -rf temp_bootloader/ tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
cd ../
rm -rf temp_bootloader_sd/
# Download latest Infix release gh release download latest-boot --pattern "*${BOOTLOADER_EMMC}*" --dir temp_bootloader_emmc/
gh release download latest --pattern "*${TARGET}*" --dir temp_infix/ mkdir -p output_emmc/images
cd temp_infix/ cd temp_bootloader_emmc/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/ tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../ cd ../
rm -rf temp_infix/ rm -rf temp_bootloader_emmc/
echo "All files extracted to output/images:" # Download Infix once and extract to both directories
ls -la output/images/ gh release download latest --pattern "*${TARGET}*" --dir temp_infix/
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output_sd/images/
tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
cd ../
rm -rf temp_infix/
echo "SD files extracted to output_sd/images:"
ls -la output_sd/images/
echo "eMMC files extracted to output_emmc/images:"
ls -la output_emmc/images/
else
# Download latest bootloader release
gh release download latest-boot --pattern "*${BOOTLOADER}*" --dir temp_bootloader/
cd temp_bootloader/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_bootloader/
# Download latest Infix release
gh release download latest --pattern "*${TARGET}*" --dir temp_infix/
cd temp_infix/
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
cd ../
rm -rf temp_infix/
echo "All files extracted to output/images:"
ls -la output/images/
fi
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Verify extracted files - name: Verify extracted files
run: | run: |
echo "Files available for mkimage.sh:" if [ "$BUILD_EMMC" = "true" ]; then
ls -la output/images/ echo "Files available for SD image:"
echo "" ls -la output_sd/images/
echo "File types:" echo ""
file output/images/* || true echo "Files available for eMMC image:"
ls -la output_emmc/images/
else
echo "Files available for mkimage.sh:"
ls -la output/images/
echo ""
echo "File types:"
file output/images/* || true
fi
- name: Create SD card image - name: Create SD card image
run: | run: |
export BINARIES_DIR=$PWD/output/images if [ "$BUILD_EMMC" = "true" ]; then
export BINARIES_DIR=$PWD/output_sd/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"
./utils/mkimage.sh -t sdcard ${{ inputs.board }}
else
export BINARIES_DIR=$PWD/output/images
export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE=""
export INFIX_ID="infix"
./utils/mkimage.sh ${{ inputs.board }}
fi
- name: Create eMMC image
if: ${{ env.BUILD_EMMC == 'true' }}
run: |
export BINARIES_DIR=$PWD/output_emmc/images
export BUILD_DIR=$PWD/build export BUILD_DIR=$PWD/build
export BR2_EXTERNAL_INFIX_PATH=$PWD export BR2_EXTERNAL_INFIX_PATH=$PWD
export RELEASE="" export RELEASE=""
export INFIX_ID="infix" export INFIX_ID="infix"
./utils/mkimage.sh ${{ inputs.board }} ./utils/mkimage.sh -t emmc ${{ inputs.board }}
- name: Verify created image - name: Verify created images
run: | run: |
echo "Contents of output/images after mkimage.sh:" if [ "$BUILD_EMMC" = "true" ]; then
ls -lh output/images/ echo "SD card image:"
ls -lh output_sd/images/*-sdcard.img* 2>/dev/null || true
if ls output_sd/images/*-sdcard.img 1> /dev/null 2>&1; then
for img in output_sd/images/*-sdcard.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null | head -20
done
fi
# Look for SD card image with pattern: *-sdcard.img echo ""
if ls output/images/*-sdcard.img 1> /dev/null 2>&1; then echo "eMMC image:"
echo "Found SD card image(s):" ls -lh output_emmc/images/*-emmc.img* 2>/dev/null || true
for img in output/images/*-sdcard.img; do if ls output_emmc/images/*-emmc.img 1> /dev/null 2>&1; then
echo "- $(basename $img)" for img in output_emmc/images/*-emmc.img; do
file "$img" echo "- $(basename $img)"
fdisk -l "$img" 2>/dev/null || true file "$img"
done fdisk -l "$img" 2>/dev/null | head -20
done
fi
# Copy both images to output/images for artifact upload
mkdir -p output/images
cp output_sd/images/*-sdcard.img* output/images/ 2>/dev/null || true
cp output_emmc/images/*-emmc.img* output/images/ 2>/dev/null || true
else else
echo "No SD card image found matching pattern: *-sdcard.img" echo "Contents of output/images after mkimage.sh:"
echo "Available files:" ls -lh output/images/
ls -la output/images/
exit 1 # Look for SD card image with pattern: *-sdcard.img
if ls output/images/*-sdcard.img 1> /dev/null 2>&1; then
echo "Found SD card image(s):"
for img in output/images/*-sdcard.img; do
echo "- $(basename $img)"
file "$img"
fdisk -l "$img" 2>/dev/null || true
done
else
echo "No SD card image found matching pattern: *-sdcard.img"
echo "Available files:"
ls -la output/images/
exit 1
fi
fi fi
- name: Upload SD card image - name: Upload images as artifacts
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: sdcard-image-${{ inputs.board }}-${{ env.BOOTLOADER }} name: images-${{ inputs.board }}
path: | path: |
output/images/*-sdcard.img* output/images/*-sdcard.img*
output/images/*-emmc.img*
retention-days: 30 retention-days: 30
- name: Create checksums - name: Create checksums
run: | run: |
cd output/images/ cd output/images/
for file in *-sdcard.img; do for file in *-sdcard.img *-emmc.img; do
if [ -f "$file" ]; then if [ -f "$file" ]; then
sha256sum "$file" > "$file.sha256" sha256sum "$file" > "$file.sha256"
fi fi
@@ -198,11 +338,28 @@ jobs:
prerelease: true prerelease: true
tag: "latest-boot" tag: "latest-boot"
token: ${{ secrets.GITHUB_TOKEN }} token: ${{ secrets.GITHUB_TOKEN }}
artifacts: "output/images/*-sdcard.img*" artifacts: "output/images/*-sdcard.img*,output/images/*-emmc.img*"
- name: Generate summary - name: Generate summary
run: | run: |
cat <<EOF >> $GITHUB_STEP_SUMMARY if [ "$BUILD_EMMC" = "true" ]; then
cat <<EOF >> $GITHUB_STEP_SUMMARY
# SD Card & eMMC Image Build Complete! 🚀
**Board:** ${{ inputs.board }}
**Target:** ${{ env.TARGET }}
**SD Bootloader:** ${{ env.BOOTLOADER_SD }}
**eMMC Bootloader:** ${{ env.BOOTLOADER_EMMC }}
**Artifact Source:** ${{ inputs.use_latest_release && 'Latest Release' || 'Latest Workflow Run' }}
## Created Images
$(find output/images/ -name "*.img" -o -name "*.img.bmap" | xargs ls -lh 2>/dev/null | awk '{print "- " $9 " (" $5 ")"}' || echo "- No images found")
## Download
Both SD card and eMMC images are available as workflow artifacts above and in the latest-boot release.
EOF
else
cat <<EOF >> $GITHUB_STEP_SUMMARY
# SD Card Image Build Complete! 🚀 # SD Card Image Build Complete! 🚀
**Board:** ${{ inputs.board }} **Board:** ${{ inputs.board }}
@@ -211,8 +368,9 @@ jobs:
**Artifact Source:** ${{ inputs.use_latest_release && 'Latest Release' || 'Latest Workflow Run' }} **Artifact Source:** ${{ inputs.use_latest_release && 'Latest Release' || 'Latest Workflow Run' }}
## Created Images ## Created Images
$(find output/images/ -name "*.img*" -o -name "*.qcow2" -o -name "*.raw" | xargs ls -lh 2>/dev/null | sed 's/^/- /' || echo "- No images found") $(find output/images/ -name "*.img" -o -name "*.img.bmap" | xargs ls -lh 2>/dev/null | awk '{print "- " $9 " (" $5 ")"}' || echo "- No images found")
## Download ## Download
The SD card image is available as a workflow artifact above. The SD card image is available as a workflow artifact above.
EOF EOF
fi
+225 -22
View File
@@ -1,27 +1,230 @@
# Banana Pi R3 # Banana Pi BPI-R3
## Support level <img src="bananapi-bpi-r3.webp" alt="The board" width=800 padding=10>
Full support for all Infix enabled features including switched ethernet ports, WiFi,
and SFP interfaces. The board includes comprehensive hardware support for
MediaTek MT7986 SoC features.
### Hardware features ## Overview
The Banana Pi R3 is a high-performance networking board featuring:
- MediaTek MT7986 ARM Cortex-A53 quad-core processor
- 4x Gigabit LAN ports (lan1-lan4)
- 1x Gigabit WAN port
- 2x SFP ports (sfp1, sfp2) for fiber connectivity
- Dual WiFi interfaces (wifi0 for 2.4GHz, wifi1 for 5GHz)
- USB support
- SD card boot support
### Network configuration The Banana Pi R3 is a high-performance networking board with full Infix
The board comes preconfigured with: support for all enabled features including switched Ethernet ports, WiFi,
- 4 switched LAN ports for internal networking and SFP interfaces.
- Dedicated WAN port with DHCP client enabled
- SFP ports for high-speed fiber connections
- Dual WiFi interfaces for wireless connectivity
### Pre-built images ### Hardware Features
SD card image: [infix-bpi-r3-sdcard.img](https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r3-sdcard.img)
- MediaTek MT7986 ARM Cortex-A53 quad-core processor @ 2.0 GHz
- 2 GB DDR4 RAM
- 8 GB eMMC storage + microSD card slot
- 5x Gigabit Ethernet ports (4x LAN, 1x WAN)
- 2x SFP cages for fiber connectivity (1G/2.5G)
- Dual-band WiFi (2.4 GHz + 5 GHz)
- USB 3.0 port
- Mini PCIe slot
### Default Network Configuration
Infix comes preconfigured with:
- **LAN ports** (lan1-lan4): Bridged for internal networking
- **WAN port**: DHCP client enabled for internet connectivity
- **SFP ports** (sfp1, sfp2): Available for configuration
- **WiFi interfaces** (wifi0, wifi1): Available for configuration
## Getting Started
### Quick Start with SD Card
The easiest way to get started is using an SD card:
1. **Download the SD card image:** [infix-bpi-r3-sdcard.img][2]
2. **Flash the image to an SD card:** see [this guide][0]
3. **Set boot switches:**
- Set DIP switches to **0000** (SD card boot mode)
- Switch positions are on the underside of the board near the SD slot
4. **Boot the board:**
- Insert the SD card
- Connect power
- Connect to LAN port or console (115200 8N1)
- Default login: `admin` / `admin`
### Boot Switch Reference
The BPI-R3 has a 4-position DIP switch that controls boot media:
<img align="right" src="bootstrap-switch.webp" alt="DIP switches" width=200 padding=10>
| Position | Mode | Description |
|----------|-------------|---------------------------------------|
| 0000 | SD card | Boot from microSD card (recommended) |
| 0110 | eMMC | Boot from internal eMMC storage |
| 0101 | SPI NAND | Boot from SPI NAND (advanced users) |
> [!NOTE]
> Switch position is read from left to right: "0" = OFF, "1" = ON.
> When the DIP switch is in the "UP" position it is OFF(0).
## Advanced: Installing to eMMC
For production deployments or better performance, you can install Infix
to the internal eMMC storage. This is more complex but provides faster
boot times and eliminates the external SD card.
### Why Use eMMC?
**Advantages:**
- Faster boot and better performance
- No external SD card to manage
- More robust for industrial/embedded deployments
**Disadvantages:**
- More complex installation process
- Requires intermediate NAND boot step
- Harder to recover from errors
### Prerequisites
- FTDI USB-to-serial cable (3.3V) for console access
- microSD card with Infix (for initial boot)
- USB flash drive (FAT32 formatted)
- Downloaded files (see below)
### Required Files
Download and place these files on a FAT32-formatted USB drive:
1. **Intermediate NAND bootloader** (from Frank-W's U-Boot):
- [bpi-r3_spim-nand_bl2.img][5] (BL2 loader)
- [bpi-r3_spim-nand_fip.bin][6] (FIP image)
2. **Infix eMMC image:**
- [infix-bpi-r3-emmc.img][3] (Complete system image)
3. **eMMC bootloader** (extracted from):
- [bpi-r3-emmc-boot-2025.01-latest.tar.gz][4]
- Extract `bl2.img` from the tarball to your USB drive
> [!WARNING]
> The following process involves multiple boot mode changes. Take your
> time verify each step carefully.
### Installation Steps
#### Step 1: Boot from SD card
1. Set boot switches to **0000** (SD card mode)
2. Insert SD card with Infix
3. Power on and break into U-Boot (press Ctrl-C during boot)
#### Step 2: Flash intermediate NAND bootloader
This step installs a temporary bootloader to NAND that will help us
flash the eMMC. From the U-Boot prompt:
```
usb start
mtd erase spi-nand0
fatload usb 0:1 0x50000000 bpi-r3_spim-nand_bl2.img
mtd write spi-nand0 0x50000000 0x0 0x100000
fatload usb 0:1 0x50000000 bpi-r3_spim-nand_fip.bin
mtd write spi-nand0 0x50000000 0x380000 0x200000
```
#### Step 3: Boot from NAND
1. Power off the board
2. Set boot switches to **0101** (NAND mode)
3. Power on - you should boot into U-Boot again
#### Step 4: Write Infix image to eMMC
From the U-Boot prompt:
```
usb start
fatload usb 0:1 0x50000000 infix-bpi-r3-emmc.img
setexpr blocks ${filesize} / 0x200
mmc write 0x50000000 0x0 ${blocks}
```
This writes the complete Infix system (partitions, rootfs, etc.) to eMMC.
#### Step 5: Configure eMMC boot
Now configure the eMMC boot partition and write the bootloader:
```
mmc partconf 0 1 1 1
mmc erase 0x0 0x400
fatload usb 0:1 0x50000000 bl2.img
mmc write 0x50000000 0x0 0x400
mmc partconf 0 1 1 0
mmc bootbus 0 0 0 0
```
#### Step 6: Boot from eMMC
1. Power off the board
2. Set boot switches to **0110** (eMMC mode)
3. Remove SD card (optional, but recommended to verify eMMC boot)
4. Power on
Your BPI-R3 should now boot Infix from internal eMMC storage!
## Troubleshooting
### Board won't boot
- Verify boot switch positions (check twice!)
- Ensure power supply provides adequate current (12V/2A recommended)
- Try booting from SD card with switches at **0000**
### Can't break into U-Boot
- Ensure serial console is connected properly (115200 8N1, 3.3V)
- Press Ctrl-C immediately when you see boot messages
- Try power cycling and pressing Ctrl-C repeatedly
### eMMC boot fails after installation
- Boot from NAND (**0101**) and verify eMMC image was written
- Check USB drive contents - ensure all files are present
- Re-run Step 5 (eMMC boot configuration)
### Reverting to SD card
Simply set boot switches back to **0000** and boot from SD card. The
eMMC installation does not affect SD card functionality.
## Additional Resources
- [Infix Documentation][1]
- [Official BPI-R3 Wiki][7]
- [Release Downloads][8]
## Building Custom Images
See the main Infix documentation for building from source. To build both
SD card and eMMC images locally:
```bash
# Build bootloaders for both SD and eMMC
make x-bpi-r3-sd-boot
make x-bpi-r3-emmc-boot
# Build main system
make aarch64
# Create SD card image
./utils/mkimage.sh -od bananapi-bpi-r3
# Create eMMC image
./utils/mkimage.sh -odt emmc bananapi-bpi-r3
```
[0]: https://kernelkit.org/posts/flashing-sdcard/
[1]: https://kernelkit.org/infix/latest/
[2]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r3-sdcard.img
[3]: https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r3-emmc.img
[4]: https://github.com/kernelkit/infix/releases/download/latest-boot/bpi-r3-emmc-boot-2025.01-latest.tar.gz
[5]: https://github.com/frank-w/u-boot/releases/download/CI-BUILD-2025-10-bpi-2025.10-2025-10-13_1032/bpi-r3_spim-nand_bl2.img
[6]: https://github.com/frank-w/u-boot/releases/download/CI-BUILD-2025-10-bpi-2025.10-2025-10-13_1032/bpi-r3_spim-nand_fip.bin
[7]: https://wiki.banana-pi.org/Banana_Pi_BPI-R3
[8]: https://github.com/kernelkit/infix/releases/tag/latest-boot
Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

+1 -1
View File
@@ -1 +1 @@
dtb-y += mediatek/mt7986a-bananapi-bpi-r3-sd.dtb dtb-y += mediatek/mt7986a-bananapi-bpi-r3-sd.dtb mediatek/mt7986a-bananapi-bpi-r3-emmc.dtb
@@ -0,0 +1,2 @@
#include "mt7986a-bananapi-bpi-r3.dtsi"
#include "mt7986a-bananapi-bpi-r3-emmc.dtsi"
@@ -0,0 +1,22 @@
// SPDX-License-Identifier: (GPL-2.0 OR MIT)
/*
* Copyright (C) 2021 MediaTek Inc.
* Author: Sam.Shih <sam.shih@mediatek.com>
*/
/*
This is copied from linux where it is an overlay, unfortunatly it is not
possible to use dtbo in sysboot unless present in syslinux.conf
*/
&{/soc/mmc@11230000} {
bus-width = <8>;
max-frequency = <200000000>;
cap-mmc-highspeed;
mmc-hs200-1_8v;
mmc-hs400-1_8v;
hs400-ds-delay = <0x14014>;
non-removable;
no-sd;
no-sdio;
status = "okay";
};
@@ -24,7 +24,7 @@ image var.ext4 {
} }
} }
image #INFIX_ID##VERSION#-bpi-r3-sdcard.img { image #INFIX_ID##VERSION#-bpi-r3-#TARGET#.img {
hdimage { hdimage {
partition-table-type = "gpt" partition-table-type = "gpt"
@@ -0,0 +1,2 @@
CONFIG_DEVICE_TREE_INCLUDES="infix-env.dtsi infix-key.dtsi mt7986-emmc-env.dtsi"
BR2_TARGET_ARM_TRUSTED_FIRMWARE_ADDITIONAL_VARIABLES="BOOT_DEVICE=emmc DRAM_USE_DDR4=1 USE_MKIMAGE=1 MKIMAGE=$(HOST_DIR)/bin/mkimage"
@@ -7,6 +7,27 @@ CONFIG_USB=y
CONFIG_USB_XHCI_HCD=y CONFIG_USB_XHCI_HCD=y
CONFIG_USB_XHCI_MTK=y CONFIG_USB_XHCI_MTK=y
CONFIG_USB_MTU3=y CONFIG_USB_MTU3=y
CONFIG_CMD_USB=y
CONFIG_PHY=y CONFIG_PHY=y
CONFIG_PHY_MTK_TPHY=y CONFIG_PHY_MTK_TPHY=y
CONFIG_MTK_SPIM=y
CONFIG_SPI=y
CONFIG_DM_SPI=y
CONFIG_SPI_FLASH=y
CONFIG_DM_SPI_FLASH=y
CONFIG_SPI_FLASH_MTD=y
CONFIG_SPI_FLASH_MACRONIX=y
CONFIG_SPI_FLASH_WINBOND=y
CONFIG_SPI_FLASH_GIGADEVICE=y
CONFIG_MTD=y
CONFIG_DM_MTD=y
CONFIG_MTD_PARTITIONS=y
CONFIG_MTD_SPI_NAND=y
CONFIG_MTK_SPIM=y
CONFIG_MTK_SNOR=y
CONFIG_CMD_SF=y
CONFIG_CMD_USB=y
CONFIG_CMD_MTD=y
CONFIG_CMD_MTDPARTS=y
CONFIG_CMD_DM=y
@@ -0,0 +1,5 @@
#include <mt7986-env.dtsi>
&env {
fdtfile = "mediatek/mt7986a-bananapi-bpi-r3-emmc.dtb";
};
+44
View File
@@ -0,0 +1,44 @@
BR2_aarch64=y
BR2_TOOLCHAIN_EXTERNAL=y
BR2_TOOLCHAIN_EXTERNAL_BOOTLIN=y
BR2_DL_DIR="$(BR2_EXTERNAL_INFIX_PATH)/dl"
BR2_CCACHE=y
BR2_CCACHE_DIR="$(BR2_EXTERNAL_INFIX_PATH)/.ccache"
BR2_ENABLE_DEBUG=y
BR2_PACKAGE_OVERRIDE_FILE="$(BR2_EXTERNAL_INFIX_PATH)/local.mk"
BR2_GLOBAL_PATCH_DIR="$(BR2_EXTERNAL_INFIX_PATH)/patches"
BR2_SSP_NONE=y
BR2_INIT_NONE=y
BR2_SYSTEM_BIN_SH_NONE=y
# BR2_PACKAGE_BUSYBOX is not set
# BR2_PACKAGE_IFUPDOWN_SCRIPTS is not set
# BR2_TARGET_ROOTFS_TAR is not set
BR2_TARGET_ARM_TRUSTED_FIRMWARE=y
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_GIT=y
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_URL="https://github.com/mtk-openwrt/arm-trusted-firmware-mtk.git"
BR2_TARGET_ARM_TRUSTED_FIRMWARE_CUSTOM_REPO_VERSION="78a0dfd927bb00ce973a1f8eb4079df0f755887a"
BR2_TARGET_ARM_TRUSTED_FIRMWARE_PLATFORM="mt7986"
BR2_TARGET_ARM_TRUSTED_FIRMWARE_FIP=y
BR2_TARGET_ARM_TRUSTED_FIRMWARE_UBOOT_AS_BL33=y
BR2_TARGET_ARM_TRUSTED_FIRMWARE_ADDITIONAL_VARIABLES="BOOT_DEVICE=emmc DRAM_USE_DDR4=1 USE_MKIMAGE=1 MKIMAGE=$(HOST_DIR)/bin/mkimage"
BR2_TARGET_ARM_TRUSTED_FIRMWARE_IMAGES="*.img *.bin"
BR2_TARGET_UBOOT=y
BR2_TARGET_UBOOT_BUILD_SYSTEM_KCONFIG=y
BR2_TARGET_UBOOT_CUSTOM_VERSION=y
BR2_TARGET_UBOOT_CUSTOM_VERSION_VALUE="2025.01"
BR2_TARGET_UBOOT_BOARD_DEFCONFIG="mt7986a_bpir3_emmc"
BR2_TARGET_UBOOT_CONFIG_FRAGMENT_FILES="${BR2_EXTERNAL_INFIX_PATH}/board/common/uboot/extras.config ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/bananapi-bpi-r3/uboot/extras.config ${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/bananapi-bpi-r3/uboot/emmc-extras.config"
BR2_TARGET_UBOOT_NEEDS_DTC=y
BR2_TARGET_UBOOT_FORMAT_DTB=y
BR2_TARGET_UBOOT_CUSTOM_DTS_PATH="${BR2_EXTERNAL_INFIX_PATH}/board/aarch64/bananapi-bpi-r3/uboot/*.dtsi"
BR2_PACKAGE_HOST_BMAP_TOOLS=y
BR2_PACKAGE_HOST_GENIMAGE=y
BR2_PACKAGE_HOST_RAUC=y
BR2_PACKAGE_HOST_UBOOT_TOOLS=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SUPPORT=y
BR2_PACKAGE_HOST_UBOOT_TOOLS_FIT_SIGNATURE_SUPPORT=y
TRUSTED_KEYS=y
TRUSTED_KEYS_DEVELOPMENT=y
DISK_IMAGE_BOOT_BIN=y
DISK_IMAGE_BOOT_DATA="${BINARIES_DIR}/flash-image.bin"
DISK_IMAGE_BOOT_OFFSET=0x00200000
+2
View File
@@ -37,6 +37,7 @@ All notable changes to the project are documented in this file.
VXLAN tunnels. This also changes the default TTL of tunnels to 64, from the VXLAN tunnels. This also changes the default TTL of tunnels to 64, from the
kernel default (*inherit*), which in turn fixes reported issues with dropped kernel default (*inherit*), which in turn fixes reported issues with dropped
OSPF Hello frames in GRE tunnels OSPF Hello frames in GRE tunnels
- [Document][bpi-r3-emmc-documentation] how to go from SD card to eMMC on bpi-r3
### Fixes ### Fixes
@@ -48,6 +49,7 @@ All notable changes to the project are documented in this file.
boot step "Mounting filesystems ..." with up to 30 seconds! boot step "Mounting filesystems ..." with up to 30 seconds!
[lastest-boot]: https://github.com/kernelkit/infix/releases/latest-boot [lastest-boot]: https://github.com/kernelkit/infix/releases/latest-boot
[bpi-r3-emmc-documentation]: https://github.com/kernelkit/infix/blob/main/board/aarch64/bananapi-bpi-r3/README.md
[v25.10.0][] - 2025-10-31 [v25.10.0][] - 2025-10-31
------------------------- -------------------------
+42 -13
View File
@@ -25,6 +25,7 @@ Options:
-l List available boards -l List available boards
-o Override auto-detection of genimage.sh, use host installed version -o Override auto-detection of genimage.sh, use host installed version
-r root-dir Path to rootfs build directory or rootfs.squashfs file (default: O= or output/) -r root-dir Path to rootfs build directory or rootfs.squashfs file (default: O= or output/)
-t target Image target type: sdcard or emmc (default: sdcard)
Arguments: Arguments:
board-name Board identifier (must come after options) board-name Board identifier (must come after options)
@@ -37,7 +38,7 @@ Description:
from separate boot and rootfs sources. Useful for CI or manual image creation. from separate boot and rootfs sources. Useful for CI or manual image creation.
Output: Output:
SD card image saved to \$BINARIES_DIR/*-sdcard.img Image saved to \$BINARIES_DIR/*-sdcard.img or *-emmc.img
Examples: Examples:
# From Buildroot build: # From Buildroot build:
@@ -52,6 +53,9 @@ Examples:
# Download bootloader and compose with Linux image in output directory: # Download bootloader and compose with Linux image in output directory:
$0 -od bananapi-bpi-r3 $0 -od bananapi-bpi-r3
# Create eMMC image instead of SD card:
$0 -t emmc bananapi-bpi-r3
EOF EOF
} }
@@ -107,7 +111,7 @@ run_genimage()
--config "$genimage_cfg" --config "$genimage_cfg"
if command -v bmaptool >/dev/null 2>&1; then if command -v bmaptool >/dev/null 2>&1; then
for img in "${BINARIES_DIR}"/*-sdcard.img; do for img in "${BINARIES_DIR}"/*-sdcard.img "${BINARIES_DIR}"/*-emmc.img; do
[ -f "$img" ] || continue [ -f "$img" ] || continue
log "Generating block map for $(basename "$img")..." log "Generating block map for $(basename "$img")..."
bmaptool create -o "${img}.bmap" "$img" bmaptool create -o "${img}.bmap" "$img"
@@ -163,12 +167,17 @@ find_build_dir()
get_bootloader_name() get_bootloader_name()
{ {
board="$1" board="$1"
target="$2"
case "$board" in case "$board" in
raspberrypi-rpi64) raspberrypi-rpi64)
echo "rpi64_boot" echo "rpi64_boot"
;; ;;
bananapi-bpi-r3) bananapi-bpi-r3)
echo "bpi_r3_boot" if [ "$target" = "emmc" ]; then
echo "bpi_r3_emmc_boot"
else
echo "bpi_r3_sd_boot"
fi
;; ;;
friendlyarm-nanopi-r2s) friendlyarm-nanopi-r2s)
echo "nanopi_r2s_boot" echo "nanopi_r2s_boot"
@@ -187,8 +196,9 @@ download_bootloader()
{ {
board="$1" board="$1"
build_dir="$2" build_dir="$2"
target="$3"
bootloader=$(get_bootloader_name "$board") || return 1 bootloader=$(get_bootloader_name "$board" "$target") || return 1
if ! command -v gh >/dev/null 2>&1; then if ! command -v gh >/dev/null 2>&1; then
die "gh CLI not found. Install it or build bootloader locally." die "gh CLI not found. Install it or build bootloader locally."
@@ -271,7 +281,7 @@ discover_rpi_boot_files()
echo "$files" echo "$files"
} }
while getopts "hldfob:r:" opt; do while getopts "hldfob:r:t:" opt; do
case $opt in case $opt in
b) b)
BOOT_DIR="$OPTARG" BOOT_DIR="$OPTARG"
@@ -299,6 +309,9 @@ while getopts "hldfob:r:" opt; do
ROOT_DIR="$OPTARG" ROOT_DIR="$OPTARG"
STANDALONE=1 STANDALONE=1
;; ;;
t)
TARGET="$OPTARG"
;;
*) *)
usage usage
exit 1 exit 1
@@ -312,6 +325,22 @@ if ! validate_board "$1"; then
exit 1 exit 1
fi fi
# Validate and set default target
: "${TARGET:=sdcard}"
case "$TARGET" in
sd|sdcard)
TARGET="sdcard"
;;
emmc)
TARGET="emmc"
;;
*)
err "Invalid target: $TARGET. Must be 'sdcard' or 'emmc'"
usage
exit 1
;;
esac
# Standalone mode: set up environment from build directories # Standalone mode: set up environment from build directories
if [ -n "$STANDALONE" ]; then if [ -n "$STANDALONE" ]; then
# In download mode without explicit dirs, default to same location for both # In download mode without explicit dirs, default to same location for both
@@ -404,7 +433,7 @@ if [ -n "$DOWNLOAD_BOOT" ]; then
# Save original output location # Save original output location
ORIGINAL_BINARIES_DIR="$BINARIES_DIR" ORIGINAL_BINARIES_DIR="$BINARIES_DIR"
download_bootloader "$BOARD" "$BUILD_DIR" download_bootloader "$BOARD" "$BUILD_DIR" "$TARGET"
# Now use the temporary directory for composition # Now use the temporary directory for composition
BINARIES_DIR="$SDCARD_TEMP_DIR" BINARIES_DIR="$SDCARD_TEMP_DIR"
@@ -458,7 +487,7 @@ fi
# Epxand template variables # Epxand template variables
sed "s|#VERSION#|${RELEASE}|" "$GENIMAGE_TEMPLATE" | \ sed "s|#VERSION#|${RELEASE}|" "$GENIMAGE_TEMPLATE" | \
sed "s|#INFIX_ID#|${INFIX_ID}|" | \ sed "s|#INFIX_ID#|${INFIX_ID}|" | \
sed "s|#TARGET#|sd|" > "$GENIMAGE_CFG" sed "s|#TARGET#|${TARGET}|" > "$GENIMAGE_CFG"
# Clean up temp file if created # Clean up temp file if created
rm -f "${GENIMAGE_CFG}.tmp" rm -f "${GENIMAGE_CFG}.tmp"
@@ -479,19 +508,19 @@ else
fi fi
if [ -z "$OVERRIDE" ] && command -v "$GENIMAGE_WRAPPER" >/dev/null 2>&1; then if [ -z "$OVERRIDE" ] && command -v "$GENIMAGE_WRAPPER" >/dev/null 2>&1; then
log "Creating SD card image using Buildroot $(basename "$GENIMAGE_WRAPPER") ..." log "Creating $TARGET image using Buildroot $(basename "$GENIMAGE_WRAPPER") ..."
"$GENIMAGE_WRAPPER" -c "$GENIMAGE_CFG" "$GENIMAGE_WRAPPER" -c "$GENIMAGE_CFG"
else else
log "Creating SD card image ..." log "Creating $TARGET image ..."
run_genimage "$GENIMAGE_CFG" run_genimage "$GENIMAGE_CFG"
fi fi
# Post-processing: move images and cleanup if using download mode # Post-processing: move images and cleanup if using download mode
if [ -n "$DOWNLOAD_BOOT" ]; then if [ -n "$DOWNLOAD_BOOT" ]; then
log "Moving SD card images to $ORIGINAL_BINARIES_DIR..." log "Moving $TARGET images to $ORIGINAL_BINARIES_DIR..."
mkdir -p "$ORIGINAL_BINARIES_DIR" mkdir -p "$ORIGINAL_BINARIES_DIR"
for img in "${BINARIES_DIR}"/*-sdcard.img*; do for img in "${BINARIES_DIR}"/*-sdcard.img* "${BINARIES_DIR}"/*-emmc.img*; do
if [ -f "$img" ]; then if [ -f "$img" ]; then
mv "$img" "$ORIGINAL_BINARIES_DIR/" mv "$img" "$ORIGINAL_BINARIES_DIR/"
log " $(basename "$img")" log " $(basename "$img")"
@@ -505,8 +534,8 @@ if [ -n "$DOWNLOAD_BOOT" ]; then
BINARIES_DIR="$ORIGINAL_BINARIES_DIR" BINARIES_DIR="$ORIGINAL_BINARIES_DIR"
fi fi
log "SD card image created successfully:" log "$TARGET image created successfully:"
for img in "${BINARIES_DIR}"/*-sdcard.img*; do for img in "${BINARIES_DIR}"/*-sdcard.img* "${BINARIES_DIR}"/*-emmc.img*; do
if [ -f "$img" ]; then if [ -f "$img" ]; then
if [ -n "$STANDALONE" ]; then if [ -n "$STANDALONE" ]; then
# Show relative path in standalone mode # Show relative path in standalone mode