2021-08-14 13:31:04 +02:00
import atexit
import shutil
2021-08-05 20:26:48 +02:00
import os
import subprocess
import click
2021-08-14 13:31:04 +02:00
import tempfile
2021-10-25 21:01:09 +02:00
from constants import FLASH_PARTS , LOCATIONS
2021-10-22 17:07:05 +02:00
from fastboot import fastboot_flash
2022-02-06 23:37:40 +01:00
from image import dd_image , partprobe , shrink_fs , losetup_rootfs_image , dump_aboot , dump_lk2nd , dump_qhypstub , get_device_and_flavour , get_image_name , get_image_path
2021-09-29 23:18:12 +02:00
from wrapper import enforce_wrap
2021-09-29 02:00:59 +02:00
2022-02-06 20:36:11 +01:00
ABOOT = FLASH_PARTS [ ' ABOOT ' ]
2021-09-29 02:00:59 +02:00
LK2ND = FLASH_PARTS [ ' LK2ND ' ]
QHYPSTUB = FLASH_PARTS [ ' QHYPSTUB ' ]
ROOTFS = FLASH_PARTS [ ' ROOTFS ' ]
2021-08-05 20:26:48 +02:00
2021-08-14 13:31:04 +02:00
2021-08-05 20:26:48 +02:00
@click.command ( name = ' flash ' )
2021-10-25 21:01:09 +02:00
@click.argument ( ' what ' , type = click . Choice ( list ( FLASH_PARTS . values ( ) ) ) )
2022-05-08 17:27:58 +02:00
@click.argument ( ' location ' , type = str , required = False )
def cmd_flash ( what : str , location : str ) :
""" Flash a partition onto a device. `location` takes either a path to a block device or one of emmc, sdcard """
2021-09-29 23:18:12 +02:00
enforce_wrap ( )
2021-08-05 20:26:48 +02:00
device , flavour = get_device_and_flavour ( )
2022-02-06 23:37:40 +01:00
device_image_name = get_image_name ( device , flavour )
device_image_path = get_image_path ( device , flavour )
2021-08-05 20:26:48 +02:00
2021-10-22 17:07:05 +02:00
# TODO: PARSE DEVICE SECTOR SIZE
sector_size = 4096
2021-09-29 02:00:59 +02:00
if what not in FLASH_PARTS . values ( ) :
raise Exception ( f ' Unknown what " { what } " , must be one of { " , " . join ( FLASH_PARTS . values ( ) ) } ' )
2021-08-05 20:26:48 +02:00
if what == ROOTFS :
2021-09-29 02:00:59 +02:00
if location is None :
raise Exception ( f ' You need to specify a location to flash { what } to ' )
2021-08-05 20:26:48 +02:00
2021-08-14 13:31:04 +02:00
path = ' '
2021-10-22 17:07:05 +02:00
if location . startswith ( " /dev/ " ) :
path = location
else :
if location not in LOCATIONS :
raise Exception ( f ' Invalid location { location } . Choose one of { " , " . join ( LOCATIONS ) } ' )
dir = ' /dev/disk/by-id '
for file in os . listdir ( dir ) :
sanitized_file = file . replace ( ' - ' , ' ' ) . replace ( ' _ ' , ' ' ) . lower ( )
if f ' jumpdrive { location . split ( " - " ) [ 0 ] } ' in sanitized_file :
path = os . path . realpath ( os . path . join ( dir , file ) )
2022-02-13 18:48:48 +01:00
partprobe ( path )
2021-10-22 17:07:05 +02:00
result = subprocess . run ( [ ' lsblk ' , path , ' -o ' , ' SIZE ' ] , capture_output = True )
if result . returncode != 0 :
raise Exception ( f ' Failed to lsblk { path } ' )
if result . stdout == b ' SIZE \n 0B \n ' :
raise Exception (
f ' Disk { path } has a size of 0B. That probably means it is not available (e.g. no microSD inserted or no microSD card slot installed in the device) or corrupt or defect '
)
if path == ' ' :
raise Exception ( ' Unable to discover Jumpdrive ' )
2021-08-14 13:31:04 +02:00
2021-10-25 21:01:09 +02:00
minimal_image_dir = tempfile . gettempdir ( )
minimal_image_path = os . path . join ( minimal_image_dir , f ' minimal- { device_image_name } ' )
2021-08-14 13:31:04 +02:00
def clean_dir ( ) :
2021-10-25 21:01:09 +02:00
shutil . rmtree ( minimal_image_dir )
2021-08-14 13:31:04 +02:00
atexit . register ( clean_dir )
2021-10-25 21:01:09 +02:00
shutil . copyfile ( device_image_path , minimal_image_path )
2021-08-14 13:31:04 +02:00
2021-10-22 17:07:05 +02:00
loop_device = losetup_rootfs_image ( minimal_image_path , sector_size )
2022-02-06 23:40:00 +01:00
partprobe ( loop_device )
2021-10-22 17:07:05 +02:00
shrink_fs ( loop_device , minimal_image_path , sector_size )
2022-02-06 23:37:40 +01:00
result = dd_image ( input = minimal_image_path , output = path )
2021-10-22 17:07:05 +02:00
if result . returncode != 0 :
raise Exception ( f ' Failed to flash { minimal_image_path } to { path } ' )
2021-08-05 20:26:48 +02:00
else :
2021-10-22 17:07:05 +02:00
loop_device = losetup_rootfs_image ( device_image_path , sector_size )
2022-02-06 20:36:11 +01:00
if what == ABOOT :
path = dump_aboot ( f ' { loop_device } p1 ' )
2021-10-22 17:07:05 +02:00
fastboot_flash ( ' boot ' , path )
elif what == LK2ND :
path = dump_lk2nd ( f ' { loop_device } p1 ' )
fastboot_flash ( ' lk2nd ' , path )
elif what == QHYPSTUB :
path = dump_qhypstub ( f ' { loop_device } p1 ' )
fastboot_flash ( ' qhypstub ' , path )
else :
raise Exception ( f ' Unknown what " { what } " , this must be a bug in kupferbootstrap! ' )