I do not stick with original partition scheme and prefer to keep limitations to the bare minimum possible. As had been figured out in this thread minimal requirements for board to boot from SD are:
- SDBOOT 20 byte signature at offset 0.
- BRLYT 32 byte signature at offset 512 (1 sector).
- Preloader binary at offset 2048 (2k == 4 sectors).
- U-boot raw binary at offset 327680 (320k = 640 sectors).
- Only MS-DOS MBR-style partition table label is allowed.
- No active partitions are allowed.
So my script to create bootable SD is like this:
#!/usr/bin/env bash
#
# Copyright (C) 2013-2019 OpenWrt.org
#
# This is free software, licensed under the GNU General Public License v2.
# See /LICENSE for more information.
#
set -ex
[ $# -eq 7 ] || {
echo "SYNTAX: $0 <file> <preloader image> <u-boot image> <bootfs image> <rootfs image> <bootfs size> <rootfs size>"
exit 1
}
OUTPUT="$1"
PRELOADER="$2"
UBOOT="$3"
BOOTFS="$4"
ROOTFS="$5"
BOOTFSSIZE="$6"
ROOTFSSIZE="$7"
head=4
sect=63
set `ptgen -o $OUTPUT -h $head -s $sect -l 1024 -t c -p ${BOOTFSSIZE}M -t 83 -p ${ROOTFSSIZE}M -a 0`
BOOT_OFFSET="$(($1 / 512))"
BOOT_SIZE="$(($2 / 512))"
ROOTFS_OFFSET="$(($3 / 512))"
ROOTFS_SIZE="$(($4 / 512))"
PRELOADER_OFFSET=2 # 2KB
UBOOT_OFFSET=320 # 320KB
SDMMC_BOOT="SDMMC_BOOT\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"
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=1024 if="${UBOOT}" of="${OUTPUT}" seek="${UBOOT_OFFSET}" conv=notrunc
dd bs=512 if="${BOOTFS}" of="${OUTPUT}" seek="${BOOT_OFFSET}" conv=notrunc
dd bs=512 if="${ROOTFS}" of="${OUTPUT}" seek="${ROOTFS_OFFSET}" conv=notrunc
Having u-boot sitting at 320k offset and knowing that u-boot binary is about 300k in size (as of 2019.01 version built from your repo) leaves us with a relatively safe assumption that we may place the start of the first partition at 1MB offset - and it so happens that this offset is a default offset for modern linux-world partitioning tools like fdisk or parted. So I have this patch applied:
diff --git a/include/configs/mt7623.h b/include/configs/mt7623.h
index ba763501..fb6ac073 100644
--- a/include/configs/mt7623.h
+++ b/include/configs/mt7623.h
@@ -53,4 +53,7 @@
#define CONFIG_EXTRA_ENV_SETTINGS \
FDT_HIGH
+#define CONFIG_SYS_MMC_ENV_DEV 0
+#define CONFIG_ENV_OFFSET 0xF3800
+
#endif
Regarding boot detection logic, here is how I’ve done it:
roottmpl=${rootdev} rootfstype=ext4 rootwait
prepsetroot=setenv setroot setenv root ${roottmpl}
buildargs=setenv bootargs "console=${console} root=${root} ${bootopts} ${graphic}"
checkbootedfrom=if itest.l *81dffff0 == 434d4d65 ; then setenv bootedfrom eMMC; else setenv bootedfrom SD; fi;
checksd=fatinfo ${device} 1:1
selectmmc=run useemmc; if test "${bootedfrom}" == "eMMC"; then echo "Booted from eMMC, using eMMC"; else run selectsd; fi;
selectsd=if run checksd; then echo "Booted from SD, pt#1 FAT OK, use SD"; run usesd; else echo "Booted from SD, pr#1 is not FAT, fall back to eMMC"; fi;
usesd=setenv partition 1:1; setenv rootdev /dev/mmcblk1p2;
useemmc=setenv partition 0:1; setenv rootdev /dev/mmcblk0p2;
newboot=run prepsetroot; run setroot;run buildargs;printenv bootargs;fatload ${device} ${partition} ${loadaddr} ${kernel}; bootm
#bootmenu
boot0=run lskernel;run askkernel;if printenv kernelinput ;then setenv kernel ${kernelinput};run lsdtb;run askdtb;if printenv dtbinput ;then setenv fdt ${dtbinput};fi; run newboot2; fi;
boot1=run newboot;
bootmenu_default=2
bootmenu_0=1. Enter kernel-name to boot from SD/EMMC.=run boot0
bootmenu_1=2. Boot kernel from TFTP.=run bootnet
bootmenu_2=3. Boot from SD/EMMC (auto select).=run boot1
bootmenu_3=4. Boot from eMMC.=run useemmc; run boot1
bootmenu_4=5. Boot from SD.=run usesd; run boot1