forked from openwrt/openwrt
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
mediatek: add SD card image creation for Banana Pi R2
Based on work by Alexey Loukianov <lx2@lexa2.ru> and others. Signed-off-by: David Woodhouse <dwmw2@infradead.org>
- Loading branch information
Showing
5 changed files
with
259 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
config BANANA_PI_BOOT_PARTSIZE | ||
int "Boot (SD Card) filesystem partition size (in MiB)" | ||
depends on TARGET_mediatek_mt7623_DEVICE_bpi_bananapi-r2 | ||
default 32 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
#!/bin/sh | ||
# | ||
# Copyright © 2019 Alexey Loukianov <lx2@lexa2.ru> | ||
# Copyright © 2020 David Woodhouse <dwmw2@infradead.org> | ||
# | ||
# This is free software, licensed under the GNU General Public License v2. | ||
# See /LICENSE for more information. | ||
# | ||
|
||
# Generates a bootable SD card image for Banana Pi R2 (and probably | ||
# other similar boards) as documented at | ||
# http://www.fw-web.de/dokuwiki/doku.php?id=en:bpi-r2:storage | ||
# | ||
# The first sector must contain the SDMMC_BOOT header shown | ||
# below, and also contains the MBR partition table in the end | ||
# of the sector. The partition table must contain no active | ||
# partitions. | ||
# | ||
# The second sector must contain the BRLYT header, and the | ||
# special preloader image goes in sector 4; 2KiB into the image. | ||
# | ||
# The preloader loads U-Boot from sector 640; 320KiB into the image. | ||
# The location and the size (512KiB) are fixed and not read from | ||
# the partition table. We set up a partition for it merely for | ||
# our own convenience for upgrades, etc. | ||
# | ||
# The second partition is a FAT file system containing the kernel | ||
# image and a uboot.env file, which is provided to this script as | ||
# $4 (bootfs image). Its size is configurable with the | ||
# CONFIG_BANANA_PI_BOOT_PARTSIZE option; by default 32MiB. | ||
# | ||
# The root filesystem comes next in the third partition. | ||
# | ||
# | ||
# ------------------------ Sector Offset | ||
# | MBR + SDMMC_BOOT | 0 0x0 | ||
# |----------------------| | ||
# | BRLYT header | 1 0x200 | ||
# |----------------------| | ||
# . . | ||
# . . | ||
# |----------------------| | ||
# | | 4 0x800 | ||
# | | | ||
# | Preloader | | ||
# . . | ||
# . . | ||
# | | 639 | ||
# |----------------------| | ||
# | MBR partition #1 | 640 0x50000 | ||
# | | | ||
# | U-Boot | | ||
# . . | ||
# . . | ||
# | | 1663 | ||
# |----------------------| | ||
# | MBR partition #2 | | ||
# | | | ||
# | FAT partition | ( BANANA_PI_BOOT_PARTSIZE | ||
# . . default 32MiB ) | ||
# . (kernel, uEnv) . | ||
# | | | ||
# |----------------------| | ||
# | MBR partition #3 | | ||
# | | | ||
# | Root partition | | ||
# | | ( TARGET_ROOTFS_PARTSIZE | ||
# | (squashfs+overlay | default 104MiB ) | ||
# . or ext4, etc.) . | ||
# . . | ||
# | | | ||
# ------------------------ | ||
# | ||
# For eMMC boot, everything up to and including the preloader must be | ||
# written to /dev/mmcblk0boot0, with the SDMMC_BOOT header changed to | ||
# read EMMC_BOOT\0 instead. | ||
# | ||
# The contents of the main eMMC are identical to the SD card layout, | ||
# with the preloader loading 512KiB of U-Boot starting at 0x50000. | ||
|
||
function usage() { | ||
echo "SYNTAX: $0 sd <file> <preloader image> <u-boot image> <bootfs image> <rootfs image> <bootfs size> <rootfs size>" | ||
echo " OR: $0 emmc <file> <preloader image>" | ||
exit 1 | ||
} | ||
|
||
set -e | ||
|
||
PRELOADER_OFFSET=2 # 2KiB | ||
|
||
SDMMC_BOOT="SDMMC_BOOT\x00\x00\x01\x00\x00\x00\x00\x02\x00\x00" | ||
EMMC_BOOT="EMMC_BOOT\x00\x00\x00\x01\x00\x00\x00\x00\x02\x00\x00" | ||
BRLYT="BRLYT\x00\x00\x00\x01\x00\x00\x00\x00\x08\x00\x00\ | ||
\x00\x08\x00\x00\x42\x42\x42\x42\x08\x00\x01\x00\x00\x08\x00\x00\ | ||
\x00\x08\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" | ||
|
||
case $1 in | ||
sd) | ||
[ $# -eq 8 ] || usage | ||
OUTPUT="$2" | ||
PRELOADER="$3" | ||
UBOOT="$4" | ||
BOOTFS="$5" | ||
ROOTFS="$6" | ||
BOOTFSSIZE="$7" | ||
ROOTFSSIZE="$8" | ||
|
||
head=4 | ||
sect=63 | ||
|
||
set $(ptgen -o $OUTPUT -h $head -s $sect -a 0 -l 1024 \ | ||
-t 41 -p 512k@320k \ | ||
-t c -p ${BOOTFSSIZE}M \ | ||
-t 83 -p ${ROOTFSSIZE}M ) | ||
|
||
UBOOT_OFFSET="$(($1 / 512))" | ||
UBOOT_SIZE="$(($2 / 512))" | ||
BOOTFS_OFFSET="$(($3 / 512))" | ||
BOOTFS_SIZE="$(($4 / 512))" | ||
ROOTFS_OFFSET="$(($5 / 512))" | ||
ROOTFS_SIZE="$(($6 / 512))" | ||
|
||
echo -en "${SDMMC_BOOT}" | dd bs=1 of="${OUTPUT}" seek=0 conv=notrunc | ||
echo -en "${BRLYT}" | dd bs=1 of="${OUTPUT}" seek=512 conv=notrunc | ||
|
||
dd bs=1024 if="${PRELOADER}" of="${OUTPUT}" seek="${PRELOADER_OFFSET}" conv=notrunc | ||
dd bs=512 if="${UBOOT}" of="${OUTPUT}" seek="${UBOOT_OFFSET}" conv=notrunc | ||
dd bs=512 if="${BOOTFS}" of="${OUTPUT}" seek="${BOOTFS_OFFSET}" conv=notrunc | ||
dd bs=512 if="${ROOTFS}" of="${OUTPUT}" seek="${ROOTFS_OFFSET}" conv=notrunc | ||
dd bs=128k if=/dev/zero of="${OUTPUT}" count=1 oflag=append conv=notrunc | ||
;; | ||
emmc) | ||
[ $# -eq 3 ] || usage | ||
OUTPUT="$2" | ||
PRELOADER="$3" | ||
|
||
echo -en "${EMMC_BOOT}" | dd bs=1 of="${OUTPUT}" seek=0 | ||
echo -en "${BRLYT}" | dd bs=1 of="${OUTPUT}" seek=512 conv=notrunc | ||
|
||
dd bs=1024 if="${PRELOADER}" of="${OUTPUT}" seek="${PRELOADER_OFFSET}" conv=notrunc | ||
;; | ||
*) | ||
usage | ||
;; | ||
esac |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
# Boot menu for Banana Pi R2 | ||
# Copyright © 2020 David Woodhouse <dwmw2@infradead.org> | ||
|
||
kernel=uImage | ||
loadaddr=0x88000000 | ||
dtaddr=0x83f00000 | ||
fdt_high=0xffffffff | ||
|
||
console=ttyS2,115200 | ||
bootopts=rootfstype=squashfs,ext4 rootwait | ||
|
||
# Create the command line (with appropriate root=) and boot the Linux FIT image. | ||
boot1=setenv bootargs "console=${console} root=${rootdev} ${bootopts}";printenv bootargs;\ | ||
fatload mmc ${partition} ${loadaddr} ${kernel}; bootm | ||
|
||
# The preloader leaves a breadcrumb behind to say what it booted from. | ||
checkbootedfrom=if itest.l *81dffff0 == 434d4d65 ; then setenv bootedfrom eMMC; else setenv bootedfrom SD; fi; | ||
|
||
# Build the boot menu one item at a time | ||
bm_count=0 | ||
checkkernel=test -e mmc ${bm_part} ${kernel} | ||
addbm=if run checkkernel; then setenv bootmenu_${bm_count} "Boot from ${bm_dev}.=setenv partition ${bm_part};setenv rootdev ${bm_root};run boot1";if test "${bootedfrom}" = "${bm_dev}"; then setenv bootmenu_default ${bm_count};fi;setexpr bm_count ${bm_count} + 1; fi | ||
# Here we assume that SD card id mmcblk1 and eMMC is mmcblk0 in linux. Swap them if your DTS define them in reverse order. | ||
addeMMCbm=setenv bm_part 0:2;setenv bm_root /dev/mmcblk0p3;setenv bm_dev eMMC;run addbm | ||
addSDbm=setenv bm_part 1:2;setenv bm_root /dev/mmcblk1p3;setenv bm_dev SD;run addbm | ||
addinstallbm=if test "${bootedfrom}" = "SD";then run checkinstall; if run validparts; then setenv bootmenu_${bm_count} "Install OpenWrt from SD to internal eMMC.=run doinstall";setexpr bm_count ${bm_count} + 1;fi;fi | ||
|
||
runbootmenu=if test "${bootedfrom}" = "";then run checkbootedfrom;fi;\ | ||
setenv bm_count 0;run addeMMCbm;run addSDbm;run addinstallbm;setenv bootmenu_${bm_count};\ | ||
bootmenu | ||
|
||
bootdelay=0 | ||
bootcmd=run checkbootedfrom;run runbootmenu | ||
|
||
# XX: Can we read this from the device, or must we trust they're all the same as mine? | ||
# Probably not that important as we're unlikely ever to hit the limit anyway. | ||
maxsect=0xe8ffff | ||
validparts=false | ||
|
||
# We could use 'part size' here but I'd like to check the types too. | ||
checkinstall=mmc dev 1;\ | ||
mmc read 0x88000002 0 1;\ | ||
setenv validparts true;\ | ||
test -e mmc 1:2 eMMCboot.bin || setenv validparts false && echo "eMMCboot.bin not present on SD partition 2";\ | ||
if run validparts && itest.b *0x880001c4 != 0x41; then echo "SD partition 1 is not a PReP Boot partition"; setenv validparts false; fi;\ | ||
if run validparts && itest.l *0x880001c8 != 0x280; then echo "SD partition 1 does not start at 320KiB for U-Boot"; mmc part; exit; fi;\ | ||
if run validparts && itest.l *0x880001cc != 0x400; then echo "SD partition 1 is not 512KiB in size for U-Boot"; mmc part; exit; fi;\ | ||
if run validparts && itest.b *0x880001d4 != 0x0c; then echo "SD partition 2 is not a FAT32 partition"; setenv validparts false; fi;\ | ||
if run validparts && itest.b *0x880001e4 != 0x83; then echo "SD partition 3 is not a Linux partition"; setenv validparts false; fi;\ | ||
setexpr.l part2_start *0x880001d8;setexpr.l part2_len *0x880001dc;setexpr.l part3_start *0x880001e8;setexpr.l part3_len *0x880001ec;\ | ||
if run validparts && test 0x${part2_start} -gt ${maxsect}; then echo "SD partition 2 start too high"; setenv validparts false; fi;\ | ||
if run validparts && test 0x${part2_len} -gt ${maxsect}; then echo "SD partition 2 is too large"; setenv validparts false; fi;\ | ||
if run validparts && test 0x${part3_start} -gt ${maxsect}; then echo "SD partition 3 start too high"; setenv validparts false; fi;\ | ||
if run validparts && test 0x${part3_len} -gt ${maxsect}; then echo "SD partition 2 is too large"; setenv validparts false; fi;\ | ||
setexpr.l part2_end 0x$(part2_start} + 0x${part2_len};setexpr.l part3_end 0x${part3_start} + 0x${part3_len};\ | ||
if run validparts && test 0x${part2_end} -ge ${maxsect}; then echo "SD partition 2 end too high"; setenv validparts false; fi;\ | ||
if run validparts && test 0x${part3_end} -ge ${maxsect}; then echo "SD partition 3 end too high"; setenv validparts false; fi; | ||
|
||
# Copy a single chunk, up to 0x8000 sectors / 16MiB, from SD to eMMC at the specified offset. | ||
writechunk=setenv thislen 8000; if test 0x${partlen} -lt 0x${thislen}; then setenv thislen ${partlen};fi;\ | ||
mmc dev 1;mmc read ${loadaddr} 0x${partofs} 0x${thislen};\ | ||
mmc dev 0; mmc write ${loadaddr} 0x${partofs} 0x${thislen};\ | ||
setexpr partofs 0x${partofs} + 0x${thislen};setexpr partlen 0x${partlen} - 0x${thislen} | ||
|
||
# Copy a partition defined by ${partofs} / ${partlen} from SD to eMMC | ||
writepart=while test 0x${partlen} -ne 0; do run writechunk; done | ||
|
||
# Configure the eMMC boot partition and write eMMCboot.bin to it | ||
writeboot=mmc partconf 0 1 1 0;fatload mmc 1:2 ${loadaddr} eMMCboot.bin;\ | ||
setexpr filesize ${filesize} + 0x1ff;setexpr blocks ${filesize} / 0x200;\ | ||
mmc dev 0 1;mmc write ${loadaddr} 0 ${blocks} | ||
|
||
# Install OpenWrt from the SD card to internal eMMC. | ||
doinstall=run checkinstall;if run validparts;then run writeboot;\ | ||
echo "Copying preloader and U-Boot";setenv partofs 0;setenv partlen 680;run writepart;\ | ||
echo "Copying FAT boot partition";setenv partofs ${part2_start};setenv partlen ${part2_len};run writepart;\ | ||
echo "Copying root partition";setenv partofs ${part3_start};setenv partlen ${part3_len};run writepart;\ | ||
echo "Installed OpenWrt to eMMC";setenv bootedfrom eMMC;run runbootmenu;fi |