diff --git a/.github/workflows/build-boot.yml b/.github/workflows/build-boot.yml index 41a2a758b..9ae6f0671 100644 --- a/.github/workflows/build-boot.yml +++ b/.github/workflows/build-boot.yml @@ -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 diff --git a/.github/workflows/build-image.yml b/.github/workflows/build-image.yml index 5b565b426..c7878bbab 100644 --- a/.github/workflows/build-image.yml +++ b/.github/workflows/build-image.yml @@ -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/ + + 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/ - # 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 "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/ + 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/ + + 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_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/ + # 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/ + 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/ - - # 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/ + 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/ + + 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/ + + # 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/ - - # 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 + 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 + + 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 <> $GITHUB_STEP_SUMMARY + if [ "$BUILD_EMMC" = "true" ]; then + cat <> $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 <> $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 diff --git a/board/aarch64/bananapi-bpi-r3/README.md b/board/aarch64/bananapi-bpi-r3/README.md index 2417412ad..fff658896 100644 --- a/board/aarch64/bananapi-bpi-r3/README.md +++ b/board/aarch64/bananapi-bpi-r3/README.md @@ -1,27 +1,230 @@ -# Banana Pi 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. - -### 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 - -### 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 - -### 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) +# Banana Pi BPI-R3 +The board + +## Overview + +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. + +### 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: + +DIP switches + +| 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 diff --git a/board/aarch64/bananapi-bpi-r3/bananapi-bpi-r3.webp b/board/aarch64/bananapi-bpi-r3/bananapi-bpi-r3.webp new file mode 100644 index 000000000..e46d56535 Binary files /dev/null and b/board/aarch64/bananapi-bpi-r3/bananapi-bpi-r3.webp differ diff --git a/board/aarch64/bananapi-bpi-r3/bootstrap-switch.webp b/board/aarch64/bananapi-bpi-r3/bootstrap-switch.webp new file mode 100644 index 000000000..6b67da2c3 Binary files /dev/null and b/board/aarch64/bananapi-bpi-r3/bootstrap-switch.webp differ diff --git a/board/aarch64/bananapi-bpi-r3/dts/Makefile b/board/aarch64/bananapi-bpi-r3/dts/Makefile index 0c3becfbb..974394efb 100644 --- a/board/aarch64/bananapi-bpi-r3/dts/Makefile +++ b/board/aarch64/bananapi-bpi-r3/dts/Makefile @@ -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 diff --git a/board/aarch64/bananapi-bpi-r3/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dts b/board/aarch64/bananapi-bpi-r3/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dts new file mode 100644 index 000000000..dafbe2451 --- /dev/null +++ b/board/aarch64/bananapi-bpi-r3/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dts @@ -0,0 +1,2 @@ +#include "mt7986a-bananapi-bpi-r3.dtsi" +#include "mt7986a-bananapi-bpi-r3-emmc.dtsi" diff --git a/board/aarch64/bananapi-bpi-r3/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtsi b/board/aarch64/bananapi-bpi-r3/dts/mediatek/mt7986a-bananapi-bpi-r3-emmc.dtsi new file mode 100644 index 000000000..c92d1163c --- /dev/null +++ b/board/aarch64/bananapi-bpi-r3/dts/mediatek/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 + */ + +/* +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"; +}; diff --git a/board/aarch64/bananapi-bpi-r3/genimage.cfg.in b/board/aarch64/bananapi-bpi-r3/genimage.cfg.in index 67d5413ac..cbb345f69 100644 --- a/board/aarch64/bananapi-bpi-r3/genimage.cfg.in +++ b/board/aarch64/bananapi-bpi-r3/genimage.cfg.in @@ -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" diff --git a/board/aarch64/bananapi-bpi-r3/uboot/emmc-extras.config b/board/aarch64/bananapi-bpi-r3/uboot/emmc-extras.config new file mode 100644 index 000000000..6a411124d --- /dev/null +++ b/board/aarch64/bananapi-bpi-r3/uboot/emmc-extras.config @@ -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" diff --git a/board/aarch64/bananapi-bpi-r3/uboot/extras.config b/board/aarch64/bananapi-bpi-r3/uboot/extras.config index 24dbf5deb..70fa5ab64 100644 --- a/board/aarch64/bananapi-bpi-r3/uboot/extras.config +++ b/board/aarch64/bananapi-bpi-r3/uboot/extras.config @@ -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 diff --git a/board/aarch64/bananapi-bpi-r3/uboot/mt7986-emmc-env.dtsi b/board/aarch64/bananapi-bpi-r3/uboot/mt7986-emmc-env.dtsi new file mode 100644 index 000000000..410ada011 --- /dev/null +++ b/board/aarch64/bananapi-bpi-r3/uboot/mt7986-emmc-env.dtsi @@ -0,0 +1,5 @@ +#include + +&env { + fdtfile = "mediatek/mt7986a-bananapi-bpi-r3-emmc.dtb"; +}; diff --git a/configs/bpi_r3_emmc_boot_defconfig b/configs/bpi_r3_emmc_boot_defconfig new file mode 100644 index 000000000..9f3844032 --- /dev/null +++ b/configs/bpi_r3_emmc_boot_defconfig @@ -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 diff --git a/configs/bpi_r3_boot_defconfig b/configs/bpi_r3_sd_boot_defconfig similarity index 100% rename from configs/bpi_r3_boot_defconfig rename to configs/bpi_r3_sd_boot_defconfig diff --git a/doc/ChangeLog.md b/doc/ChangeLog.md index 8d41aff75..326e07340 100644 --- a/doc/ChangeLog.md +++ b/doc/ChangeLog.md @@ -24,6 +24,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 @@ -32,6 +33,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 ------------------------- diff --git a/utils/mkimage.sh b/utils/mkimage.sh index 58f7ef0d6..b5da7d90d 100755 --- a/utils/mkimage.sh +++ b/utils/mkimage.sh @@ -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