mirror of
https://github.com/bkerler/mtkclient.git
synced 2024-11-14 19:25:05 -05:00
Fix reset/shutdown
This commit is contained in:
parent
537c8c76bc
commit
727ae63298
5 changed files with 128 additions and 27 deletions
32
mtk
32
mtk
|
@ -20,6 +20,7 @@ cmds = {
|
|||
"wo": "Write flash starting at offset from filename",
|
||||
"e": "Erase partition",
|
||||
"es": "Erase partition with sector count",
|
||||
"ess": "Erase sector with sector count",
|
||||
"footer": "Read crypto footer from flash",
|
||||
"reset": "Send mtk reset command",
|
||||
"dumpbrom": "Try to dump the bootrom",
|
||||
|
@ -72,6 +73,7 @@ if __name__ == '__main__':
|
|||
parser_wo = subparsers.add_parser("wo", help="Write flash starting at offset from filename")
|
||||
parser_e = subparsers.add_parser("e", help="Erase partition")
|
||||
parser_es = subparsers.add_parser("es", help="Erase partition with sector count")
|
||||
parser_ess = subparsers.add_parser("ess", help="Erase sector with sector count")
|
||||
parser_footer = subparsers.add_parser("footer", help="Read crypto footer from flash")
|
||||
parser_reset = subparsers.add_parser("reset", help="Send mtk reset command")
|
||||
|
||||
|
@ -536,6 +538,36 @@ if __name__ == '__main__':
|
|||
parser_es.add_argument('--crash', help='Enforce crash if device is in pl mode to enter brom mode')
|
||||
parser_es.add_argument('--socid', help='Read Soc ID')
|
||||
|
||||
parser_ess.add_argument('startsector', help='Startsector to erase')
|
||||
parser_ess.add_argument('sectors', help='Sectors to erase')
|
||||
parser_ess.add_argument('--loader', type=str, help='Use specific DA loader, disable autodetection')
|
||||
parser_ess.add_argument('--vid', type=str, help='Set usb vendor id used for MTK Preloader')
|
||||
parser_ess.add_argument('--pid', type=str, help='Set usb product id used for MTK Preloader')
|
||||
parser_ess.add_argument('--sectorsize', default='0x200', help='Set default sector size')
|
||||
parser_ess.add_argument('--debugmode', action='store_true', default=False, help='Enable verbose mode')
|
||||
parser_ess.add_argument('--gpt-num-part-entries', default='0', help='Set GPT entry count')
|
||||
parser_ess.add_argument('--gpt-part-entry-size', default='0', help='Set GPT entry size')
|
||||
parser_ess.add_argument('--gpt-part-entry-start-lba', default='0', help='Set GPT entry start lba sector')
|
||||
parser_ess.add_argument('--gpt_file', help='Use a gpt file instead of trying to read gpt from flash')
|
||||
parser_ess.add_argument('--skip', help='Skip reading partition with names "partname1,partname2,etc."')
|
||||
parser_ess.add_argument('--skipwdt', help='Skip wdt init')
|
||||
parser_ess.add_argument('--wdt', help='Set a specific watchdog addr')
|
||||
parser_ess.add_argument('--mode', help='Set a crash mode (0=dasend1,1=dasend2,2=daread)')
|
||||
parser_ess.add_argument('--var1', help='Set kamakiri specific var1 value')
|
||||
parser_ess.add_argument('--uart_addr', help='Set payload uart_addr value')
|
||||
parser_ess.add_argument('--da_addr', help='Set a specific da payload addr')
|
||||
parser_ess.add_argument('--brom_addr', help='Set a specific brom payload addr')
|
||||
parser_ess.add_argument('--ptype',
|
||||
help='Set the payload type ( "amonet","kamakiri","kamakiri2","carbonara" kamakiri2/da used by default)')
|
||||
parser_ess.add_argument('--preloader', help='Set the preloader filename for dram config')
|
||||
parser_ess.add_argument('--verifystage2', help='Verify if stage2 data has been written correctly')
|
||||
parser_ess.add_argument('--parttype', help='Partition type\n' +
|
||||
'\t\tEMMC: [user, boot1, boot2, gp1, gp2, gp3, gp4, rpmb]' +
|
||||
'\t\tUFS: [lu0, lu1, lu2, lu0_lu1]')
|
||||
parser_ess.add_argument('--filename', help='Optional filename')
|
||||
parser_ess.add_argument('--crash', help='Enforce crash if device is in pl mode to enter brom mode')
|
||||
parser_ess.add_argument('--socid', help='Read Soc ID')
|
||||
|
||||
parser_footer.add_argument('filename', help='Filename to store footer')
|
||||
parser_footer.add_argument('--loader', type=str, help='Use specific DA loader, disable autodetection')
|
||||
parser_footer.add_argument('--vid', type=str, help='Set usb vendor id used for MTK Preloader')
|
||||
|
|
|
@ -435,6 +435,37 @@ class DA_handler(metaclass=LogBase):
|
|||
elif countFP != len(partitions) and countFP > 1:
|
||||
print(f"Failed to format all partitions.")
|
||||
|
||||
def da_ess(self, sector: int, sectors: int, parttype: str):
|
||||
if parttype == "user" or parttype is None:
|
||||
wipedata = b"\x00" * 0x200000
|
||||
error = False
|
||||
while sectors:
|
||||
sectorsize = sectors * self.mtk.daloader.daconfig.pagesize
|
||||
wsize = min(sectorsize, 0x200000)
|
||||
if self.mtk.daloader.writeflash(addr=sector * self.mtk.daloader.daconfig.pagesize,
|
||||
length=wsize,
|
||||
filename=None,
|
||||
wdata=wipedata[:wsize],
|
||||
parttype="user"):
|
||||
print(
|
||||
f"Failed to format sector {str(sector)} with " +
|
||||
f"sector count {str(sectors)}.")
|
||||
error = True
|
||||
break
|
||||
sectors -= (wsize // self.mtk.daloader.daconfig.pagesize)
|
||||
sector += (wsize // self.mtk.daloader.daconfig.pagesize)
|
||||
if not error:
|
||||
print(
|
||||
f"Formatted sector {str(sector)} with sector count {str(sectors)}.")
|
||||
else:
|
||||
pos = 0
|
||||
self.mtk.daloader.formatflash(addr=sector * self.mtk.daloader.daconfig.pagesize,
|
||||
length=min(sectors*self.mtk.daloader.daconfig.pagesize,0xF000000),
|
||||
partitionname=None,
|
||||
parttype=parttype,
|
||||
display=True)
|
||||
print(f"Formatted sector {str(pos // 0x200)}")
|
||||
|
||||
def da_es(self, partitions: list, parttype: str, sectors: int):
|
||||
if parttype == "user" or parttype is None:
|
||||
i = 0
|
||||
|
@ -478,7 +509,8 @@ class DA_handler(metaclass=LogBase):
|
|||
else:
|
||||
pos = 0
|
||||
for partitionname in partitions:
|
||||
self.mtk.daloader.formatflash(addr=pos, length=0xF000000, partitionname=partitionname,
|
||||
self.mtk.daloader.formatflash(addr=pos, length=min(sectors * self.mtk.daloader.daconfig.pagesize,0xF000000),
|
||||
partitionname=partitionname,
|
||||
parttype=parttype,
|
||||
display=True)
|
||||
print(f"Formatted sector {str(pos // 0x200)}")
|
||||
|
@ -648,11 +680,19 @@ class DA_handler(metaclass=LogBase):
|
|||
self.close()
|
||||
partitions = partitionname.split(",")
|
||||
self.da_es(partitions=partitions, parttype=parttype, sectors=sectors)
|
||||
elif cmd == "ess":
|
||||
sector = args.startsector
|
||||
parttype = args.parttype
|
||||
sectors = getint(args.sectors)
|
||||
if args.sectors is None:
|
||||
self.error("Sector count is missing. Usage: ess [sector] [sector count]")
|
||||
self.close()
|
||||
self.da_ess(sector=sector, parttype=parttype, sectors=sectors)
|
||||
elif cmd == "reset":
|
||||
if os.path.exists(".state"):
|
||||
os.remove(".state")
|
||||
os.remove(os.path.join("logs", "hwparam.json"))
|
||||
mtk.daloader.close()
|
||||
mtk.daloader.shutdown(bootmode=0)
|
||||
print("Reset command was sent. Disconnect usb cable to power off.")
|
||||
elif cmd == "da":
|
||||
subcmd = args.subcmd
|
||||
|
|
|
@ -957,11 +957,11 @@ class DALegacy(metaclass=LogBase):
|
|||
m_ext_ram_size = unpack(">Q", self.usbread(8))[0] # 0x80000000
|
||||
self.info(f"M_EXT_RAM_SIZE : {hex(m_ext_ram_size)}")
|
||||
if self.daconfig.emiver in [0x0D]:
|
||||
self.usbread(4) # 00000003
|
||||
Raw_0 = self.usbread(4) # 1C004004
|
||||
Raw_1 = self.usbread(4) # aa080033
|
||||
CJ_0 = self.usbread(4) # 00000013
|
||||
CJ_1 = self.usbread(4) # 00000010
|
||||
self.usbread(4) # 00000003
|
||||
Raw_0 = self.usbread(4) # 1C004004
|
||||
Raw_1 = self.usbread(4) # aa080033
|
||||
CJ_0 = self.usbread(4) # 00000013
|
||||
CJ_1 = self.usbread(4) # 00000010
|
||||
else:
|
||||
self.error("Preloader needed due to dram config.")
|
||||
self.mtk.port.close(reset=True)
|
||||
|
@ -1112,8 +1112,13 @@ class DALegacy(metaclass=LogBase):
|
|||
return True
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
self.finish(0x0) # DISCONNECT_USB_AND_RELEASE_POWERKEY
|
||||
class ShutDownModes:
|
||||
NORMAL = 0
|
||||
HOME_SCREEN = 1
|
||||
FASTBOOT = 2
|
||||
|
||||
def shutdown(self, async_mode: int = 0, dl_bit: int = 0, bootmode: ShutDownModes = ShutDownModes.NORMAL):
|
||||
self.finish(bootmode) # DISCONNECT_USB_AND_RELEASE_POWERKEY
|
||||
self.mtk.port.close(reset=True)
|
||||
|
||||
def brom_send(self, dasetup, dadata, stage, packetsize=0x1000):
|
||||
|
|
|
@ -16,6 +16,7 @@ from mtkclient.Library.xflash_ext import xflashext
|
|||
from mtkclient.Library.legacy_ext import legacyext
|
||||
from mtkclient.Library.settings import hwparam
|
||||
|
||||
|
||||
class DAloader(metaclass=LogBase):
|
||||
def __init__(self, mtk, loglevel=logging.INFO):
|
||||
self.__logger = logsetup(self, self.__logger, loglevel, mtk.config.gui)
|
||||
|
@ -41,7 +42,7 @@ class DAloader(metaclass=LogBase):
|
|||
|
||||
def writestate(self):
|
||||
config = {}
|
||||
config["xflash"] = self.mtk.config.chipconfig.damode==damodes.XFLASH
|
||||
config["xflash"] = self.mtk.config.chipconfig.damode == damodes.XFLASH
|
||||
config["hwcode"] = self.config.hwcode
|
||||
if self.config.meid is not None:
|
||||
config["meid"] = hexlify(self.config.meid).decode('utf-8')
|
||||
|
@ -49,7 +50,7 @@ class DAloader(metaclass=LogBase):
|
|||
config["socid"] = hexlify(self.config.socid).decode('utf-8')
|
||||
config["flashtype"] = self.daconfig.flashtype
|
||||
config["flashsize"] = self.daconfig.flashsize
|
||||
if not self.mtk.config.chipconfig.damode==damodes.XFLASH:
|
||||
if not self.mtk.config.chipconfig.damode == damodes.XFLASH:
|
||||
config["m_emmc_ua_size"] = self.da.emmc.m_emmc_ua_size
|
||||
config["m_emmc_boot1_size"] = self.da.emmc.m_emmc_boot1_size
|
||||
config["m_emmc_boot2_size"] = self.da.emmc.m_emmc_boot2_size
|
||||
|
@ -61,7 +62,7 @@ class DAloader(metaclass=LogBase):
|
|||
open(".state", "w").write(json.dumps(config))
|
||||
|
||||
def compute_hash_pos(self, da1, da2, da2sig_len):
|
||||
hashlen = len(da2)-da2sig_len
|
||||
hashlen = len(da2) - da2sig_len
|
||||
|
||||
hashmode, idx = self.calc_da_hash(da1, da2[:hashlen])
|
||||
if idx == -1:
|
||||
|
@ -118,7 +119,7 @@ class DAloader(metaclass=LogBase):
|
|||
self.da.nand = nandinfo64()
|
||||
self.da.emmc = emmcinfo(self.config)
|
||||
self.da.sdc = sdcinfo(self.config)
|
||||
self.lft=legacyext(self.mtk, self.da, self.loglevel)
|
||||
self.lft = legacyext(self.mtk, self.da, self.loglevel)
|
||||
self.da.emmc.m_emmc_ua_size = config["m_emmc_ua_size"]
|
||||
self.da.emmc.m_emmc_boot1_size = config["m_emmc_boot1_size"]
|
||||
self.da.emmc.m_emmc_boot2_size = config["m_emmc_boot2_size"]
|
||||
|
@ -152,7 +153,7 @@ class DAloader(metaclass=LogBase):
|
|||
self.xflash = True
|
||||
if self.xflash:
|
||||
self.da = DAXFlash(self.mtk, self.daconfig, self.loglevel)
|
||||
if porttype not in ["off","usb","uart"]:
|
||||
if porttype not in ["off", "usb", "uart"]:
|
||||
self.error("Only \"off\",\"usb\" or \"uart\" are allowed.")
|
||||
if self.da.set_meta(porttype):
|
||||
self.info(f"Successfully set meta mode to {porttype}")
|
||||
|
@ -192,8 +193,13 @@ class DAloader(metaclass=LogBase):
|
|||
def upload(self):
|
||||
return self.da.upload()
|
||||
|
||||
def close(self):
|
||||
return self.da.close()
|
||||
class ShutDownModes:
|
||||
NORMAL = 0
|
||||
HOME_SCREEN = 1
|
||||
FASTBOOT = 2
|
||||
|
||||
def shutdown(self, bootmode=ShutDownModes.NORMAL):
|
||||
return self.da.shutdown(async_mode=0, dl_bit=0, bootmode=bootmode)
|
||||
|
||||
def upload_da(self, preloader=None):
|
||||
self.daconfig.setup()
|
||||
|
@ -213,12 +219,12 @@ class DAloader(metaclass=LogBase):
|
|||
|
||||
def get_packet_length(self):
|
||||
if self.xflash:
|
||||
pt=self.da.get_packet_length()
|
||||
pt = self.da.get_packet_length()
|
||||
return pt.read_packet_length
|
||||
else:
|
||||
return 512
|
||||
|
||||
def peek(self, addr: int, length:int):
|
||||
def peek(self, addr: int, length: int):
|
||||
if self.xflash:
|
||||
return self.xft.custom_read(addr=addr, length=length)
|
||||
else:
|
||||
|
@ -261,4 +267,4 @@ class DAloader(metaclass=LogBase):
|
|||
if self.xflash:
|
||||
return self.xft.erase_rpmb()
|
||||
self.error("Device is not in xflash mode, cannot run erase rpmb cmd.")
|
||||
return False
|
||||
return False
|
||||
|
|
|
@ -174,7 +174,7 @@ class DAXFlash(metaclass=LogBase):
|
|||
except:
|
||||
return -1
|
||||
|
||||
def xsend(self, data, datatype=DataType.DT_PROTOCOL_FLOW, is64bit:bool = False):
|
||||
def xsend(self, data, datatype=DataType.DT_PROTOCOL_FLOW, is64bit: bool = False):
|
||||
if isinstance(data, int):
|
||||
if is64bit:
|
||||
data = pack("<Q", data)
|
||||
|
@ -515,8 +515,9 @@ class DAXFlash(metaclass=LogBase):
|
|||
|
||||
chipid = Chipid
|
||||
data = self.send_devctrl(self.Cmd.GET_CHIP_ID)
|
||||
chipid.hw_code, chipid.hw_sub_code, chipid.hw_version, chipid.sw_version, chipid.chip_evolution = unpack("<HHHHH",
|
||||
data[:(5 * 2)])
|
||||
chipid.hw_code, chipid.hw_sub_code, chipid.hw_version, chipid.sw_version, chipid.chip_evolution = unpack(
|
||||
"<HHHHH",
|
||||
data[:(5 * 2)])
|
||||
status = self.status()
|
||||
if status == 0:
|
||||
self.info("HW-CODE : 0x%X", chipid.hw_code)
|
||||
|
@ -778,6 +779,7 @@ class DAXFlash(metaclass=LogBase):
|
|||
if resp != b"":
|
||||
status = self.status()
|
||||
if status == 0:
|
||||
# full-speed, high-speed, hyper-speed
|
||||
return resp
|
||||
else:
|
||||
self.error(f"Error on getting usb speed: {self.eh.status(status)}")
|
||||
|
@ -889,15 +891,31 @@ class DAXFlash(metaclass=LogBase):
|
|||
return buffer
|
||||
return False
|
||||
|
||||
def close(self):
|
||||
class ShutDownModes:
|
||||
NORMAL = 0
|
||||
HOME_SCREEN = 1
|
||||
FASTBOOT = 2
|
||||
|
||||
def shutdown(self, async_mode: int = 0, dl_bit: int = 0, bootmode: ShutDownModes = ShutDownModes.NORMAL):
|
||||
if self.xsend(self.Cmd.SHUTDOWN):
|
||||
status = self.status()
|
||||
if status == 0:
|
||||
self.mtk.port.close(reset=True)
|
||||
return True
|
||||
hasflags = 0
|
||||
# bootmode 0: shutdown 1: home screen, 2: fastboot
|
||||
if async_mode or dl_bit or bootmode > 0:
|
||||
hasflags = 1
|
||||
enablewdt = 0 # Disable wdt
|
||||
dont_resetrtc = 0 # Reset RTC
|
||||
leaveusb = 0 # Disconnect usb
|
||||
if self.xsend(pack("<IIIIIIII", hasflags, enablewdt, async_mode, bootmode, dl_bit,
|
||||
dont_resetrtc, leaveusb, 0)):
|
||||
status = self.status()
|
||||
if status == 0:
|
||||
self.mtk.port.close(reset=True)
|
||||
return True
|
||||
else:
|
||||
self.error(f"Error on sending shutdown: {self.eh.status(status)}")
|
||||
self.mtk.port.close(True)
|
||||
self.mtk.port.close(reset=True)
|
||||
return False
|
||||
|
||||
def getstorage(self, parttype, length):
|
||||
|
@ -1031,7 +1049,7 @@ class DAXFlash(metaclass=LogBase):
|
|||
|
||||
hashaddr, hashmode, hashlen = self.mtk.daloader.compute_hash_pos(da1, da2, da2sig_len)
|
||||
if hashaddr is not None:
|
||||
#da1 = self.xft.patch_da1(da1)
|
||||
# da1 = self.xft.patch_da1(da1)
|
||||
da2 = self.xft.patch_da2(da2)
|
||||
da1 = self.mtk.daloader.fix_hash(da1, da2, hashaddr, hashmode, hashlen)
|
||||
self.patch = True
|
||||
|
|
Loading…
Reference in a new issue