Several fixes

This commit is contained in:
Bjoern Kerler 2020-12-26 21:55:59 +01:00
parent 524b2639fe
commit 9565f48167
15 changed files with 233 additions and 264 deletions

View file

@ -76,7 +76,7 @@ msmids = {
0x000390E1: "MDM9350",
0x0003A0E1: "MDM9650",
0x0003B0E1: "MDM9655",
0x0007D0E1: "MDM9x60",
0x0007D0E1: "MDM9x60", #SDX20
0x0007F0E1: "MDM9x65",
0x008090E1: "MDM9916",
0x0080B0E1: "MDM9955",
@ -134,6 +134,7 @@ msmids = {
0x001350E1: "Lahaina", #0x600F0100 soc_hw_version #d40eee56f3194665574109a39267724ae7944134cd53cb767e293d3c40497955bc8a4519ff992b031fadc6355015ac87
0x000400E1: "Rennell", #d40eee56f3194665574109a39267724ae7944134cd53cb767e293d3c40497955bc8a4519ff992b031fadc6355015ac87
0x001060E1: "qm215", #7be49b72f9e4337223ccb84d6eccca4e61ce16e3602ac2008cb18b75babe6d09
0x200cf0E1: "SDX55M" # Netgear MR5100, sdxprairie
}
@ -255,7 +256,8 @@ infotbl = {
"SDX24M": [[0x300000, 0x3c000], [0x780000, 0x10000], []],
"SDX55:CD90-PG591": [[0x300000, 0x3c000], [0x780000, 0x10000], []],
"SDX55:CD90-PH809": [[0x300000, 0x3c000], [0x780000, 0x10000], []],
"SDX50M": [[0x100000, 0x18000], [0x000A0000, 0x6FFF], [0x200000, 0x24000]],
"SDX50M": [[0x300000, 0x3c000], [0x780000, 0x10000], []],
"SDX55M": [[0x300000, 0x3c000], [0x780000, 0x10000], []],
"SM6150": [[0x300000, 0x3c000], [0x780000, 0x10000], []],
"SM6150p": [[0x300000, 0x3c000], [0x780000, 0x10000], []],
"SM7150": [[0x300000, 0x3c000], [0x780000, 0x10000], []],
@ -351,9 +353,10 @@ secureboottbl = {
"SDM845": 0x00780350,
"SDX24" : 0x00780390,
"SDX24M": 0x00780390,
"SDX50M": 0x000a01e0,
"SDX50M": 0x007804D0,
"SDX55:CD90-PG591": 0x007805E8,
"SDX55:CD90-PH809": 0x007805E8,
"SDX55M" : 0x007804D0,
"SM6150": 0x00780360,
"SM6150p": 0x00780360,
"SM7150": 0x00780460,

View file

@ -5,11 +5,11 @@ SUBSYSTEMS=="usb", ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="9008", MODE="0666
# Qualcomm Memory Debug
SUBSYSTEMS=="usb", ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="9006", MODE="0666", GROUP="plugdev"
# Qualcomm Memory Debug
SUBSYSTEMS=="usb", ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="900E", MODE="0666", GROUP="plugdev"
# LG Memory Debug
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1004", ATTRS{idProduct}=="61a1", MODE="0666", GROUP="plugdev"
# Sierra Wireless
SUBSYSTEMS=="usb", ATTRS{idVendor}=="1199", ATTRS{idProduct}=="9071", MODE="0666", GROUP="plugdev"
# Netgear EDL
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0846", ATTRS{idProduct}=="68e0", MODE="0666", GROUP="plugdev"

View file

@ -2,10 +2,6 @@ try:
from Library.Modules.generic import generic
except Exception as e:
pass
try:
from Library.Modules.oneplus import oneplus
except Exception as e:
pass
class modules():
@ -23,11 +19,6 @@ class modules():
except Exception as e:
pass
self.ops = None
try:
self.ops = oneplus(fh=self.fh, projid=self.devicemodel, serial=self.serial,
supported_functions=self.supported_functions)
except Exception as e:
pass
def addpatch(self):
if self.ops is not None:

View file

@ -41,11 +41,12 @@ class firehose_client:
LOGGER.info(funcs)
self.target_name = self.firehose.cfg.TargetName
if "hwid" in dir(sahara):
hwid = sahara.hwid >> 32
if hwid in msmids:
self.target_name = msmids[hwid]
elif hwid in sochw:
self.target_name = sochw[hwid].split(",")[0]
if sahara.hwid is not None:
hwid = sahara.hwid >> 32
if hwid in msmids:
self.target_name = msmids[hwid]
elif hwid in sochw:
self.target_name = sochw[hwid].split(",")[0]
def check_cmd(self, func):
if not self.supported_functions:
@ -677,13 +678,13 @@ class firehose_client:
elif cmd == "modules":
if not self.check_param(["<command>", "<options>"]):
return False
command = options["<command>"]
options = options["<options>"]
mcommand = options["<command>"]
moptions = options["<options>"]
if self.firehose.modules is None:
self.LOGGER.error("Feature is not supported")
return False
else:
return self.firehose.modules.run(mainargs=options, command=command)
return self.firehose.modules.run(command=mcommand, args=moptions)
else:
self.LOGGER.error("Unknown/Missing command, a command is required.")
return False

View file

@ -4,6 +4,17 @@ from struct import unpack, pack
c_uint8 = ctypes.c_uint8
# nandbase MSM_NAND_BASE
# qfprom SECURITY_CONTROL_BASE_PHYS
config_tbl={
# bam nandbase bcraddr secureboot pbl qfprom memtbl
3: ["9x25",1,0xf9af0000,0xfc401a40,0xFC4B8000 + 0x6080,[0xFC010000, 0x18000],[0xFC4B8000, 0x6000], [0x200000, 0x24000]],
8: ["9x35",1,0xf9af0000,0xfc401a40,0xFC4B8000 + 0x6080,[0xFC010000, 0x18000],[0xFC4B8000, 0x6000], [0x200000, 0x24000]],
10: ["9x45",1,0x79B0000,0x183f000,0xFC4B8000 + 0x6080,[0xFC010000, 0x18000],[0x58000, 0x6000],[0x200000, 0x24000]],
16: ["9x55",0,0x79B0000,0x183F000,0x000a01d0,[0x100000, 0x18000],[0x000A0000, 0x6000],[0x200000, 0x24000]], #9x6x as well
12: ["9x07",0,0x79B0000,0x183F000,0x000a01d0,[0x100000, 0x18000],[0x000A0000, 0x6000],[0x200000, 0x24000]]
}
supported_flash = {
# Flash ID Density(MB) Wid Pgsz Blksz oobsz onenand Manuf */
0x2690ac2c: [(512 << 20), 0, 4096, (4096 << 6), 224, 0], # QUECTEL_NAND_FM6BD4G2GXA
@ -220,7 +231,6 @@ samsung_tbl = {
0xD5: [False, -1, 16384]
}
class SettingsOpt:
def __init__(self, parent, chipset, logger, verbose=False):
self.PAGESIZE = 4096
@ -255,74 +265,17 @@ class SettingsOpt:
self.BAD_BLOCK_BYTE_NUM = 0
self.BAD_BLOCK_IN_SPARE_AREA = 0
self.ECC_MODE = 0
if chipset <= 0:
self.bad_loader = 1
if chipset == 3:
self.name = "MDM9x25"
self.loader = "NPRG9x25p.bin"
self.eloader = "ENPRG9x25p.bin"
self.msmid = [0x07f1]
self.ctrl_type = 0
self.udflag = 1
self.nandbase = 0xf9af0000
self.bcraddr = 0xfc401a40
self.secureboot = 0xFC4B8000 + 0x6080
self.pbl = [0xFC010000, 0x18000]
self.qfprom = [0xFC4B8000, 0x6000] # SECURITY_CONTROL_BASE_PHYS
self.memtbl = [0x200000, 0x24000]
elif chipset == 8:
self.name = "MDM9x3X"
self.loader = "NPRG9x35p.bin"
self.eloader = "ENPRG9x35p.bin"
self.msmid = [0x0922]
self.ctrl_type = 0
self.udflag = 1
self.nandbase = 0xf9af0000 # MSM_NAND_BASE
self.bcraddr = 0xfc401a40
self.secureboot = 0xFC4B8000 + 0x6080
self.pbl = [0xFC010000, 0x18000]
self.qfprom = [0xFC4B8000, 0x6000]
self.memtbl = [0x200000, 0x24000]
elif chipset == 10:
self.name = "MDM9x4X"
self.loader = "NPRG9x45p.bin"
self.eloader = "ENPRG9x45p.bin"
self.msmid = [0x0950, 0x0951]
self.ctrl_type = 0
self.udflag = 1
self.nandbase = 0x79B0000
self.bcraddr = 0x183f000
self.secureboot = 0xFC4B8000 + 0x6080
self.pbl = [0xFC010000, 0x18000]
self.qfprom = [0x58000, 0x6000]
self.memtbl = [0x200000, 0x24000]
elif chipset == 11:
self.name = "MDM9x5X"
self.loader = "NPRG9x55p.bin"
self.eloader = "ENPRG9x55p.bin"
self.msmid = [0x0320, 0x03e0, 0x03a0]
self.ctrl_type = 0
self.udflag = 1
self.nandbase = 0x79B0000
self.bcraddr = 0x183F000
self.secureboot = 0x000a01d0
self.pbl = [0x100000, 0x18000]
self.qfprom = [0x000A0000, 0x6000]
self.memtbl = [0x200000, 0x24000]
elif chipset == 12:
self.name = "MDM9x07"
self.loader = "NPRG9x07p.bin"
self.eloader = "ENPRG9x07p.bin"
self.msmid = [0x0480, 0x4a0]
self.ctrl_type = 0
self.udflag = 1
self.nandbase = 0x79B0000
self.bcraddr = 0x183F000
self.secureboot = 0x000a01d0
self.pbl = [0x100000, 0x18000]
self.qfprom = [0x000A0000, 0x6000]
self.memtbl = [0x200000, 0x24000]
self.bad_loader = 1
if chipset in config_tbl:
self.chipname, self.bam, self.nandbase, self.bcraddr, self.secureboot, self.pbl, self.qfprom, self.memtbl=config_tbl[chipset]
self.bad_loader = 0
else:
for chipid in config_tbl:
loadername=parent.sahara.loader
if config_tbl[chipid][0] in loadername:
self.chipname, self.bam, self.nandbase, self.bcraddr, self.secureboot, self.pbl, self.qfprom, self.memtbl = \
config_tbl[chipset]
self.bad_loader = 0
class nand_toshiba_ids(ctypes.LittleEndianStructure):
_fields_ = [
@ -429,72 +382,50 @@ class NandDevice:
def __init__(self, settings):
self.settings = settings
if settings.ctrl_type == 0:
# device commands
self.NAND_CMD_SOFT_RESET = 0x01
self.NAND_CMD_PAGE_READ = 0x32
self.NAND_CMD_PAGE_READ_ECC = 0x33
self.NAND_CMD_PAGE_READ_ALL = 0x34
self.NAND_CMD_SEQ_PAGE_READ = 0x15
self.NAND_CMD_PRG_PAGE = 0x36
self.NAND_CMD_PRG_PAGE_ECC = 0x37
self.NAND_CMD_PRG_PAGE_ALL = 0x39
self.NAND_CMD_BLOCK_ERASE = 0x3A
self.NAND_CMD_FETCH_ID = 0x0B
self.NAND_CMD_STATUS = 0x0C
self.NAND_CMD_RESET = 0x0D
# device commands
self.NAND_CMD_SOFT_RESET = 0x01
self.NAND_CMD_PAGE_READ = 0x32
self.NAND_CMD_PAGE_READ_ECC = 0x33
self.NAND_CMD_PAGE_READ_ALL = 0x34
self.NAND_CMD_SEQ_PAGE_READ = 0x15
self.NAND_CMD_PRG_PAGE = 0x36
self.NAND_CMD_PRG_PAGE_ECC = 0x37
self.NAND_CMD_PRG_PAGE_ALL = 0x39
self.NAND_CMD_BLOCK_ERASE = 0x3A
self.NAND_CMD_FETCH_ID = 0x0B
self.NAND_CMD_STATUS = 0x0C
self.NAND_CMD_RESET = 0x0D
# addr offsets
self.NAND_FLASH_CMD = settings.nandbase + 0
self.NAND_ADDR0 = settings.nandbase + 4
self.NAND_ADDR1 = settings.nandbase + 8
self.NAND_FLASH_CHIP_SELECT = settings.nandbase + 0xc
self.NAND_EXEC_CMD = settings.nandbase + 0x10
self.NAND_FLASH_STATUS = settings.nandbase + 0x14
self.NAND_BUFFER_STATUS = settings.nandbase + 0x18
self.NAND_DEV0_CFG0 = settings.nandbase + 0x20
self.NAND_DEV0_CFG1 = settings.nandbase + 0x24
self.NAND_DEV0_ECC_CFG = settings.nandbase + 0x28
self.NAND_DEV1_ECC_CFG = settings.nandbase + 0x2C
self.NAND_DEV1_CFG0 = settings.nandbase + 0x30
self.NAND_DEV1_CFG1 = settings.nandbase + 0x34
self.NAND_SFLASHC_CMD = settings.nandbase + 0x38
self.NAND_SFLASHC_EXEC = settings.nandbase + 0x3C
self.NAND_READ_ID = settings.nandbase + 0x40
self.NAND_READ_STATUS = settings.nandbase + 0x44
self.NAND_CONFIG_DATA = settings.nandbase + 0x50
self.NAND_CONFIG = settings.nandbase + 0x54
self.NAND_CONFIG_MODE = settings.nandbase + 0x58
self.NAND_CONFIG_STATUS = settings.nandbase + 0x60
self.NAND_DEV_CMD0 = settings.nandbase + 0xA0
self.NAND_DEV_CMD1 = settings.nandbase + 0xA4
self.NAND_DEV_CMD2 = settings.nandbase + 0xA8
self.NAND_DEV_CMD_VLD = settings.nandbase + 0xAC
self.SFLASHC_BURST_CFG = settings.nandbase + 0xe0
self.NAND_EBI2_ECC_BUF_CFG = settings.nandbase + 0xF0
self.NAND_HW_INFO = settings.nandbase + 0xFC
self.NAND_FLASH_BUFFER = settings.nandbase + 0x100
elif settings.ctrl_type == 1:
self.NAND_CMD_SOFT_RESET = 0x07
self.NAND_CMD_PAGE_READ = 0x01
self.NAND_CMD_PAGE_READ_ALL = 0xffff
self.NAND_CMD_PRG_PAGE = 0x03
self.NAND_CMD_PRG_PAGE_ALL = 0xffff
self.NAND_CMD_BLOCK_ERASE = 0x04
self.NAND_CMD_FETCH_ID = 0x05
self.NAND_FLASH_CMD = settings.nandbase + 0x304
self.NAND_ADDR0 = settings.nandbase + 0x300
self.NAND_ADDR1 = settings.nandbase + 0xffff
self.NAND_FLASH_CHIP_SELECT = settings.nandbase + 0x30c
self.NAND_EXEC_CMD = settings.nandbase + 0xffff
self.NAND_BUFFER_STATUS = settings.nandbase + 0xffff
self.NAND_FLASH_STATUS = settings.nandbase + 0x308
self.NAND_DEV0_CFG0 = settings.nandbase + 0xffff
self.NAND_DEV0_CFG1 = settings.nandbase + 0x328
self.NAND_DEV0_ECC_CFG = settings.nandbase + 0xffff
self.NAND_READ_ID = settings.nandbase + 0x320
self.NAND_FLASH_BUFFER = settings.nandbase + 0x0
# addr offsets
self.NAND_FLASH_CMD = settings.nandbase + 0
self.NAND_ADDR0 = settings.nandbase + 4
self.NAND_ADDR1 = settings.nandbase + 8
self.NAND_FLASH_CHIP_SELECT = settings.nandbase + 0xc
self.NAND_EXEC_CMD = settings.nandbase + 0x10
self.NAND_FLASH_STATUS = settings.nandbase + 0x14
self.NAND_BUFFER_STATUS = settings.nandbase + 0x18
self.NAND_DEV0_CFG0 = settings.nandbase + 0x20
self.NAND_DEV0_CFG1 = settings.nandbase + 0x24
self.NAND_DEV0_ECC_CFG = settings.nandbase + 0x28
self.NAND_DEV1_ECC_CFG = settings.nandbase + 0x2C
self.NAND_DEV1_CFG0 = settings.nandbase + 0x30
self.NAND_DEV1_CFG1 = settings.nandbase + 0x34
self.NAND_SFLASHC_CMD = settings.nandbase + 0x38
self.NAND_SFLASHC_EXEC = settings.nandbase + 0x3C
self.NAND_READ_ID = settings.nandbase + 0x40
self.NAND_READ_STATUS = settings.nandbase + 0x44
self.NAND_CONFIG_DATA = settings.nandbase + 0x50
self.NAND_CONFIG = settings.nandbase + 0x54
self.NAND_CONFIG_MODE = settings.nandbase + 0x58
self.NAND_CONFIG_STATUS = settings.nandbase + 0x60
self.NAND_DEV_CMD0 = settings.nandbase + 0xA0
self.NAND_DEV_CMD1 = settings.nandbase + 0xA4
self.NAND_DEV_CMD2 = settings.nandbase + 0xA8
self.NAND_DEV_CMD_VLD = settings.nandbase + 0xAC
self.SFLASHC_BURST_CFG = settings.nandbase + 0xE0
self.NAND_EBI2_ECC_BUF_CFG = settings.nandbase + 0xF0
self.NAND_HW_INFO = settings.nandbase + 0xFC
self.NAND_FLASH_BUFFER = settings.nandbase + 0x100
self.PAGE_ACC = 1 << 4
self.LAST_PAGE = 1 << 5
@ -645,9 +576,10 @@ class NandDevice:
self.settings.ecc_bit = 8
elif pid == 0xEC: # Samsung
self.samsung_config(nandid)
elif pid == 0x2C:
elif pid == 0x2C: # Micron
self.generic_config(nandid, chipsize)
if nandid == 0x2690AC2C: # MT29AZ5A3CHHWD
# MT29AZ5A3CHHWD
if nandid == 0x2690AC2C or nandid == 0x26D0A32C:
self.settings.ecc_bit = 8
elif pid == 0x01:
self.generic_config(nandid, chipsize)

View file

@ -271,6 +271,7 @@ class qualcomm_sahara:
def __init__(self, cdc):
self.cdc = cdc
self.init_loader_db()
self.version=2.1
self.programmer = None
self.mode = ""
self.serial = None
@ -289,8 +290,10 @@ class qualcomm_sahara:
def get_rsp(self):
v = self.cdc.read()
if b"<?xml" in v:
if v==b'':
return [-1, -1]
if b"<?xml" in v:
return ["firehose", None]
pkt = read_object(v[0:0x2 * 0x4], self.pkt_cmd_hdr)
if pkt['cmd'] == self.cmd.SAHARA_HELLO_REQ:
data = read_object(v[0x0:0xC * 0x4], self.pkt_hello_req)
@ -341,10 +344,10 @@ class qualcomm_sahara:
if cmd['cmd'] == self.cmd.SAHARA_HELLO_REQ:
data = read_object(v[0x0:0xC * 0x4], self.pkt_hello_req)
self.pktsize = data['max_cmd_len']
self.version_min = data['version_min']
self.version = float(str(data['version'])+"."+str(data['version_min']))
return ["sahara", data]
elif v[0] == 0x04:
return ["sahara", v]
elif v[0] == self.cmd.SAHARA_END_TRANSFER:
return ["sahara", None]
elif b"<?xml" in v:
return ["firehose", None]
else:
@ -355,6 +358,9 @@ class qualcomm_sahara:
return ["nandprg", None]
elif b"<?xml" in res:
return ["firehose", None]
elif res[0] == self.cmd.SAHARA_END_TRANSFER:
print("Device is in Sahara error state, please reboot the device.")
return ["sahara", None]
else:
self.cmd_modeswitch(self.sahara_mode.SAHARA_MODE_COMMAND)
data = b"<?xml version=\"1.0\" ?><data><nop /></data>"
@ -377,6 +383,8 @@ class qualcomm_sahara:
return ["", None]
self.cmd_modeswitch(self.sahara_mode.SAHARA_MODE_MEMORY_DEBUG)
cmd, pkt = self.get_rsp()
if cmd==-1 and pkt==-1:
return ["",None]
return ["sahara", pkt]
def enter_command_mode(self):
@ -433,9 +441,10 @@ class qualcomm_sahara:
if self.enter_command_mode():
self.serial = self.cmdexec_get_serial_num()
self.serials = "{:08x}".format(self.serial)
self.sblversion = "{:08x}".format(self.cmdexec_get_sbl_version())
self.hwid = self.cmdexec_get_msm_hwid()
self.pkhash = self.cmdexec_get_pkhash()
if self.version>=2.4:
self.sblversion = "{:08x}".format(self.cmdexec_get_sbl_version())
if self.hwid is not None:
self.hwidstr = "{:016x}".format(self.hwid)
self.msm_id = int(self.hwidstr[0:8], 16)
@ -444,14 +453,21 @@ class qualcomm_sahara:
self.oem_str = "{:04x}".format(self.oem_id)
self.model_id = "{:04x}".format(self.model_id)
self.msm_str = "{:08x}".format(self.msm_id)
logger.info(f"\n------------------------\n" +
f"HWID: 0x{self.hwidstr} (MSM_ID:0x{self.msm_str}," +
f"OEM_ID:0x{self.oem_str}," +
f"MODEL_ID:0x{self.model_id})\n" +
f"PK_HASH: 0x{self.pkhash}\n" +
f"Serial: 0x{self.serials}\n" +
f"SBL Version: 0x{self.sblversion}\n")
if self.version >= 2.4:
logger.info(f"\n------------------------\n" +
f"HWID: 0x{self.hwidstr} (MSM_ID:0x{self.msm_str}," +
f"OEM_ID:0x{self.oem_str}," +
f"MODEL_ID:0x{self.model_id})\n" +
f"PK_HASH: 0x{self.pkhash}\n" +
f"Serial: 0x{self.serials}\n" +
f"SBL Version: 0x{self.sblversion}\n")
else:
logger.info(f"\n------------------------\n" +
f"HWID: 0x{self.hwidstr} (MSM_ID:0x{self.msm_str}," +
f"OEM_ID:0x{self.oem_str}," +
f"MODEL_ID:0x{self.model_id})\n" +
f"PK_HASH: 0x{self.pkhash}\n" +
f"Serial: 0x{self.serials}\n")
if self.programmer == "":
fname = ""
if self.hwidstr in self.loaderdb:
@ -479,11 +495,14 @@ class qualcomm_sahara:
break
# print("Couldn't find a loader for given hwid and pkhash :(")
# exit(0)
else:
elif self.hwidstr!=None and self.pkhash!=None:
logger.error(
f"Couldn't find a loader for given hwid and pkhash ({self.hwidstr}_{self.pkhash[0:16]}" +
"_[FHPRG/ENPRG].bin) :(")
exit(0)
return False
else:
logger.error(f"Couldn't find a suitable loader :(")
return False
self.programmer = fname
self.cmd_modeswitch(self.sahara_mode.SAHARA_MODE_COMMAND)
@ -499,16 +518,17 @@ class qualcomm_sahara:
return False
def cmd_done(self):
self.cdc.write(struct.pack("<II", self.cmd.SAHARA_DONE_REQ, 0x8))
cmd, pkt = self.get_rsp()
time.sleep(0.3)
if cmd["cmd"] == self.cmd.SAHARA_DONE_RSP:
if self.cdc.write(struct.pack("<II", self.cmd.SAHARA_DONE_REQ, 0x8)):
cmd, pkt = self.get_rsp()
time.sleep(0.3)
if cmd["cmd"] == self.cmd.SAHARA_DONE_RSP:
return True
elif cmd["cmd"] == self.cmd.SAHARA_END_TRANSFER:
if pkt["status"] == self.status.SAHARA_NAK_INVALID_CMD:
logger.error("Invalid Transfer command received.")
return False
return True
elif cmd["cmd"] == self.cmd.SAHARA_END_TRANSFER:
if pkt["status"] == self.status.SAHARA_NAK_INVALID_CMD:
logger.error("Invalid Transfer command received.")
return False
return True
return False
def cmd_reset(self):
self.cdc.write(struct.pack("<II", self.cmd.SAHARA_RESET_REQ, 0x8))

View file

@ -15,7 +15,6 @@ class QualcommStreaming:
self.flashinfo = None
self.bbtbl = {}
self.nanddevice = None
self.ctrl_type = 0
self.nandbase = 0
def get_flash_config(self):
@ -31,10 +30,12 @@ class QualcommStreaming:
self.nandwait()
dev_cfg0 = self.regs.NAND_DEV0_CFG0
dev_cfg1 = self.regs.NAND_DEV0_CFG1
dev_cfg1_0 = self.regs.NAND_DEV1_CFG0
dev_cfg1_1 = self.regs.NAND_DEV1_CFG1
dev_ecc_cfg = self.regs.NAND_DEV0_ECC_CFG
dev_ecc1_cfg = self.regs.NAND_DEV1_ECC_CFG
#dev_ecc1_cfg = self.regs.NAND_DEV1_ECC_CFG
#dev_cfg1_0 = self.regs.NAND_DEV1_CFG0
#dev_cfg1_1 = self.regs.NAND_DEV1_CFG1
"""
self.nand_reset()
self.set_address(1, 0)
@ -108,10 +109,10 @@ class QualcommStreaming:
# increase the codeword size by the OOB chunk size per sector˰
self.settings.cwsize += self.settings.OOBSIZE // self.settings.sectors_per_page
self.regs.NAND_DEV0_ECC_CFG = (
self.regs.NAND_DEV0_ECC_CFG & 0xfffffffe) | self.settings.args_disable_ecc # ECC on/off
self.regs.NAND_DEV0_CFG1 = (
self.regs.NAND_DEV0_CFG1 & 0xfffffffe) | self.settings.args_disable_ecc # ECC on/off
# ECC on/off
self.regs.NAND_DEV0_ECC_CFG = (self.regs.NAND_DEV0_ECC_CFG & 0xfffffffe) | self.settings.args_disable_ecc
# ECC on/off
self.regs.NAND_DEV0_CFG1 = (self.regs.NAND_DEV0_CFG1 & 0xfffffffe) | self.settings.args_disable_ecc
self.regs.NAND_FLASH_CMD = self.nanddevice.NAND_CMD_SOFT_RESET # Resetting all controller operations
self.regs.NAND_EXEC_CMD = 0x1
self.nandwait()
@ -257,33 +258,20 @@ class QualcommStreaming:
return True
def nandwait(self):
if self.settings.ctrl_type == 0:
while True:
if self.regs.NAND_FLASH_STATUS & 0xF == 0:
break
else:
while True:
if self.regs.NAND_FLASH_STATUS & 0x3 == 0:
break
while True:
if self.regs.NAND_FLASH_STATUS & 0xF == 0:
break
def set_address(self, block, page):
address = (block * self.settings.num_pages_per_blk) + page
if self.settings.ctrl_type == 0: # MDM
self.regs.NAND_ADDR0 = address << 16
self.regs.NAND_ADDR1 = (address >> 16) & 0xFF
# self.regs.NAND_FLASH_CHIP_SELECT = 0 | 4 # flash0 + undoc bit
else: # MSM
self.regs.NAND_ADDR0 = address << 8
self.regs.NAND_FLASH_CHIP_SELECT = 0 | 4 # flash0 + undoc bit
self.regs.NAND_ADDR0 = address << 16
self.regs.NAND_ADDR1 = (address >> 16) & 0xFF
# self.regs.NAND_FLASH_CHIP_SELECT = 0 | 4 # flash0 + undoc bit
def exec_nand(self, cmd):
if self.settings.ctrl_type == 0: # MDM
self.regs.NAND_FLASH_CMD = cmd
self.regs.NAND_EXEC_CMD = 1
self.nandwait()
else: # MSM
self.regs.NAND_FLASH_CMD = cmd
self.nandwait()
self.regs.NAND_FLASH_CMD = cmd
self.regs.NAND_EXEC_CMD = 1
self.nandwait()
def nand_reset(self):
self.exec_nand(1)
@ -412,36 +400,34 @@ class QualcommStreaming:
return buffer, spare
self.nand_reset()
if self.settings.ctrl_type == 0:
if self.settings.ECC_MODE == 1:
if cwsize >= self.settings.sectorsize + 4:
self.regs.NAND_FLASH_CMD = self.nanddevice.NAND_CMD_PAGE_READ_ALL
else:
self.regs.NAND_FLASH_CMD = self.nanddevice.NAND_CMD_PAGE_READ_ECC
else:
if self.settings.ECC_MODE == 1:
if cwsize >= self.settings.sectorsize + 4:
self.regs.NAND_FLASH_CMD = self.nanddevice.NAND_CMD_PAGE_READ_ALL
else:
self.regs.NAND_FLASH_CMD = self.nanddevice.NAND_CMD_PAGE_READ_ECC
else:
self.regs.NAND_FLASH_CMD = self.nanddevice.NAND_CMD_PAGE_READ_ALL
self.bch_reset()
if self.settings.ctrl_type == 0:
self.set_address(block, page)
bad_ecc = False
for sector in range(0, sectors):
self.regs.NAND_EXEC_CMD = 0x1
self.nandwait()
ecc_status = self.check_ecc_status()
if ecc_status == -1:
bad_ecc = True
tmp = self.memread(self.nanddevice.NAND_FLASH_BUFFER, cwsize)
size = self.settings.UD_SIZE_BYTES
if cursize + size > self.settings.PAGESIZE:
size = cursize + size - self.settings.PAGESIZE
buffer.extend(tmp[:-size])
spare.extend(tmp[-size:])
else:
buffer.extend(tmp)
cursize += size
if bad_ecc:
logger.debug("ECC error at : Block %08X Page %08X" % (block, page))
self.set_address(block, page)
bad_ecc = False
for sector in range(0, sectors):
self.regs.NAND_EXEC_CMD = 0x1
self.nandwait()
ecc_status = self.check_ecc_status()
if ecc_status == -1:
bad_ecc = True
tmp = self.memread(self.nanddevice.NAND_FLASH_BUFFER, cwsize)
size = self.settings.UD_SIZE_BYTES
if cursize + size > self.settings.PAGESIZE:
size = cursize + size - self.settings.PAGESIZE
buffer.extend(tmp[:-size])
spare.extend(tmp[-size:])
else:
buffer.extend(tmp)
cursize += size
if bad_ecc:
logger.debug("ECC error at : Block %08X Page %08X" % (block, page))
if self.settings.bad_processing_flag == BadFlags.BAD_DISABLE.value:
self.hardware_bad_off()
@ -521,13 +507,14 @@ class QualcommStreaming:
self.regs.NAND_DEV0_CFG0 = oldcfg
def disable_bam(self):
nandcstate = []
nandcstate = {}
for i in range(0, 0xec, 4):
nandcstate.append(self.mempeek(self.nanddevice.NAND_FLASH_CMD + i))
value=self.mempeek(self.nanddevice.NAND_FLASH_CMD + i)
nandcstate[i]=value
self.mempoke(self.settings.bcraddr, 1)
self.mempoke(self.settings.bcraddr, 0)
for i in range(len(nandcstate)):
addr = self.nanddevice.NAND_FLASH_CMD + (i * 4)
for i in nandcstate:
addr = self.nanddevice.NAND_FLASH_CMD + i
value = nandcstate[i]
self.mempoke(addr, value)
self.regs.NAND_EXEC_CMD = 1
@ -620,6 +607,10 @@ class QualcommStreaming:
info = b"\x01QCOM fast download protocol host\x03\x23\x23\x23\x20"
resp = self.send(info, True)
if b"Unrecognized flash device" in resp:
logging.error("Unrecognized flash device, patch loader !")
self.reset()
return False
resp = bytearray(resp)
if resp[1] != 2:
resp = self.send(info, True)
@ -633,16 +624,28 @@ class QualcommStreaming:
chipset = self.identify_chipset()
self.settings = SettingsOpt(self, chipset, logger, False)
if self.settings.bad_loader:
logging.error("Loader id doesn't match device, please fix config and patch loader. Rebooting.")
self.reset()
return False
self.nanddevice = NandDevice(self.settings)
self.setupregs()
if self.settings.sahara:
if self.cdc.pid == 0x900e:
print("Boot to 0x9008")
self.mempoke(0x193d100, 1)
self.mempeek(0x7980000)
self.cdc.close()
sys.exit(0)
if self.settings.bam:
self.disable_bam() # only for sahara
self.get_flash_config()
cfg0 = self.mempeek(self.nanddevice.NAND_DEV0_CFG0)
sectorsize = (cfg0 & (0x3ff << 9)) >> 9
sparebytes = (cfg0 >> 23) & 0xf
logging.info("HELLO protocol version: %i" % resp[0x22])
logging.info("Chipset: %s" % self.settings.name)
logging.info("Chipset: %s" % self.settings.chipname)
logging.info("Base address of the NAND controller: %08x" % self.settings.nandbase)
val = resp[0x2d:0x2d + infolen].decode('utf-8') if resp[0x2d] != 0x65 else ""
logging.info("Flash memory: %s %s, %s" % (self.settings.flash_mfr, val, self.settings.flash_descr))
@ -779,7 +782,6 @@ class QualcommStreaming:
def test_nand_config():
class sahara:
mode = None
qs = QualcommStreaming(None, sahara())
qs.settings = SettingsOpt(qs, 8, logger)
qs.nanddevice = NandDevice(qs.settings)
@ -802,7 +804,9 @@ def test_nand_config():
[0x9580f1c2, 8, 128, 2048, 131072, 64, 4, 0x2a0408c0, 0x0804745c, 0x00000203, 0x42040700, 0x000001d1],
[0x9580f1c2, 8, 128, 2048, 131072, 64, 4, 0x2a0408c0, 0x0804745c, 0x00000203, 0x42040700, 0x000001d1],
[0x9590dac2, 8, 256, 2048, 131072, 64, 4, 0x2a0408c0, 0x0804745c, 0x00000203, 0x42040700, 0x000001d1],
[0x1590ac01, 8, 512, 2048, 128, 64, 4, 0x2a0408c0, 0x0804745c, 0x00000203, 0x42040700, 0x000001d1]
[0x1590ac01, 8, 512, 2048, 128, 64, 4, 0x2a0408c0, 0x0804745c, 0x00000203, 0x42040700, 0x000001d1],
# Netgear MR5100
[0x26d0a32c, 8, 1024, 4096, 262144, 256, 8, 0x290409c0, 0x08045d5c, 0x00000203, 0x42040d10, 0x00000175],
]
errorids = []
for test in testconfig:
@ -810,15 +814,19 @@ def test_nand_config():
res_cfg0, res_cfg1, res_ecc_buf_cfg, res_ecc_bch_cfg = qs.nanddevice.nand_setup(nandid)
if cfg0 != res_cfg0 or cfg1 != res_cfg1 or eccbufcfg != res_ecc_buf_cfg or res_ecc_bch_cfg != bccbchcfg:
errorids.append(nandid)
res_cfg0, res_cfg1, res_ecc_buf_cfg, res_ecc_bch_cfg = qs.nanddevice.nand_setup(nandid)
if len(errorids) > 0:
st = ""
for id in errorids:
st += hex(id) + ","
st = st[:-1]
print("Error at: "+st)
assert ("Error at : " + st)
else:
print("Yay, all nand_config tests are ok !!!!")
if __name__ == "__main__":
print("Running nand config tests...")
test_nand_config()

View file

@ -254,8 +254,7 @@ class usb_class:
return bytearray(tmp)
elif e.errno is not None:
print(repr(e), type(e), e.errno)
self.connect()
raise e
sys.exit(0)
else:
break
self.log.verify_data(bytearray(tmp), "RX:")

Binary file not shown.

Binary file not shown.

View file

@ -40,7 +40,7 @@ or
### Generic
- "./edl.py -h" -> to see help with all options
- "./edl.py server --memory=ufs --tcpport=1340" -> Run TCP/IP server on port 1340, see Examples/tcpclient.py for an example client
- "./edl.py server --memory=ufs --tcpport=1340" -> Run TCP/IP server on port 1340, see tcpclient.py for an example client
- "./edl.py xml run.xml" -> To send a xml file run.xml via firehose
- "./edl.py reset" -> To reboot the phone
- "./edl.py rawxml <xmlstring>' -> To send own xml string, example :
@ -97,6 +97,7 @@ or
- "./edl.py pbl pbl.bin" -> To dump pbl (only on EL3 loaders)
- "./edl.py qfp qfp.bin" -> To dump qfprom fuses (only on EL3 loaders)
### For generic unlocking
- "./edl.py modules oemunlock enable" -> Unlocks OEM if partition "config" exists, fastboot oem unlock is still needed afterwards
@ -108,10 +109,15 @@ or
#### Sierra Wireless Modem
- Send AT!BOOTHOLD and AT!QPSTDLOAD to modem port or use ./boottodwnload.py script
- Send AT!ENTERCND="A710" and then AT!EROPTION=0 for memory dump
- "./edl.py --vid 1199 --pid 9070 --loader=Loaders/qualcomm/patched/NPRG9x35p.bin printgpt" -> To show the partition table
- "./edl.py --vid 1199 --pid 9070 --loader=loaders/NPRG9x35p.bin printgpt" -> To show the partition table
#### Netgear MR1100
- run modem/netgear_boottodownload.py, device will enter download mode (0x900E pid)
- "./edl.py printgpt --loader=Loaders/qualcomm/patched/mdm9x5x/NPRG9x55p.bin", device will reboot to 0x9008
- now use ./edl.py regulary such as "./edl.py printgpt" (do not use loader option)
#### ZTE MF920V
- Send to at port "AT+ZCDRUN=E", or run "./diag.py -sahara"
- run modem/zte_enable_adb.sh, or send to at port "AT+ZCDRUN=E", or send via diag.py "4b650100"
- "adb reboot edl"
- "./edl.py printgpt" -> To show the partition table
@ -148,12 +154,13 @@ For Oneplus 6T, enter *#801#* on dialpad, set Engineer Mode and Serial to on and
## Issues
- Secure loader with SDM660 on Xiaomi (EDL auth) and Oppo (VIP Programming) not yet supported
- EFS directory write and file read has to be added
- Secure loader with SDM660 on Xiaomi not yet supported (EDL authentification)
- VIP Programming not supported (Contributions are welcome !)
- EFS directory write and file read has to be added (Contributions are welcome !)
## Tested with
- Oneplus 3T/5/6T/7T/8/8t/N10/N100 (Read-Only), BQ X, BQ X5, BQ X2, Gigaset ME Pure, ZTE MF210, ZTE MF920V, Sierra Wireless EM7455, Quectel EC25
- Oneplus 3T/5/6T/7T/8/8t/N10/N100 (Read-Only), BQ X, BQ X5, BQ X2, Gigaset ME Pure, ZTE MF210, ZTE MF920V, Sierra Wireless EM7455, Netgear MR1100-10EUS, Netgear MR5100
Published under MIT license
Additional license limitations: No use in commercial products without prior permit.

15
edl.py
View file

@ -233,6 +233,8 @@ def parse_cmd(args):
cmd = "reset"
elif args["nop"]:
cmd = "nop"
elif args["modules"]:
cmd = "modules"
return cmd
def main():
@ -241,7 +243,7 @@ def main():
loop = 0
vid = int(args["--vid"], 16)
pid = int(args["--pid"], 16)
usbids = [[vid, pid], [0x05c6, 0x9025], [0x1199, 0x9062], [0x1199, 0x9070], [0x1199, 0x9090], [0x0846, 0x68e0]]
usbids = [[vid, pid], [0x05c6,0x9008], [0x05c6,0x900e] , [0x05c6, 0x9025], [0x1199, 0x9062], [0x1199, 0x9070], [0x1199, 0x9090], [0x0846, 0x68e0]]
filename = "log.txt"
if args["--debugmode"]:
LOGGER = log_class(logging.DEBUG, filename)
@ -273,7 +275,12 @@ def main():
sys.exit()
# print((mode, resp))
if mode == "sahara":
if "mode" in resp:
if resp==None:
if mode=="sahara":
print("Sahara in error state, resetting ...")
sahara.cmd_reset()
exit(cdc)
elif "mode" in resp:
mode = resp["mode"]
if mode == sahara.sahara_mode.SAHARA_MODE_MEMORY_DEBUG:
if args["memorydump"]:
@ -293,9 +300,9 @@ def main():
mode = "load_enandprg"
elif "nprg" in sahara.programmer.lower():
mode = "load_nandprg"
else:
elif mode!="":
mode = "load_" + mode
if mode != "load_":
if "load_" in mode:
time.sleep(0.3)
else:
print("Error, couldn't find suitable enprg/nprg loader :(")

View file

@ -3,6 +3,8 @@
# (c) B.Kerler 2020 under MIT license
# If you use my code, make sure you refer to my name
# If you want to use in a commercial product, ask me before integrating it
import time
from telnetlib import Telnet
def sendcmd(tn,cmd):
tn.write(bytes(cmd,'utf-8')+b"\n")
@ -10,13 +12,12 @@ def sendcmd(tn,cmd):
return tn.read_eager().strip().decode('utf-8')
def main():
from telnetlib import Telnet
tn = Telnet("localhost", 5510)
print("Sending download mode command to localhost:5510")
tn = Telnet("192.168.1.1", 5510)
print("Sending download mode command to 192.168.1.1:5510")
print(sendcmd(tn,"AT!BOOTHOLD\r"))
print(sendcmd(tn,'AT!QPSTDLOAD\r'))
print("Done switching to download mode")
tn.close()
if __name__=="__main__":
main()
main()