add "fastboot-bootpart" flasher to flash split images with fastboot (!1871)
asus-me176c has a Fastboot interface that can be used for flashing, but in postmarketOS we do not use Android boot images for it. This is because is it not very practical - the boot partition is quite small and there is a (custom) EFI bootloader that can boot directly from any other FAT32 partition. At the moment the installation process is manual: 1. pmbootstrap install --split to have separated boot (FAT32) and rootfs images 2. pmbootstrap export 3. Flash boot and rootfs images manually using Fastboot The "fastboot-bootpart" flasher implements that process in a more convenient way. When a device uses the "fastboot-bootpart" flasher: - We generate --split images on "pmbootstrap install" by default. (This can be disabled using --no-split instead.) - pmbootstrap flasher flash_kernel flashes the raw boot partition (not an Android boot image) using Fastboot, just like the rootfs. There are some limitations that could be improved in the future: - "fastboot-bootpart" is not offered in the device wizard. I think it is special enough that no-one will be starting with it, and the difference to normal "fastboot" might be confusing. - Support "pmbootstrap flasher boot". asus-me176c does not support "fastboot boot" properly, but theoretically we could still generate Android boot images to use when booting an image directly. - At the moment the boot partition image is not regenerated when using "pmbootstrap flasher flash_kernel" (unlike when using Android boot images). "pmbootstrap install" needs to be run manually first.
This commit is contained in:
parent
ba1e39f48e
commit
87dd071b32
|
@ -344,7 +344,9 @@ Flasher abstraction. Allowed variables:
|
|||
|
||||
$BOOT: Path to the /boot partition
|
||||
$FLAVOR: Kernel flavor
|
||||
$IMAGE: Path to the rootfs image
|
||||
$IMAGE: Path to the combined boot/rootfs image
|
||||
$IMAGE_SPLIT_BOOT: Path to the (split) boot image
|
||||
$IMAGE_SPLIT_ROOT: Path to the (split) rootfs image
|
||||
$PARTITION_KERNEL: Partition to flash the kernel/boot.img to
|
||||
$PARTITION_SYSTEM: Partition to flash the rootfs to
|
||||
|
||||
|
@ -365,6 +367,23 @@ flashers = {
|
|||
"boot", "$BOOT/boot.img-$FLAVOR"]],
|
||||
},
|
||||
},
|
||||
# Some devices provide Fastboot but using Android boot images is not practical
|
||||
# for them (e.g. because they support booting from FAT32 partitions directly
|
||||
# and/or the Android boot partition is too small). This can be implemented
|
||||
# using --split (separate image files for boot and rootfs).
|
||||
# This flasher allows flashing the split image files using Fastboot.
|
||||
"fastboot-bootpart": {
|
||||
"split": True,
|
||||
"depends": ["android-tools"],
|
||||
"actions": {
|
||||
"list_devices": [["fastboot", "devices", "-l"]],
|
||||
"flash_rootfs": [["fastboot", "flash", "$PARTITION_SYSTEM",
|
||||
"$IMAGE_SPLIT_ROOT"]],
|
||||
"flash_kernel": [["fastboot", "flash", "$PARTITION_KERNEL",
|
||||
"$IMAGE_SPLIT_BOOT"]],
|
||||
# TODO: Add support for boot
|
||||
},
|
||||
},
|
||||
# Some Samsung devices need the initramfs to be baked into the kernel (e.g.
|
||||
# i9070, i9100). We want the initramfs to be generated after the kernel was
|
||||
# built, so we put the real initramfs on another partition (e.g. RECOVERY)
|
||||
|
|
|
@ -61,16 +61,21 @@ def list_flavors(args):
|
|||
|
||||
|
||||
def rootfs(args):
|
||||
method = args.flash_method or args.deviceinfo["flash_method"]
|
||||
|
||||
# Generate rootfs, install flasher
|
||||
img_path = "/home/pmos/rootfs/" + args.device + ".img"
|
||||
if not os.path.exists(args.work + "/chroot_native" + img_path):
|
||||
suffix = ".img"
|
||||
if pmb.config.flashers.get(method, {}).get("split", False):
|
||||
suffix = "-root.img"
|
||||
|
||||
img_path = args.work + "/chroot_native/home/pmos/rootfs/" + args.device + suffix
|
||||
if not os.path.exists(img_path):
|
||||
raise RuntimeError("The rootfs has not been generated yet, please run"
|
||||
" 'pmbootstrap install' first.")
|
||||
|
||||
# Do not flash if using fastboot & image is too large
|
||||
method = args.flash_method or args.deviceinfo["flash_method"]
|
||||
if method == "fastboot" and args.deviceinfo["flash_fastboot_max_size"]:
|
||||
img_size = os.path.getsize(args.work + "/chroot_native" + img_path) / 1024**2
|
||||
if method.startswith("fastboot") and args.deviceinfo["flash_fastboot_max_size"]:
|
||||
img_size = os.path.getsize(img_path) / 1024**2
|
||||
max_size = int(args.deviceinfo["flash_fastboot_max_size"])
|
||||
if img_size > max_size:
|
||||
raise RuntimeError("The rootfs is too large for fastboot to"
|
||||
|
|
|
@ -23,7 +23,7 @@ def variables(args, flavor, method):
|
|||
if "cmdline" in args and args.cmdline:
|
||||
_cmdline = args.cmdline
|
||||
|
||||
if method == "fastboot":
|
||||
if method.startswith("fastboot"):
|
||||
_partition_kernel = args.deviceinfo["flash_fastboot_partition_kernel"] or "boot"
|
||||
_partition_system = args.deviceinfo["flash_fastboot_partition_system"] or "system"
|
||||
else:
|
||||
|
@ -38,6 +38,8 @@ def variables(args, flavor, method):
|
|||
vars = {
|
||||
"$BOOT": "/mnt/rootfs_" + args.device + "/boot",
|
||||
"$FLAVOR": flavor if flavor is not None else "",
|
||||
"$IMAGE_SPLIT_BOOT": "/home/pmos/rootfs/" + args.device + "-boot.img",
|
||||
"$IMAGE_SPLIT_ROOT": "/home/pmos/rootfs/" + args.device + "-root.img",
|
||||
"$IMAGE": "/home/pmos/rootfs/" + args.device + ".img",
|
||||
"$KERNEL_CMDLINE": _cmdline,
|
||||
"$PARTITION_KERNEL": _partition_kernel,
|
||||
|
|
|
@ -195,6 +195,12 @@ def install(args):
|
|||
if args.rsync and not args.sdcard:
|
||||
raise ValueError("Installation using rsync only works on sdcard.")
|
||||
|
||||
if not args.sdcard and args.split is None:
|
||||
# Default to split if the flash method requires it
|
||||
flasher = pmb.config.flashers.get(args.deviceinfo["flash_method"], {})
|
||||
if flasher.get("split", False):
|
||||
args.split = True
|
||||
|
||||
pmb.install.install(args)
|
||||
|
||||
|
||||
|
|
|
@ -436,35 +436,47 @@ def install_system_image(args):
|
|||
" target device:")
|
||||
|
||||
# System flash information
|
||||
if not args.sdcard and not args.split:
|
||||
method = args.deviceinfo["flash_method"]
|
||||
flasher = pmb.config.flashers.get(method, {})
|
||||
flasher_actions = flasher.get("actions", {})
|
||||
requires_split = flasher.get("split", False)
|
||||
|
||||
if "flash_rootfs" in flasher_actions and not args.sdcard and \
|
||||
bool(args.split) == requires_split:
|
||||
logging.info("* pmbootstrap flasher flash_rootfs")
|
||||
logging.info(" Flashes the generated rootfs image to your device:")
|
||||
logging.info(" " + args.work + "/chroot_native/home/pmos/rootfs/" +
|
||||
args.device + ".img")
|
||||
logging.info(" (NOTE: This file has a partition table, which contains"
|
||||
" /boot and / subpartitions. That way we don't need to"
|
||||
" change the partition layout on your device.)")
|
||||
if args.split:
|
||||
logging.info(" " + args.work + "/chroot_native/home/pmos/rootfs/" +
|
||||
args.device + "-rootfs.img")
|
||||
else:
|
||||
logging.info(" " + args.work + "/chroot_native/home/pmos/rootfs/" +
|
||||
args.device + ".img")
|
||||
logging.info(" (NOTE: This file has a partition table, which contains"
|
||||
" /boot and / subpartitions. That way we don't need to"
|
||||
" change the partition layout on your device.)")
|
||||
|
||||
logging.info("* pmbootstrap flasher flash_kernel")
|
||||
logging.info(" Flashes the kernel + initramfs to your device:")
|
||||
logging.info(" " + args.work + "/chroot_rootfs_" + args.device +
|
||||
"/boot")
|
||||
method = args.deviceinfo["flash_method"]
|
||||
if (method in pmb.config.flashers and "boot" in
|
||||
pmb.config.flashers[method]["actions"]):
|
||||
# Most flash methods operate independently of the boot partition.
|
||||
# (e.g. an Android boot image is generated). In that case, "flash_kernel"
|
||||
# works even when partitions are split or installing for sdcard.
|
||||
# This is not possible if the flash method requires split partitions.
|
||||
if "flash_kernel" in flasher_actions and (not requires_split or args.split):
|
||||
logging.info("* pmbootstrap flasher flash_kernel")
|
||||
logging.info(" Flashes the kernel + initramfs to your device:")
|
||||
if requires_split:
|
||||
logging.info(" " + args.work + "/chroot_native/home/pmos/rootfs/" +
|
||||
args.device + "-boot.img")
|
||||
else:
|
||||
logging.info(" " + args.work + "/chroot_rootfs_" + args.device + "/boot")
|
||||
|
||||
if "boot" in flasher_actions:
|
||||
logging.info(" (NOTE: " + method + " also supports booting"
|
||||
" the kernel/initramfs directly without flashing."
|
||||
" Use 'pmbootstrap flasher boot' to do that.)")
|
||||
|
||||
# Export information
|
||||
if args.split:
|
||||
logging.info("* Boot and root image files have been generated, run"
|
||||
" 'pmbootstrap export' to create symlinks and flash"
|
||||
" outside of pmbootstrap.")
|
||||
else:
|
||||
logging.info("* If the above steps do not work, you can also create"
|
||||
" symlinks to the generated files with 'pmbootstrap export'"
|
||||
" and flash outside of pmbootstrap.")
|
||||
logging.info("* If the above steps do not work, you can also create"
|
||||
" symlinks to the generated files with 'pmbootstrap export'"
|
||||
" and flash outside of pmbootstrap.")
|
||||
|
||||
|
||||
def install_recovery_zip(args):
|
||||
|
|
|
@ -472,7 +472,11 @@ def arguments():
|
|||
group.add_argument("--sdcard", help="path to the sdcard device,"
|
||||
" eg. /dev/mmcblk0")
|
||||
group.add_argument("--split", help="install the boot and root partition"
|
||||
" in separated image files", action="store_true")
|
||||
" in separated image files (default: only if flash method"
|
||||
" requires it)", action="store_true", default=None)
|
||||
group.add_argument("--no-split", help="create combined boot + root image"
|
||||
" even if flash method requires it",
|
||||
dest="split", action="store_false")
|
||||
group.add_argument("--android-recovery-zip",
|
||||
help="generate TWRP flashable zip",
|
||||
action="store_true", dest="android_recovery_zip")
|
||||
|
|
Loading…
Reference in New Issue