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>master
parent
0c7bce7efd
commit
7adc29f59e
@ -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
|
@ -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
|
@ -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
|
Loading…
Reference in New Issue