[openwrt/openwrt] mediatek: add SD card image creation for Banana Pi R2

LEDE Commits lede-commits at lists.infradead.org
Wed Jul 8 17:22:58 EDT 2020


ynezz pushed a commit to openwrt/openwrt.git, branch master:
https://git.openwrt.org/7adc29f59ede5112b94b3df4688b47a88f84f544

commit 7adc29f59ede5112b94b3df4688b47a88f84f544
Author: David Woodhouse <dwmw2 at infradead.org>
AuthorDate: Fri Jun 12 11:06:38 2020 +0100

    mediatek: add SD card image creation for Banana Pi R2
    
    Based on work by Alexey Loukianov <lx2 at lexa2.ru> and others.
    
    Signed-off-by: David Woodhouse <dwmw2 at infradead.org>
---
 .../patches/005-update-bpir2-defconfig.patch       |   3 +-
 target/linux/mediatek/image/Config.in              |   4 +
 target/linux/mediatek/image/gen_banana_pi_img.sh   | 145 +++++++++++++++++++++
 target/linux/mediatek/image/mt7623.mk              |  30 +++++
 target/linux/mediatek/image/mt7623n_bpir2-uEnv.txt |  78 +++++++++++
 5 files changed, 259 insertions(+), 1 deletion(-)

diff --git a/package/boot/uboot-mediatek/patches/005-update-bpir2-defconfig.patch b/package/boot/uboot-mediatek/patches/005-update-bpir2-defconfig.patch
index 104994bf63..a45665eff6 100644
--- a/package/boot/uboot-mediatek/patches/005-update-bpir2-defconfig.patch
+++ b/package/boot/uboot-mediatek/patches/005-update-bpir2-defconfig.patch
@@ -2,7 +2,7 @@ diff --git a/configs/mt7623n_bpir2_defconfig b/configs/mt7623n_bpir2_defconfig
 index 6b9fbd7e22..fb2a004803 100644
 --- a/configs/mt7623n_bpir2_defconfig
 +++ b/configs/mt7623n_bpir2_defconfig
-@@ -52,3 +52,12 @@ CONFIG_TIMER=y
+@@ -52,3 +52,13 @@ CONFIG_TIMER=y
  CONFIG_WDT_MTK=y
  CONFIG_LZMA=y
  # CONFIG_EFI_LOADER is not set
@@ -15,3 +15,4 @@ index 6b9fbd7e22..fb2a004803 100644
 +CONFIG_ENV_FAT_FILE="uboot.env"
 +CONFIG_CMD_ASKENV=y
 +CONFIG_ENV_SIZE=0x2000
++CONFIG_CMD_SETEXPR=y
diff --git a/target/linux/mediatek/image/Config.in b/target/linux/mediatek/image/Config.in
new file mode 100644
index 0000000000..f32f83c321
--- /dev/null
+++ b/target/linux/mediatek/image/Config.in
@@ -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
diff --git a/target/linux/mediatek/image/gen_banana_pi_img.sh b/target/linux/mediatek/image/gen_banana_pi_img.sh
new file mode 100755
index 0000000000..26fbca1388
--- /dev/null
+++ b/target/linux/mediatek/image/gen_banana_pi_img.sh
@@ -0,0 +1,145 @@
+#!/bin/sh
+#
+# Copyright © 2019 Alexey Loukianov <lx2 at lexa2.ru>
+# Copyright © 2020 David Woodhouse <dwmw2 at 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 at 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
diff --git a/target/linux/mediatek/image/mt7623.mk b/target/linux/mediatek/image/mt7623.mk
index a38c03deb9..1c2dcf7624 100644
--- a/target/linux/mediatek/image/mt7623.mk
+++ b/target/linux/mediatek/image/mt7623.mk
@@ -1,5 +1,30 @@
 KERNEL_LOADADDR := 0x80008000
 
+ifneq ($(CONFIG_BANANA_PI_BOOT_PARTSIZE),)
+BOOTFS_BLOCK_SIZE := 1024
+BOOTFS_BLOCKS := $(shell echo $$(($(CONFIG_BANANA_PI_BOOT_PARTSIZE)*1024*1024/$(BOOTFS_BLOCK_SIZE))))
+endif
+
+define Build/banana-pi-sdcard
+	rm -f $@.boot
+	mkfs.fat -C $@.boot $(BOOTFS_BLOCKS)
+
+	./gen_banana_pi_img.sh emmc $@.emmc \
+		$(STAGING_DIR_IMAGE)/$(UBOOT_TARGET)-preloader.bin
+
+	mkenvimage -s 0x2000 -o $(STAGING_DIR_IMAGE)/$(UBOOT_TARGET)-uboot.env $(UBOOT_TARGET)-uEnv.txt
+	mcopy -i $@.boot $(STAGING_DIR_IMAGE)/$(UBOOT_TARGET)-uboot.env ::uboot.env
+	mcopy -i $@.boot $(IMAGE_KERNEL) ::uImage
+	mcopy -i $@.boot $@.emmc ::eMMCboot.bin
+	./gen_banana_pi_img.sh sd $@ \
+		$(STAGING_DIR_IMAGE)/$(UBOOT_TARGET)-preloader.bin \
+		$(STAGING_DIR_IMAGE)/$(UBOOT_TARGET)-u-boot.bin \
+		$@.boot \
+		$(IMAGE_ROOTFS) \
+		$(CONFIG_BANANA_PI_BOOT_PARTSIZE) \
+		$(CONFIG_TARGET_ROOTFS_PARTSIZE)
+endef
+
 define Device/bpi_bananapi-r2
   DEVICE_VENDOR := Bpi
   DEVICE_MODEL := Banana Pi R2
@@ -7,6 +32,11 @@ define Device/bpi_bananapi-r2
   SUPPORTED_DEVICES := bananapi,bpi-r2
   DEVICE_PACKAGES := kmod-fs-vfat kmod-nls-cp437 kmod-nls-iso8859-1 kmod-mmc \
 	mkf2fs e2fsprogs kmod-usb-ohci kmod-usb2 kmod-usb3 kmod-ata-ahci-mtk
+  UBOOT_TARGET := mt7623n_bpir2
+  IMAGES := img.gz
+  IMAGE/img.gz := banana-pi-sdcard | gzip | append-metadata
+  KERNEL := kernel-bin | fit none $$(DTS_DIR)/$$(DEVICE_DTS).dtb
+  KERNEL_INITRAMFS :=
 endef
 TARGET_DEVICES += bpi_bananapi-r2
 
diff --git a/target/linux/mediatek/image/mt7623n_bpir2-uEnv.txt b/target/linux/mediatek/image/mt7623n_bpir2-uEnv.txt
new file mode 100644
index 0000000000..f260ed9176
--- /dev/null
+++ b/target/linux/mediatek/image/mt7623n_bpir2-uEnv.txt
@@ -0,0 +1,78 @@
+# Boot menu for Banana Pi R2
+# Copyright © 2020 David Woodhouse <dwmw2 at 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



More information about the lede-commits mailing list