mirror of
https://github.com/kernelkit/infix.git
synced 2026-07-22 17:23:00 +02:00
Merge pull request #1240 from kernelkit/bananapi-emmc
Bananapi eMMC support
This commit is contained in:
@@ -17,7 +17,8 @@ jobs:
|
||||
matrix:
|
||||
defconfig:
|
||||
- aarch64_qemu_boot
|
||||
- bpi_r3_boot
|
||||
- bpi_r3_sd_boot
|
||||
- bpi_r3_emmc_boot
|
||||
- cn9130_crb_boot
|
||||
- fireant_boot
|
||||
- nanopi_r2s_boot
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
name: Create SD Card Images
|
||||
name: Create SD Card & eMMC Images
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
@@ -56,21 +56,33 @@ jobs:
|
||||
raspberrypi-rpi64)
|
||||
echo "BOOTLOADER=rpi64_boot" >> $GITHUB_ENV
|
||||
echo "TARGET=aarch64" >> $GITHUB_ENV
|
||||
echo "BUILD_EMMC=false" >> $GITHUB_ENV
|
||||
;;
|
||||
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 "BUILD_EMMC=true" >> $GITHUB_ENV
|
||||
;;
|
||||
friendlyarm-nanopi-r2s)
|
||||
echo "BOOTLOADER=nanopi_r2s_boot" >> $GITHUB_ENV
|
||||
echo "TARGET=aarch64" >> $GITHUB_ENV
|
||||
echo "BUILD_EMMC=false" >> $GITHUB_ENV
|
||||
;;
|
||||
*)
|
||||
echo "Error: Unknown board ${{ inputs.board }}"
|
||||
exit 1
|
||||
;;
|
||||
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
|
||||
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
|
||||
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
|
||||
cd temp_bootloader/
|
||||
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
|
||||
cd ../
|
||||
rm -rf temp_bootloader/
|
||||
echo "Downloading eMMC bootloader: ${BOOTLOADER_EMMC}"
|
||||
gh run download ${BOOT_RUN_ID} --name artifact-${BOOTLOADER_EMMC} --dir temp_bootloader_emmc/
|
||||
mkdir -p output_emmc/images
|
||||
cd temp_bootloader_emmc/
|
||||
tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
|
||||
cd ../
|
||||
rm -rf temp_bootloader_emmc/
|
||||
|
||||
echo "Bootloader files extracted to output/images:"
|
||||
ls -la output/images/
|
||||
echo "SD bootloader files:"
|
||||
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:
|
||||
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
|
||||
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/
|
||||
tar -xzf *.tar.gz --strip-components=1 -C ../output/images/
|
||||
cd ../
|
||||
rm -rf 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 "Infix files extracted to output/images:"
|
||||
ls -la output/images/
|
||||
echo "Infix files extracted to output_sd/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:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Download from latest releases
|
||||
if: ${{ inputs.use_latest_release }}
|
||||
run: |
|
||||
# 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/
|
||||
if [ "$BUILD_EMMC" = "true" ]; then
|
||||
# Download both SD and eMMC bootloaders
|
||||
gh release download latest-boot --pattern "*${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/
|
||||
|
||||
# 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/
|
||||
gh release download latest-boot --pattern "*${BOOTLOADER_EMMC}*" --dir temp_bootloader_emmc/
|
||||
mkdir -p output_emmc/images
|
||||
cd temp_bootloader_emmc/
|
||||
tar -xzf *.tar.gz --strip-components=1 -C ../output_emmc/images/
|
||||
cd ../
|
||||
rm -rf temp_bootloader_emmc/
|
||||
|
||||
echo "All files extracted to output/images:"
|
||||
ls -la output/images/
|
||||
# Download Infix once and extract to both directories
|
||||
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:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Verify extracted files
|
||||
run: |
|
||||
echo "Files available for mkimage.sh:"
|
||||
ls -la output/images/
|
||||
echo ""
|
||||
echo "File types:"
|
||||
file output/images/* || true
|
||||
if [ "$BUILD_EMMC" = "true" ]; then
|
||||
echo "Files available for SD image:"
|
||||
ls -la output_sd/images/
|
||||
echo ""
|
||||
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
|
||||
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 BR2_EXTERNAL_INFIX_PATH=$PWD
|
||||
export RELEASE=""
|
||||
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: |
|
||||
echo "Contents of output/images after mkimage.sh:"
|
||||
ls -lh output/images/
|
||||
if [ "$BUILD_EMMC" = "true" ]; then
|
||||
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
|
||||
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
|
||||
echo ""
|
||||
echo "eMMC image:"
|
||||
ls -lh output_emmc/images/*-emmc.img* 2>/dev/null || true
|
||||
if ls output_emmc/images/*-emmc.img 1> /dev/null 2>&1; then
|
||||
for img in output_emmc/images/*-emmc.img; do
|
||||
echo "- $(basename $img)"
|
||||
file "$img"
|
||||
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
|
||||
echo "No SD card image found matching pattern: *-sdcard.img"
|
||||
echo "Available files:"
|
||||
ls -la output/images/
|
||||
exit 1
|
||||
echo "Contents of output/images after mkimage.sh:"
|
||||
ls -lh output/images/
|
||||
|
||||
# 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
|
||||
|
||||
- name: Upload SD card image
|
||||
- name: Upload images as artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: sdcard-image-${{ inputs.board }}-${{ env.BOOTLOADER }}
|
||||
name: images-${{ inputs.board }}
|
||||
path: |
|
||||
output/images/*-sdcard.img*
|
||||
output/images/*-emmc.img*
|
||||
retention-days: 30
|
||||
|
||||
- name: Create checksums
|
||||
run: |
|
||||
cd output/images/
|
||||
for file in *-sdcard.img; do
|
||||
for file in *-sdcard.img *-emmc.img; do
|
||||
if [ -f "$file" ]; then
|
||||
sha256sum "$file" > "$file.sha256"
|
||||
fi
|
||||
@@ -198,11 +338,28 @@ jobs:
|
||||
prerelease: true
|
||||
tag: "latest-boot"
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
artifacts: "output/images/*-sdcard.img*"
|
||||
artifacts: "output/images/*-sdcard.img*,output/images/*-emmc.img*"
|
||||
|
||||
- name: Generate summary
|
||||
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! 🚀
|
||||
|
||||
**Board:** ${{ inputs.board }}
|
||||
@@ -211,8 +368,9 @@ jobs:
|
||||
**Artifact Source:** ${{ inputs.use_latest_release && 'Latest Release' || 'Latest Workflow Run' }}
|
||||
|
||||
## 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
|
||||
The SD card image is available as a workflow artifact above.
|
||||
EOF
|
||||
fi
|
||||
|
||||
@@ -1,27 +1,230 @@
|
||||
# Banana Pi R3
|
||||
# Banana Pi BPI-R3
|
||||
|
||||
## Support level
|
||||
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.
|
||||
<img src="bananapi-bpi-r3.webp" alt="The board" width=800 padding=10>
|
||||
|
||||
### Hardware features
|
||||
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
|
||||
## Overview
|
||||
|
||||
### Network configuration
|
||||
The board comes preconfigured with:
|
||||
- 4 switched LAN ports for internal networking
|
||||
- Dedicated WAN port with DHCP client enabled
|
||||
- SFP ports for high-speed fiber connections
|
||||
- Dual WiFi interfaces for wireless connectivity
|
||||
The Banana Pi R3 is a high-performance networking board with full Infix
|
||||
support for all enabled features including switched Ethernet ports, WiFi,
|
||||
and SFP interfaces.
|
||||
|
||||
### Pre-built images
|
||||
SD card image: [infix-bpi-r3-sdcard.img](https://github.com/kernelkit/infix/releases/download/latest-boot/infix-bpi-r3-sdcard.img)
|
||||
### Hardware Features
|
||||
|
||||
- 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 @@
|
||||
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 {
|
||||
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_MTK=y
|
||||
CONFIG_USB_MTU3=y
|
||||
CONFIG_CMD_USB=y
|
||||
CONFIG_PHY=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";
|
||||
};
|
||||
@@ -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
|
||||
@@ -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
|
||||
kernel default (*inherit*), which in turn fixes reported issues with dropped
|
||||
OSPF Hello frames in GRE tunnels
|
||||
- [Document][bpi-r3-emmc-documentation] how to go from SD card to eMMC on bpi-r3
|
||||
|
||||
### 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!
|
||||
|
||||
[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
|
||||
-------------------------
|
||||
|
||||
+42
-13
@@ -25,6 +25,7 @@ Options:
|
||||
-l List available boards
|
||||
-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/)
|
||||
-t target Image target type: sdcard or emmc (default: sdcard)
|
||||
|
||||
Arguments:
|
||||
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.
|
||||
|
||||
Output:
|
||||
SD card image saved to \$BINARIES_DIR/*-sdcard.img
|
||||
Image saved to \$BINARIES_DIR/*-sdcard.img or *-emmc.img
|
||||
|
||||
Examples:
|
||||
# From Buildroot build:
|
||||
@@ -52,6 +53,9 @@ Examples:
|
||||
# Download bootloader and compose with Linux image in output directory:
|
||||
$0 -od bananapi-bpi-r3
|
||||
|
||||
# Create eMMC image instead of SD card:
|
||||
$0 -t emmc bananapi-bpi-r3
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
@@ -107,7 +111,7 @@ run_genimage()
|
||||
--config "$genimage_cfg"
|
||||
|
||||
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
|
||||
log "Generating block map for $(basename "$img")..."
|
||||
bmaptool create -o "${img}.bmap" "$img"
|
||||
@@ -163,12 +167,17 @@ find_build_dir()
|
||||
get_bootloader_name()
|
||||
{
|
||||
board="$1"
|
||||
target="$2"
|
||||
case "$board" in
|
||||
raspberrypi-rpi64)
|
||||
echo "rpi64_boot"
|
||||
;;
|
||||
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)
|
||||
echo "nanopi_r2s_boot"
|
||||
@@ -187,8 +196,9 @@ download_bootloader()
|
||||
{
|
||||
board="$1"
|
||||
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
|
||||
die "gh CLI not found. Install it or build bootloader locally."
|
||||
@@ -271,7 +281,7 @@ discover_rpi_boot_files()
|
||||
echo "$files"
|
||||
}
|
||||
|
||||
while getopts "hldfob:r:" opt; do
|
||||
while getopts "hldfob:r:t:" opt; do
|
||||
case $opt in
|
||||
b)
|
||||
BOOT_DIR="$OPTARG"
|
||||
@@ -299,6 +309,9 @@ while getopts "hldfob:r:" opt; do
|
||||
ROOT_DIR="$OPTARG"
|
||||
STANDALONE=1
|
||||
;;
|
||||
t)
|
||||
TARGET="$OPTARG"
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
@@ -312,6 +325,22 @@ if ! validate_board "$1"; then
|
||||
exit 1
|
||||
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
|
||||
if [ -n "$STANDALONE" ]; then
|
||||
# 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
|
||||
ORIGINAL_BINARIES_DIR="$BINARIES_DIR"
|
||||
|
||||
download_bootloader "$BOARD" "$BUILD_DIR"
|
||||
download_bootloader "$BOARD" "$BUILD_DIR" "$TARGET"
|
||||
|
||||
# Now use the temporary directory for composition
|
||||
BINARIES_DIR="$SDCARD_TEMP_DIR"
|
||||
@@ -458,7 +487,7 @@ fi
|
||||
# Epxand template variables
|
||||
sed "s|#VERSION#|${RELEASE}|" "$GENIMAGE_TEMPLATE" | \
|
||||
sed "s|#INFIX_ID#|${INFIX_ID}|" | \
|
||||
sed "s|#TARGET#|sd|" > "$GENIMAGE_CFG"
|
||||
sed "s|#TARGET#|${TARGET}|" > "$GENIMAGE_CFG"
|
||||
|
||||
# Clean up temp file if created
|
||||
rm -f "${GENIMAGE_CFG}.tmp"
|
||||
@@ -479,19 +508,19 @@ else
|
||||
fi
|
||||
|
||||
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"
|
||||
else
|
||||
log "Creating SD card image ..."
|
||||
log "Creating $TARGET image ..."
|
||||
run_genimage "$GENIMAGE_CFG"
|
||||
fi
|
||||
|
||||
# Post-processing: move images and cleanup if using download mode
|
||||
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"
|
||||
|
||||
for img in "${BINARIES_DIR}"/*-sdcard.img*; do
|
||||
for img in "${BINARIES_DIR}"/*-sdcard.img* "${BINARIES_DIR}"/*-emmc.img*; do
|
||||
if [ -f "$img" ]; then
|
||||
mv "$img" "$ORIGINAL_BINARIES_DIR/"
|
||||
log " $(basename "$img")"
|
||||
@@ -505,8 +534,8 @@ if [ -n "$DOWNLOAD_BOOT" ]; then
|
||||
BINARIES_DIR="$ORIGINAL_BINARIES_DIR"
|
||||
fi
|
||||
|
||||
log "SD card image created successfully:"
|
||||
for img in "${BINARIES_DIR}"/*-sdcard.img*; do
|
||||
log "$TARGET image created successfully:"
|
||||
for img in "${BINARIES_DIR}"/*-sdcard.img* "${BINARIES_DIR}"/*-emmc.img*; do
|
||||
if [ -f "$img" ]; then
|
||||
if [ -n "$STANDALONE" ]; then
|
||||
# Show relative path in standalone mode
|
||||
|
||||
Reference in New Issue
Block a user