UPLOAD
This commit is contained in:
parent
a31b37d3d2
commit
ded84b9cd5
77
mstar-bin-tool/README.md
Normal file
77
mstar-bin-tool/README.md
Normal file
@ -0,0 +1,77 @@
|
||||
# mstar-bin-tool
|
||||
|
||||
Command line tools to pack/unpack MStar bin firmware
|
||||
|
||||
Currently available tools:
|
||||
- **unpack.py** - unpack MStar bin firmware
|
||||
- **pack.py** - pack MStar bin firmware
|
||||
- **extract_keys.py** - extract AES and RSA-public keys from MBOOT binary
|
||||
- **secure_partition.py** - encrypt image and generate signature file
|
||||
|
||||
|
||||
## Unpack MStar bin firmware files
|
||||
|
||||
```
|
||||
Usage: unpack.py <firmware> <output folder [default: ./unpacked/]>
|
||||
<firmware> - MStar bin firmware to unpack
|
||||
<output folder> - directory to store unpacked stuff. Default value: ./unpacked/
|
||||
```
|
||||
|
||||
|
||||
## Pack MStar bin firmware
|
||||
```
|
||||
Usage: pack.py <config file>
|
||||
Example: pack.py configs/letv-x355pro-full.ini
|
||||
<config file> - Configuration file. The config file structure will be described later.
|
||||
For now you can take a look at configs/letv-x355pro-full.ini
|
||||
and use it as an example
|
||||
```
|
||||
|
||||
|
||||
## Extract keys from MBOOT
|
||||
That tool is used to get AES and public RSA keys from the MBOOT. AES keys are needed to encrypt/decrypt
|
||||
boot.img and recovery.img images. aescrypt2 tool is used.
|
||||
|
||||
```
|
||||
Usage: extract_keys.py <path to mboot> [<folder to store keys>] [<key bank offset>] [<key bank size>]
|
||||
Defaults:
|
||||
<folder to store keys> keys
|
||||
<key bank offset> 0x168e00
|
||||
<key bank size> 0x450
|
||||
Example: extract_keys.py ./unpacked/MBOOT.img
|
||||
Example: extract_keys.py ./unpacked/MBOOT.img ./keys 0x169e00 0x450
|
||||
```
|
||||
|
||||
## Encrypt/Decrypt partition
|
||||
You can encrypt/decrypt partition with using *aescrypt2.exe* tool, which is located in bin/win32 folder
|
||||
|
||||
Default mstar key is *hex:0007FF4154534D92FC55AA0FFF0110E0* All mstar default keys are in default_keys folder. (These keys are in public access in github)
|
||||
|
||||
Last parameter can be hex value or path to AES key. If your vendor is using custom aes keys you can use extract_keys.py to extract them.
|
||||
|
||||
To encrypt image use:
|
||||
```
|
||||
aescrypt2 0 boot.img boot.img.aes hex:0007FF4154534D92FC55AA0FFF0110E0
|
||||
or
|
||||
aescrypt2 0 boot.img boot.img.aes keys/AESBootKey
|
||||
```
|
||||
|
||||
So to decrypt image use:
|
||||
```
|
||||
aescrypt2 1 boot.img.aes boot.img hex:0007FF4154534D92FC55AA0FFF0110E0
|
||||
or
|
||||
aescrypt2 1 boot.img boot.img.aes keys/AESBootKey
|
||||
```
|
||||
|
||||
## Encrypt partition and generate signature
|
||||
All new MStar builds have SECURE_BOOT option enabled. In that case
|
||||
boot.img and recovery.img is encrypted (AES) and signed with RSA priv keys.
|
||||
That script is used to encrypt image and generate sign file.
|
||||
|
||||
To manually encrypt|decrypt image use aescrypt2 tool from bin folder.
|
||||
AES key can be extracted from MBOOT with extract_keys.py script.
|
||||
|
||||
```
|
||||
Usage: secure_partition.py <file to encrypt> <AES key file> <RSA private key file> <RSA public key file> <output encrypted file> <output signature file>
|
||||
Example: secure_partition.py ./pack/boot.img ./keys/AESbootKey ./keys/RSAboot_priv.txt ./keys/RSAboot_pub.txt ./pack/boot.img.aes ./pack/bootSign
|
||||
```
|
||||
BIN
mstar-bin-tool/__pycache__/utils.cpython-37.pyc
Normal file
BIN
mstar-bin-tool/__pycache__/utils.cpython-37.pyc
Normal file
Binary file not shown.
BIN
mstar-bin-tool/bin/win32/SubSecureInfoGen.exe
Normal file
BIN
mstar-bin-tool/bin/win32/SubSecureInfoGen.exe
Normal file
Binary file not shown.
BIN
mstar-bin-tool/bin/win32/aescrypt2.exe
Normal file
BIN
mstar-bin-tool/bin/win32/aescrypt2.exe
Normal file
Binary file not shown.
BIN
mstar-bin-tool/bin/win32/alignment.exe
Normal file
BIN
mstar-bin-tool/bin/win32/alignment.exe
Normal file
Binary file not shown.
BIN
mstar-bin-tool/bin/win32/lzop.exe
Normal file
BIN
mstar-bin-tool/bin/win32/lzop.exe
Normal file
Binary file not shown.
BIN
mstar-bin-tool/bin/win32/rsa_sign.exe
Normal file
BIN
mstar-bin-tool/bin/win32/rsa_sign.exe
Normal file
Binary file not shown.
28
mstar-bin-tool/configs/LETV_USB_SCRIPT_938.ini
Normal file
28
mstar-bin-tool/configs/LETV_USB_SCRIPT_938.ini
Normal file
@ -0,0 +1,28 @@
|
||||
#
|
||||
# LeEco X3-50+ (6a928), Super4 (6a938)
|
||||
# Enable UART and set the tv to stand by mode to allow normal bin file flashing
|
||||
#
|
||||
# NB! Rename generated file to LETV_USB_SCRIPT_928 if you have LeEco X3-50+ (6a928)
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=LETV_USB_SCRIPT_938
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=false
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=${FirmwareFileName}
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
|
||||
|
||||
Suffix:
|
||||
|
||||
# Enable UART
|
||||
setenv ForcePowerOn 0
|
||||
setenv UARTOnOff on
|
||||
saveenv
|
||||
reset
|
||||
32
mstar-bin-tool/configs/dexp-madison-system.ini
Normal file
32
mstar-bin-tool/configs/dexp-madison-system.ini
Normal file
@ -0,0 +1,32 @@
|
||||
#
|
||||
# Dexp H32B8200K F40B8300K F49B8200K F55B8200K TVs
|
||||
# Config file to pack a single partition to firmware file (system.img)
|
||||
# This will not create the partition, just erase and rewrite it
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=MadisonUpgrade.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=false
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=${FirmwareFileName}
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
dont_overwrite_init
|
||||
|
||||
Suffix:
|
||||
setenv MstarUpgrade_complete 1
|
||||
setenv ResetAfterUpgrade 1
|
||||
setenv ForcePowerOn 0
|
||||
saveenv
|
||||
|
||||
[part/system]
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/system.img
|
||||
type=partitionImage
|
||||
lzo=True
|
||||
chunkSize=150MB
|
||||
31
mstar-bin-tool/configs/empty-skip-example.ini
Normal file
31
mstar-bin-tool/configs/empty-skip-example.ini
Normal file
@ -0,0 +1,31 @@
|
||||
#
|
||||
# Example of using emptySkip param. It is non-required param
|
||||
# By default emptySkip is set to False for sboot partition type and True for any other partitions
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=LetvUpgrade938.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=true
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=$$(UpgradeImage)
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
|
||||
Suffix:
|
||||
setenv MstarUpgrade_complete 1
|
||||
setenv ResetAfterUpgrade 1
|
||||
setenv ForcePowerOn 0
|
||||
saveenv
|
||||
|
||||
[part/system]
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/system.img
|
||||
type=partitionImage
|
||||
lzo=True
|
||||
chunkSize=50MB
|
||||
emptySkip=False
|
||||
38
mstar-bin-tool/configs/letv-emmc2usb.ini
Normal file
38
mstar-bin-tool/configs/letv-emmc2usb.ini
Normal file
@ -0,0 +1,38 @@
|
||||
#
|
||||
# All MBOOT models
|
||||
# Simple config file which contains mboot commands to start backuping whole emmc content to usb drive
|
||||
# Flash it as usual bin firmware. Instead of flashing it will backup emmc data to usb drive
|
||||
# Change output filename according your needs
|
||||
#
|
||||
|
||||
[Main]
|
||||
#FirmwareFileName=LetvUpgrade928.bin
|
||||
FirmwareFileName=LetvUpgrade938.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=false
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=${FirmwareFileName}
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
|
||||
# uncomment next line if your emmc > 4GB
|
||||
# that will clone whlole emmc to usb drive (similar to dd command in linux)
|
||||
# 0 - is the usb port number. In my case it's usb2.0 port on right side of the TV
|
||||
#mmc dd mmc2usb 0
|
||||
|
||||
# uncomment next line if your emmc <= 4GB
|
||||
# that will generate boot1.bin boot2.bin and emmc.bin in the root folder of the usb drive
|
||||
# 0 - is the usb port number. In my case it's usb2.0 port on right side of the TV
|
||||
# emmcbin 0
|
||||
|
||||
# let mboot know we are done to allow normal boot
|
||||
setenv LetvUpgrade_complete 1
|
||||
setenv ForcePowerOn 0
|
||||
saveenv
|
||||
|
||||
Suffix:
|
||||
# Nothig here
|
||||
25
mstar-bin-tool/configs/letv-enable-uart.ini
Normal file
25
mstar-bin-tool/configs/letv-enable-uart.ini
Normal file
@ -0,0 +1,25 @@
|
||||
#
|
||||
# LeEco X3-50+ (6a928), Super4 (6a938)
|
||||
# Enable UART
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=enable_uart
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=false
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=${FirmwareFileName}
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
|
||||
|
||||
Suffix:
|
||||
|
||||
# Enable UART
|
||||
setenv UARTOnOff on
|
||||
saveenv
|
||||
reset
|
||||
23
mstar-bin-tool/configs/letv-force-bin-update.ini
Normal file
23
mstar-bin-tool/configs/letv-force-bin-update.ini
Normal file
@ -0,0 +1,23 @@
|
||||
#
|
||||
# LeEco X3-50+ (6a928), Super4 (6a938)
|
||||
# Force flash bin firmware
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=force_flash_bin_firmware
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=false
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=${FirmwareFileName}
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
|
||||
|
||||
Suffix:
|
||||
|
||||
# Start flashing
|
||||
custar
|
||||
43
mstar-bin-tool/configs/letv-x340-43-recovery-no-secure.ini
Normal file
43
mstar-bin-tool/configs/letv-x340-43-recovery-no-secure.ini
Normal file
@ -0,0 +1,43 @@
|
||||
#
|
||||
# LeEco X3-40 X3-43
|
||||
# Config file to pack a single partition to firmware file (recovery.img)
|
||||
#
|
||||
# This will NOT create the partition, just erase and rewrite it
|
||||
# NO security info (signature) will be added to the bin !
|
||||
# Security checking for recovery will be DISABLED
|
||||
# Use it to flash plain non encrypted recovery.img
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=LetvUpgrade.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=false
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=${FirmwareFileName}
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
# Nothing here
|
||||
|
||||
Suffix:
|
||||
|
||||
# Enable UART
|
||||
setenv UARTOnOff on
|
||||
|
||||
# No auth for the recovery
|
||||
setenv recoverycmd mmc read.p 0x25000000 recovery 0x00800000\; bootm 0x25000000
|
||||
|
||||
|
||||
# Done
|
||||
setenv LetvUpgrade_complete 1
|
||||
setenv ResetAfterUpgrade 1
|
||||
setenv ForcePowerOn 0
|
||||
saveenv
|
||||
|
||||
[part/recovery]
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/recovery.img
|
||||
type=partitionImage
|
||||
210
mstar-bin-tool/configs/letv-x355pro-full.ini
Normal file
210
mstar-bin-tool/configs/letv-x355pro-full.ini
Normal file
@ -0,0 +1,210 @@
|
||||
#
|
||||
# LeEco X3-55pro (Super3 x55 Pro) packer configuration file
|
||||
# The TV is based on mst6a928 cpu
|
||||
#
|
||||
|
||||
[Main]
|
||||
|
||||
# Output file name
|
||||
FirmwareFileName=LetvUpgrade928.bin
|
||||
|
||||
# Folder which contains images to pack
|
||||
ProjectFolder=./pack
|
||||
|
||||
# Use hex values in "mmc write.p" directive.
|
||||
# Check your unpacked ~header_script file for the "mmc write.p" paramers.
|
||||
# Set it to True, if the paramers have "0x" prefix.
|
||||
# All newest Mstar firwares uses hex values
|
||||
useHexValuesPrefix=false
|
||||
|
||||
# Firmware file name to use in "filepartload" directive.
|
||||
# All newest Mstar firwares uses $(UpgradeImage) Otherwise it should be equal FirmwareFileName value.
|
||||
SCRIPT_FIRMWARE_FILE_NAME=${FirmwareFileName}
|
||||
|
||||
# DRAM_BUF_ADDR value
|
||||
DRAM_BUF_ADDR=20200000
|
||||
|
||||
# Magic footer value. It's reserved for future use, usually it's "12345678" string
|
||||
MAGIC_FOOTER=12345678
|
||||
|
||||
# Header size is always 16KB
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
|
||||
# Custom header script directives at the beginning of the script
|
||||
Prefix:
|
||||
mmc slc 0 1
|
||||
mmc rmgpt
|
||||
factory_init factory 0x02000000
|
||||
|
||||
# Custom directives at the end of the script
|
||||
Suffix:
|
||||
cleanallenv
|
||||
setenv filesize 6748c0
|
||||
setenv LOAD_KERNEL mmc read.p 0x25000000 boot 0x01000000\; authenticateAN 0x25000000
|
||||
setenv filesize 6748c0
|
||||
setenv BOOT_KERNEL bootm 0x25000000
|
||||
setenv recoverycmd mmc read.p 0x25000000 recovery 0x02000000\; authenticateAN 0x25000000\; bootm 0x25000000
|
||||
setenv LOAD_NUTTX mmc read.p 0x5EC70000 tee 0x600000
|
||||
setenv BOOT_NUTTX bootNuttx 0x1EC70000
|
||||
setenv CMA_REG0 CMA0=mali0,miu=0,hid=16,sz=0x1F000000
|
||||
setenv CMA_REG1 CMA1=mali1,miu=1,hid=17,sz=0x5400000
|
||||
setenv CMA_REG2 CMA2=VDEC1,miu=1,hid=19,sz=0xCC00000,st=0x6C00000
|
||||
setenv bootargs console=ttyS0,115200 androidboot.console=ttyS0 root=/dev/ram rw rootwait init=/init CORE_DUMP_PATH=/data/Logs/Log.0/core_dump.%%p.gz KDebug=1 delaylogo=True androidboot.selinux=permissive $(CMA_REG0) $(CMA_REG1) $(CMA_REG2) PM51_ADDR=0x20010000 PM51_LEN=0x10000 DRAM_LEN=0xC0000000 BOOTLOGO_IN_MBOOT ENV_VAR_OFFSET=0x0 ENV_VAR_SIZE=0x10000 ENV=EMMC SECURITY=ON
|
||||
setenv bootlogo_gopidx 3
|
||||
setenv bootlogo_buffer E_MMAP_ID_PHOTO_INTER
|
||||
setenv str_crc 1
|
||||
setenv db_table 0
|
||||
setenv verify n
|
||||
setenv bootcmd $(LOAD_KERNEL)\; $(LOAD_NUTTX)\; $(BOOT_NUTTX)\; $(BOOT_KERNEL)
|
||||
setenv ForcePowerOn 1
|
||||
setenv factory_poweron_mode secondary
|
||||
setenv sync_mmap 1
|
||||
setenv detect_mmap 1
|
||||
saveenv
|
||||
setenv LetvUpgrade_complete 1
|
||||
setenv factory_mode 0
|
||||
setenv ResetAfterUpgrade 1
|
||||
setenv ForcePowerOn 1
|
||||
setenv db_table 0
|
||||
saveenv
|
||||
printenv
|
||||
|
||||
# List of partitions to pack
|
||||
# [partition_name] - Name of partition. Shold begin with "part/"
|
||||
# create - flag to generate "mmc create" directive. It requires "size" parameter
|
||||
# size - Required parameter, if create flag sets to True. Partition size to create [hex]
|
||||
# erase - flag to generate "mmc erase.p" directive.
|
||||
# imageFile - Path to image file to pack
|
||||
# type - partition type:
|
||||
# partitionImage - Plain partition image. It generates "filepartload" and "mmc write.p" directives
|
||||
# secureInfo - signature file. Uses "store_secure_info" directive
|
||||
# nuttxConfig - Nuttx config file. Uses "store_nuttx_config" directive
|
||||
# lzo - pack partition/chunk to lzo. Uses "mmc unlzo" directive
|
||||
# chunkSize - chunk size to split partition. A single chunk uses, if chunkSize is not set. Units: B, KB, MB, GB
|
||||
|
||||
[part/MPOOL]
|
||||
# Signatures (secureInfo) stored in that partition, so it should be erased before writing secure info.
|
||||
# We erase it very first
|
||||
erase=True
|
||||
|
||||
[part/ipanic]
|
||||
create=True
|
||||
size=0x00200000
|
||||
|
||||
[part/misc]
|
||||
create=True
|
||||
size=0x00080000
|
||||
erase=True
|
||||
|
||||
[part/reserved]
|
||||
create=True
|
||||
size=0x02000000
|
||||
|
||||
[part/recovery]
|
||||
create=True
|
||||
size=0x02000000
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/recovery.img
|
||||
type=partitionImage
|
||||
|
||||
[part/recoverySign]
|
||||
imageFile=${Main:ProjectFolder}/recoverySign
|
||||
type=secureInfo
|
||||
|
||||
[part/boot]
|
||||
create=True
|
||||
size=0x01000000
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/boot.img
|
||||
type=partitionImage
|
||||
|
||||
[part/bootSign]
|
||||
imageFile=${Main:ProjectFolder}/bootSign
|
||||
type=secureInfo
|
||||
|
||||
[part/tee]
|
||||
create=True
|
||||
size=0x01000000
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/tee.img
|
||||
type=partitionImage
|
||||
|
||||
[part/teeSign]
|
||||
imageFile=${Main:ProjectFolder}/teeSign
|
||||
type=secureInfo
|
||||
|
||||
[part/NuttxConfig]
|
||||
imageFile=${Main:ProjectFolder}/NuttxConfig
|
||||
type=nuttxConfig
|
||||
|
||||
[part/RTPM]
|
||||
create=True
|
||||
size=0x00040000
|
||||
erase=True
|
||||
imageFile=pack/RTPM.img
|
||||
type=partitionImage
|
||||
|
||||
[part/system]
|
||||
create=True
|
||||
size=0x60000000
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/system.img
|
||||
type=partitionImage
|
||||
lzo=True
|
||||
chunkSize=150MB
|
||||
|
||||
[part/cache]
|
||||
create=True
|
||||
size=0x60000000
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/cache.img
|
||||
type=partitionImage
|
||||
lzo=True
|
||||
|
||||
[part/tvservice]
|
||||
create=True
|
||||
size=0x09600000
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/tvservice.img
|
||||
type=partitionImage
|
||||
|
||||
[part/tvconfig]
|
||||
create=True
|
||||
size=0x06400000
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/tvconfig.img
|
||||
type=partitionImage
|
||||
|
||||
[part/tvdatabase]
|
||||
create=True
|
||||
size=0x02000000
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/tvdatabase.img
|
||||
type=partitionImage
|
||||
|
||||
[part/tvcustomer]
|
||||
create=True
|
||||
size=0x01000000
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/tvcustomer.img
|
||||
type=partitionImage
|
||||
|
||||
[part/userdata]
|
||||
create=True
|
||||
size=0x320D3F000 variable:0x1000000,0x64D93E000,0x2A9B3F000,0xD7C3F800
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/userdata.img
|
||||
type=partitionImage
|
||||
lzo=True
|
||||
chunkSize=150MB
|
||||
|
||||
[part/sboot]
|
||||
imageFile=${Main:ProjectFolder}/sboot.img
|
||||
type=sboot
|
||||
|
||||
[part/MBOOT]
|
||||
imageFile=${Main:ProjectFolder}/MBOOT.img
|
||||
type=partitionImage
|
||||
|
||||
43
mstar-bin-tool/configs/letv-x355pro-recovery-no-secure.ini
Normal file
43
mstar-bin-tool/configs/letv-x355pro-recovery-no-secure.ini
Normal file
@ -0,0 +1,43 @@
|
||||
#
|
||||
# LeEco X3-55pro (Super3 x55 Pro)
|
||||
# Config file to pack a single partition to firmware file (recovery.img)
|
||||
#
|
||||
# This will NOT create the partition, just erase and rewrite it
|
||||
# NO security info (signature) will be added to the bin !
|
||||
# Security checking for recovery will be DISABLED
|
||||
# Use it to flash plain non encrypted recovery.img
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=LetvUpgrade928.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=false
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=${FirmwareFileName}
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
dont_overwrite_init
|
||||
|
||||
Suffix:
|
||||
|
||||
# Enable UART
|
||||
setenv UARTOnOff on
|
||||
|
||||
# No auth for the recovery
|
||||
setenv recoverycmd mmc read.p 0x25000000 recovery 0x02000000\; bootm 0x25000000
|
||||
|
||||
|
||||
# Done
|
||||
setenv LetvUpgrade_complete 1
|
||||
setenv ResetAfterUpgrade 1
|
||||
setenv ForcePowerOn 0
|
||||
saveenv
|
||||
|
||||
[part/recovery]
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/recovery.img
|
||||
type=partitionImage
|
||||
46
mstar-bin-tool/configs/letv-x355pro-recovery.ini
Normal file
46
mstar-bin-tool/configs/letv-x355pro-recovery.ini
Normal file
@ -0,0 +1,46 @@
|
||||
#
|
||||
# LeEco X3-55pro (Super3 x55 Pro)
|
||||
# Config file to pack a single partition to firmware file (recovery.img)
|
||||
# This will not create the partition, just erase and rewrite it
|
||||
# Also security info (signature) will be added to the bin
|
||||
# You have to generate signature and encrypt image before pack it to the firmware.
|
||||
# Use secure_partition.py script to do so. RSA production key and AES key are required.
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=LetvUpgrade928.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=false
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=${FirmwareFileName}
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
dont_overwrite_init
|
||||
|
||||
Suffix:
|
||||
|
||||
# Enable UART
|
||||
setenv UARTOnOff on
|
||||
|
||||
# Auth enabled for the recovery partition
|
||||
# In that case security info (signature) is required
|
||||
setenv recoverycmd mmc read.p 0x25000000 recovery 0x02000000\; authenticateAN 0x25000000\; bootm 0x25000000
|
||||
|
||||
# Done
|
||||
setenv LetvUpgrade_complete 1
|
||||
setenv ResetAfterUpgrade 1
|
||||
setenv ForcePowerOn 1
|
||||
saveenv
|
||||
|
||||
[part/recovery]
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/recovery.img.aes
|
||||
type=partitionImage
|
||||
|
||||
[part/recoverySign]
|
||||
imageFile=${Main:ProjectFolder}/recovery.signature
|
||||
type=secureInfo
|
||||
32
mstar-bin-tool/configs/letv-x355pro-system.ini
Normal file
32
mstar-bin-tool/configs/letv-x355pro-system.ini
Normal file
@ -0,0 +1,32 @@
|
||||
#
|
||||
# LeEco X3-55pro (Super3 x55 Pro)
|
||||
# Config file to pack a single partition to firmware file (system.img)
|
||||
# This will not create the partition, just erase and rewrite it
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=LetvUpgrade928.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=false
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=${FirmwareFileName}
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
dont_overwrite_init
|
||||
|
||||
Suffix:
|
||||
setenv LetvUpgrade_complete 1
|
||||
setenv ResetAfterUpgrade 1
|
||||
setenv ForcePowerOn 0
|
||||
saveenv
|
||||
|
||||
[part/system]
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/system.img
|
||||
type=partitionImage
|
||||
lzo=True
|
||||
chunkSize=150MB
|
||||
45
mstar-bin-tool/configs/letv-x4-recovery-no-secure.ini
Normal file
45
mstar-bin-tool/configs/letv-x4-recovery-no-secure.ini
Normal file
@ -0,0 +1,45 @@
|
||||
#
|
||||
# LeEco X3-55pro (Super3 x55 Pro)
|
||||
# Config file to pack a single partition to firmware file (recovery.img)
|
||||
#
|
||||
# This will NOT create the partition, just erase and rewrite it
|
||||
# NO security info (signature) will be added to the bin !
|
||||
# Security checking for recovery will be DISABLED
|
||||
# Use it to flash plain non encrypted recovery.img
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=LetvUpgrade938-recovery.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=true
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=$$(UpgradeImage)
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
|
||||
|
||||
Suffix:
|
||||
|
||||
# Enable UART
|
||||
setenv UARTOnOff on
|
||||
|
||||
# No auth for the recovery
|
||||
setenv recoverycmd mmc read.p 0x23000000 dtb 0x00100000\; mmc read.p 0x25000000 recovery 0x02000000\; bootm 0x25000000
|
||||
# setenv recoverycmd mmc read.p 0x25000000 recovery 0x02000000\; bootm 0x25000000
|
||||
|
||||
|
||||
# Done
|
||||
setenv selinux_force_disable 1
|
||||
setenv LetvUpgrade_complete 1
|
||||
setenv ResetAfterUpgrade 1
|
||||
setenv ForcePowerOn 0
|
||||
saveenv
|
||||
|
||||
[part/recovery]
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/recovery.img
|
||||
type=partitionImage
|
||||
56
mstar-bin-tool/configs/letv-x4-systemless-live.ini
Normal file
56
mstar-bin-tool/configs/letv-x4-systemless-live.ini
Normal file
@ -0,0 +1,56 @@
|
||||
#
|
||||
# LeEco Super4 (Mstar 6a938)
|
||||
#
|
||||
# Config file to create "live" bin files
|
||||
# which allows to use custom recovery or boot images
|
||||
# without affecting the actual system
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=LetvUpgrade938-systemless-live.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=true
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=$$(UpgradeImage)
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
|
||||
# Init panel
|
||||
panel_pre_init
|
||||
hdmi init
|
||||
panel_post_init
|
||||
|
||||
|
||||
Suffix:
|
||||
|
||||
# Enable UART
|
||||
setenv UARTOnOff on
|
||||
|
||||
# Disable selinux
|
||||
setenv selinux_force_disable 1
|
||||
|
||||
# Do not boot
|
||||
setenv ForcePowerOn 0
|
||||
saveenv
|
||||
|
||||
# Boot uImage
|
||||
# 0x25000000 - image offset in memory
|
||||
bootm 0x25000000
|
||||
|
||||
|
||||
|
||||
[part/recovery]
|
||||
imageFile=${Main:ProjectFolder}/recovery.img
|
||||
# Do not store it to mmc, just load it and keep in memory
|
||||
type=inMemory
|
||||
memoryOffset=0x25000000
|
||||
|
||||
[part/dtb]
|
||||
imageFile=${Main:ProjectFolder}/dtb.bin
|
||||
# Do not store it to mmc, just load it and keep in memory
|
||||
type=inMemory
|
||||
memoryOffset=0x23000000
|
||||
35
mstar-bin-tool/configs/letv-x450pro-system.ini
Normal file
35
mstar-bin-tool/configs/letv-x450pro-system.ini
Normal file
@ -0,0 +1,35 @@
|
||||
#
|
||||
# LeEco X4-50pro (Super4 x50 Pro)
|
||||
# Config file to pack a single partition to firmware file (system.img)
|
||||
# This will not create the partition, just erase and rewrite it
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=LetvUpgrade938.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=true
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=$$(UpgradeImage)
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
|
||||
Suffix:
|
||||
setenv str_crc 2
|
||||
setenv db_table 0
|
||||
setenv verify n
|
||||
setenv ForcePowerOn 0
|
||||
saveenv
|
||||
setenv LetvUpgrade_complete 1
|
||||
saveenv
|
||||
printenv
|
||||
|
||||
[part/system]
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/system.img
|
||||
type=partitionImage
|
||||
lzo=True
|
||||
chunkSize=150MB
|
||||
35
mstar-bin-tool/configs/tcl-s68at02-system.ini
Normal file
35
mstar-bin-tool/configs/tcl-s68at02-system.ini
Normal file
@ -0,0 +1,35 @@
|
||||
#
|
||||
# TCL P1US-series (L43P2US etc)
|
||||
# Should work on all TV based on S68AT02 (MS68A-AP board)
|
||||
# Config file to pack a single partition to firmware file (system.img)
|
||||
# This will not create the partition, just erase and rewrite it
|
||||
#
|
||||
|
||||
[Main]
|
||||
FirmwareFileName=V8-S68AT02-LF1V108.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=true
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=$$(UpgradeImage)
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
|
||||
Suffix:
|
||||
setenv str_crc 1
|
||||
setenv db_table 0
|
||||
setenv verify n
|
||||
setenv ForcePowerOn 0
|
||||
saveenv
|
||||
setenv MstarUpgrade_complete 1
|
||||
saveenv
|
||||
|
||||
[part/system]
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/system.img
|
||||
type=partitionImage
|
||||
lzo=True
|
||||
chunkSize=150MB
|
||||
27
mstar-bin-tool/configs/xgimi.ini
Normal file
27
mstar-bin-tool/configs/xgimi.ini
Normal file
@ -0,0 +1,27 @@
|
||||
[Main]
|
||||
FirmwareFileName=GIMI_XF11G_MONACO_WMP_H1S.bin
|
||||
ProjectFolder=./pack
|
||||
useHexValuesPrefix=true
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME=${FirmwareFileName}
|
||||
DRAM_BUF_ADDR=20200000
|
||||
MAGIC_FOOTER=12345678
|
||||
HEADER_SIZE=16KB
|
||||
USE_XGIMI_CRC2=True
|
||||
|
||||
[HeaderScript]
|
||||
Prefix:
|
||||
|
||||
Suffix:
|
||||
setenv MstarUpgrade_complete 1
|
||||
setenv sync_mmap 1
|
||||
setenv db_table 0
|
||||
saveenv
|
||||
printenv
|
||||
|
||||
[part/system]
|
||||
erase=True
|
||||
imageFile=${Main:ProjectFolder}/system.img
|
||||
type=partitionImage
|
||||
lzo=True
|
||||
chunkSize=150MB
|
||||
BIN
mstar-bin-tool/default_keys/AESboot.bin
Normal file
BIN
mstar-bin-tool/default_keys/AESboot.bin
Normal file
Binary file not shown.
BIN
mstar-bin-tool/default_keys/AESupgrade.bin
Normal file
BIN
mstar-bin-tool/default_keys/AESupgrade.bin
Normal file
Binary file not shown.
3
mstar-bin-tool/default_keys/README.md
Normal file
3
mstar-bin-tool/default_keys/README.md
Normal file
@ -0,0 +1,3 @@
|
||||
# MSTAR default AES and RSA keys
|
||||
|
||||
These keys I found on github in a few public repositories. It seems like it's mstar default keys provided with their sdk.
|
||||
8
mstar-bin-tool/default_keys/RSAboot_priv.txt
Normal file
8
mstar-bin-tool/default_keys/RSAboot_priv.txt
Normal file
@ -0,0 +1,8 @@
|
||||
N = AA5E3FDAD01DDF4AFAFE67A1B53BBB8B931FECBAAC0F0C0ED61A66EC04C416E5A4A69AAFEFB6EE7DA3E7A559E4006BC5FCE979B28B8E81136C8AB6CC11D9A7CEA83C7A431835D04DA6AE40CD4D0414F6CA3D5EF2274EF38C8A6FBC6AC4CCD123FBCA638ABBC40514A998127671F3A36EA8B207E40E169BF75EC41915BE3A9EF2309A7661681191D6AC2C22AA46194DE8C712B7EFCE29D38BB920955C0E5A26FCF9651F568F3CDB6085364A2A357D94BDCFD0CF6C615064B12A9A7DA2AC03EC254899E013B4864E6815653206823F02BE4C0D594B4CF6548238AA0947A31A8BA1D1F8CC0911158FFD4C01460C6FF78DB822E4872851F6C0097CEAD15C46B4FB4B
|
||||
E = 010001
|
||||
D = 2D26E7737D7EBD4428FB2DC9FCB745003BD0D533B01018D901C3638D9FC1BC73C64C6568C5764D04BD60D240DD9D82F2A911D3B00F2E8864F67A58F202B515B53E7F30C4017199B04AC199E90F454AAD11726C6C6F208C89ADD2E933BECEAD8B04DB61C04DFD287F8E670055A5E3B567C98BCD6D92924969A912FDB6F680A0C90E7F0899436880FC66CC7E1399E11263497A42011BE8BE9B1C003F956448C425F4A8138D9DD3B6B735474A6CB7AC5A39CC0EDE5ED74D2DD7A9CCC681B58741D4DDA496B9C0DE1EF367B6709E2488A4B2915F1CCF92CD563C25D1CBF5D719F100D2A4C1DDAC1F49EB092100F9A2276289CFB9990C7AB7D11D2D40685D165C3849
|
||||
P = D623430C4E6C9BBC5D306EBEEAA0724F0847BB7E679E7E5B3EBDF21CE642C4296422824335A488D80A6DF3B24069BBEB10D4BC331DCC2C015717F934BF0B777B96166928FB355CBB27CB383E2F2FB499B8DBDE2425FEA7A134737A0964ECA25DFE304539EBC3BBD31128FB2B295DC1FA2C5968A7969A94E37287F2A31BC56F37
|
||||
Q = CBAC7EB7B047868F65C5681253DF2451287E06F60D4D683467876AD8A27EE0514F0B29A8E667D690BBC6164B977FCBD241663F71D6238838632D9DE057DF4E4BB349BA0FF213DA9DB8F89BFD83D1B902F45B5A028094D22947CE7A06437D12820412FAE2ECF1A4606C92C844E8AB624844DFEA573B0627A047969830BBD8168D
|
||||
DP = 0A863F245AB261D1172F6B31FCEC17D2249109F90374B9B718555391F20B3402E8C5FD6AFA36F4F6D1446826C99DA8BBBBDF08C4E6610384A958274A5D5D5DE8F80E6FEAB0B605B1B919F6D0AF9703A44E7E97E364EEA824772479C9FE68D6EE11B123A5DE1D879CAF0A3995FC797C30247FDC71E827FECB52F4B58B28B1426F
|
||||
DQ = 6C5D61AA70030E47FB78F5AF52AA95D30C7D494CDEB501AD682BF7A03D8CCDE2D4F07680E3DDF99E5619C5C10061415BA3EA37F5645ED15A57026D4E70D262010AEA3E31BFB5EA8A22613BF5BD8DF726E8463674C05EEE16829B0BF78B2EDF8B0789E5AC992ED42B6D79074F0A902D21906BA66E34FC485711DFC127A4BA0AFD
|
||||
QP = 2848FD5806119A589490ADDD419167BA952E38CBF6EF11B4B39D36156F2BE6B72372A04270D0ABFF2628F3A1E32BE9FF2C89323CABA492248FBF559E7068541E0A9238E4A61A9A5A9A77F53246693ACB12BDC3C94F83A7C6F379483E2F3CB450D3DE8FD26F7A2B1B8858C3621C7E22E0470ED225563F919658A125ECD7A0BA16
|
||||
BIN
mstar-bin-tool/default_keys/RSAboot_pub.bin
Normal file
BIN
mstar-bin-tool/default_keys/RSAboot_pub.bin
Normal file
Binary file not shown.
2
mstar-bin-tool/default_keys/RSAboot_pub.txt
Normal file
2
mstar-bin-tool/default_keys/RSAboot_pub.txt
Normal file
@ -0,0 +1,2 @@
|
||||
N = AA5E3FDAD01DDF4AFAFE67A1B53BBB8B931FECBAAC0F0C0ED61A66EC04C416E5A4A69AAFEFB6EE7DA3E7A559E4006BC5FCE979B28B8E81136C8AB6CC11D9A7CEA83C7A431835D04DA6AE40CD4D0414F6CA3D5EF2274EF38C8A6FBC6AC4CCD123FBCA638ABBC40514A998127671F3A36EA8B207E40E169BF75EC41915BE3A9EF2309A7661681191D6AC2C22AA46194DE8C712B7EFCE29D38BB920955C0E5A26FCF9651F568F3CDB6085364A2A357D94BDCFD0CF6C615064B12A9A7DA2AC03EC254899E013B4864E6815653206823F02BE4C0D594B4CF6548238AA0947A31A8BA1D1F8CC0911158FFD4C01460C6FF78DB822E4872851F6C0097CEAD15C46B4FB4B
|
||||
E = 010001
|
||||
8
mstar-bin-tool/default_keys/RSAimage_priv.txt
Normal file
8
mstar-bin-tool/default_keys/RSAimage_priv.txt
Normal file
@ -0,0 +1,8 @@
|
||||
N = 846276CCBD5A5A4030C096408728DB85EDED9F3EDE4E65E67B1B7817879DF616C3D327BCB45A031335B0965A9641744EB9D17796F78DE2E71509659C4679EAF0916735FA694C83F7DCCF9720F2A5BA72809D557917DC6E60A5E70E9E899B460652FC645602089A9641E24FDBB660C338DFF497815D1202AE2B9F0929B99D5145D29E2BAF64CA9A064E943567F78E047B2438A0DFE75F1E6D298E30D7838CB441D2FDBF5B18CA50D127D1F67D543E805F20DC8882CFBEE1462AD663B9B99DA3C7683E48CE6A626FD16AC3B6DEF33925ECF67920B5F230256E99AE3956DAAF83D6B849157881CC3C4F665D957E31D4372ABEFCB466F891010A533C3CAB86B980B7
|
||||
E = 010001
|
||||
D = 73A17978CD6F8CE30272450AE9C383331125FB713345B0F5C6D3B06A84F7310AA352DD23933807F59070C4732D48D0A92EDECA211FEB5BA451989A9B0C67D310FB3FF642DA148E344237441EF032578F49CDA2E99930DD6C279C910562D6302CB7F162464992704C0C11FB84C260F443CA41DECF8C967DA6D9CD1878CC7A9F902474E2A938933D2B51C8EF06D46019EA213379F648938A953C128F458D421E0E862144BE86FA877F6840F6CFF36EAC3E64AB682DAAE8AE194669E2B3E200E2C6E775143CB13A45D11845883F4BD06C6420BABD384269AA087A3A98DDF94574F5D78E2BAD671D42572E488522F0C91F7742C2285C8EE20C3DE3B060D1AA9987E1
|
||||
P = CE85599F5EB3800196192D5B9127499ACF77F94ECE68726DE24D708066728903430C240F175901999A522AE1420DA9C662BA0DC7AAC710B53C24EF7F365FFBDDBD8A919196172EB7B12BEB06472A9EFF1393BD400E1B62AF5AD0FE8740DDFC6DEF970CE8F4481387B0EEDBBB2310BA3E97B71F5F7022722B0BCAD2E03D3A8727
|
||||
Q = A41A13A32F07E49890E8E65FC5D1D51F54746623DF195A4F46006C15913A55F5A92534FE1C59F2FF2FCBFA74B82AF69A8709DD85512B58EF9D5EE3705990D7F548D0BDD1333BD0F229F097DCDB96909AC2FE033157E10F7F677E52317DCC671E744E4104ECF6705C0D521FD08BCAA593C29690436C4C9BFE68FCCDC72CE0B3F1
|
||||
DP = 2C3FD2361D7A6460F2A22E5FC23822C332D4C7EC24B9A85AF6F414B8CE3A9834C4B6E33B008BA7961BC4A33F6481BCF0AED2A285378833824182C07607568586BB47E76CC435EF6298698A8FEBCBAC09874E4E6C5D196D099971D23774A49BA38A8458D5C911706DD0713D4F59720A15C3380F56C995F7D455507DE261FC1A5D
|
||||
DQ = 5E61B51BACC8105D03334094A2D4FD8BC86A2DF8C1AEF63713DED84B4B3CCF05BCA3EEA79C2CCBCAA375E0F5D29ABB3CC320146D41F2F972CF032D328800FB8452BDE3FE774616F5C0D364B49D032AE627F22A69EDCE3EB89B10973B69CBEF1F1FEB860FCC2E2D0F7485E05074A637B7153ABD7C59C4720FCFD85E8E08ACB031
|
||||
QP = 8310683F28ECBE7F437A6B64A489F5A8B0114A4FC41BEEB6672AF677A9D5B64FACE2E35CC5D59D6C42D4BE6ED8633203E51F8BCA8EA9BDF41B2B87238F988BAC02BD8A11C96BC90BF435749CAE8FCC7E9B37A37AD57218D6CCA127B882FB0015F59DFD87FB994518305DFFCC1C692AE796E04967B31723506F8B29FAD24DE15E
|
||||
BIN
mstar-bin-tool/default_keys/RSAimage_pub.bin
Normal file
BIN
mstar-bin-tool/default_keys/RSAimage_pub.bin
Normal file
Binary file not shown.
2
mstar-bin-tool/default_keys/RSAimage_pub.txt
Normal file
2
mstar-bin-tool/default_keys/RSAimage_pub.txt
Normal file
@ -0,0 +1,2 @@
|
||||
N = 846276CCBD5A5A4030C096408728DB85EDED9F3EDE4E65E67B1B7817879DF616C3D327BCB45A031335B0965A9641744EB9D17796F78DE2E71509659C4679EAF0916735FA694C83F7DCCF9720F2A5BA72809D557917DC6E60A5E70E9E899B460652FC645602089A9641E24FDBB660C338DFF497815D1202AE2B9F0929B99D5145D29E2BAF64CA9A064E943567F78E047B2438A0DFE75F1E6D298E30D7838CB441D2FDBF5B18CA50D127D1F67D543E805F20DC8882CFBEE1462AD663B9B99DA3C7683E48CE6A626FD16AC3B6DEF33925ECF67920B5F230256E99AE3956DAAF83D6B849157881CC3C4F665D957E31D4372ABEFCB466F891010A533C3CAB86B980B7
|
||||
E = 010001
|
||||
8
mstar-bin-tool/default_keys/RSAupgrade_priv.txt
Normal file
8
mstar-bin-tool/default_keys/RSAupgrade_priv.txt
Normal file
@ -0,0 +1,8 @@
|
||||
N = 9BA7D26B0F3AACB837807CED2A87D54C974976E967EBBEAAB297E3A4ED0C2491896DF16319698CC4323CC8ECFD8CA209BDE194D3BEB38458D7A2C859C717826DB7688245340323953CFF94F9EE8363DFF854E22C6A7F41FC2B545B2291051CCCB09A33742D6DC02FA49723D2B481EA8C679911671565E14F65534240012C642683F98976102A4AF6E06FE130028689BA2372349CAC3E35D4CE46055C234EF4EAC4DF9636FFA8A46276DFC3EC78EE7AFF6E05236E4574AB5D15EBD2DE86A4C96E90F1F9CC00F048EDCFFBC33500251BF669F5A4F00F5437C2E4B6BAD492154FF48F420A8C7E149161A3F11F3BEB680EE394182FD3484479EA224420CC1EBCA391
|
||||
E = 010001
|
||||
D = 705CD4439E69BFB6F7B1D3FCAC800394D77D1BCEDFCAC907960699393C3950C892898000069F30138D245DF2DE1140038243AE58B0480C98C988E3D2132B40670D47EF0A1FC2C853FA0591B85DDA1125E3B0FAD80F44B0106602EE0AE4DEE8EC45EBFA8ABA2488E09B92D3344E439E5A1E8ADB8A2B6331234C44AF055F13797342E9EC86139836A825C61E63C93A6EB39ED9F8463DC914D223AF45CE8E4D80491EBC78C4E253FC0B51A5F83AADD4CB9D48A66508D82F6E54245B48FF95DEC41E17541FDFEFDAEB1F72B0E9B31E810560A06E483D2DE2A242D2D5FE52C3FF09F21CE35E99217D501C621D0CCCEB78B17BEA403C447909684577C22B364FFC0BA5
|
||||
P = F1056953D2E8AD64BB8FDF24B781F5D1CA961DC9A46786625F7AD3E3CDF50DACD005B903ADC4C16C2726A80530E15C66FE75901A218B05FC7282C8BC7DB5316CB8A9102AD0623A73B679FABD21A973C8340412EC3C04EF8818A2C35E61370DE145D5513C3B93F234C4D57318FC45E6D073D6AC9DFAB38F5B023104268A106D2B
|
||||
Q = A55443B7CF7E48EE8CA0E9813350C4AF25BB302CC1025DEFB8C356C11E8A5E5702A57F306F675C7C68A971B34FC805651915EEC594863BC4CEAE7F09B4EB51A81354BD8F6BAF299F84F1EDC324C4CE7FD5B49242E8ADFE812B73B389293397F36639E097481F4EEF0AA39D25C3417E44565197876AB367E0E4EE8DC4195AAC33
|
||||
DP = CC5CCB474110FB5CEB507D637399E566424170F675C9360019775B4CD0689574CF59DADB8CAEC556C0079DF5F0D155791B0F71E54645CC0896CBE00B3B07B4E5BBD9D614876692AB64B11EF2D92506405E228A2CF66334FB0FF08A796F32B0392FEE45182E682EB9A1A05F1C73638DE7782131722E8DABE2FE03B3C23DD4D9CB
|
||||
DQ = 906D1B372090FE5F3E0477D7C11F46A286C08E661A39DA1BC779057971178930538485A6A73B5124F13D4CB14AF9BE14C22451D0D25DAD2AD12EC8958F319EC4C81657FE4920DCA898B7CB6F94D844589234CB2C9E1D195E77B9FC55CEE35E5367B319CAAE5B8355F92252EEA132BE7E2E35DABC966EA1496A54270DEEE431D7
|
||||
QP = B7752EE6E5694BA1159CE9837FEAE2F9584F94DF50094A737771AD0D70F3295B3FF4D3EFCD8374999768976092E73D214B9F93B9FC1718BE886652EBF9289D02072C1177D94FBE7BEC3C0170BDB6D17B94EF84550C8FB1688AA3A8450BCE20B0ED0762903B740B7FEC56E8C5BAD166153515AB9489BEAD94493720CE67B13DF2
|
||||
BIN
mstar-bin-tool/default_keys/RSAupgrade_pub.bin
Normal file
BIN
mstar-bin-tool/default_keys/RSAupgrade_pub.bin
Normal file
Binary file not shown.
2
mstar-bin-tool/default_keys/RSAupgrade_pub.txt
Normal file
2
mstar-bin-tool/default_keys/RSAupgrade_pub.txt
Normal file
@ -0,0 +1,2 @@
|
||||
N = 9BA7D26B0F3AACB837807CED2A87D54C974976E967EBBEAAB297E3A4ED0C2491896DF16319698CC4323CC8ECFD8CA209BDE194D3BEB38458D7A2C859C717826DB7688245340323953CFF94F9EE8363DFF854E22C6A7F41FC2B545B2291051CCCB09A33742D6DC02FA49723D2B481EA8C679911671565E14F65534240012C642683F98976102A4AF6E06FE130028689BA2372349CAC3E35D4CE46055C234EF4EAC4DF9636FFA8A46276DFC3EC78EE7AFF6E05236E4574AB5D15EBD2DE86A4C96E90F1F9CC00F048EDCFFBC33500251BF669F5A4F00F5437C2E4B6BAD492154FF48F420A8C7E149161A3F11F3BEB680EE394182FD3484479EA224420CC1EBCA391
|
||||
E = 010001
|
||||
BIN
mstar-bin-tool/docs/Introduction to MBoot.doc
Normal file
BIN
mstar-bin-tool/docs/Introduction to MBoot.doc
Normal file
Binary file not shown.
186
mstar-bin-tool/extract_keys.py
Normal file
186
mstar-bin-tool/extract_keys.py
Normal file
@ -0,0 +1,186 @@
|
||||
'''
|
||||
Tool to extract security keys from the MBOOT
|
||||
|
||||
That tool can be used only if you have Mstar.Key.Bank section in the mboot
|
||||
To check that you need to enable debug mode in the mboot console,
|
||||
and check for next lines during the boot:
|
||||
[DEBUG] isCustomerKeyBankCipher:926: keyBankOffset=0x168e00
|
||||
[DEBUG] isCustomerKeyBankCipher:927: keyBankSize=0x450
|
||||
|
||||
keyBankOffset - is an offset of the key bank section in the mboot
|
||||
keyBankSize - section size
|
||||
|
||||
There will be similar lines for the key bank backup.
|
||||
|
||||
Another way to check it is to open MBOOT binary in the hex editor and
|
||||
do search for u8MagicID, which is most of the time equals to "Mstar.Key.Bank" string.
|
||||
You should get two equal sections, the key bank and the key bank backup.
|
||||
|
||||
==== Key bank structures ===
|
||||
|
||||
#define AES_IV_LEN 16
|
||||
#define AES_KEY_LEN 16
|
||||
#define HMAC_KEY_LEN 32
|
||||
|
||||
#define SIGNATURE_LEN 256
|
||||
#define RSA_PUBLIC_KEY_N_LEN 256
|
||||
#define RSA_PUBLIC_KEY_E_LEN 4
|
||||
#define RSA_PUBLIC_KEY_LEN (RSA_PUBLIC_KEY_N_LEN+RSA_PUBLIC_KEY_E_LEN)
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U32 u32Num;
|
||||
U32 u32Size;
|
||||
}IMAGE_INFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U8 u8SecIdentify[8];
|
||||
IMAGE_INFO info;
|
||||
U8 u8Signature[SIGNATURE_LEN];
|
||||
}_SUB_SECURE_INFO;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
U8 N[RSA_PUBLIC_KEY_N_LEN];
|
||||
U8 E[RSA_PUBLIC_KEY_E_LEN];
|
||||
}RSA_PUBLIC_KEY;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
_SUB_SECURE_INFO customer;
|
||||
RSA_PUBLIC_KEY u8RSABootPublicKey;
|
||||
RSA_PUBLIC_KEY u8RSAUpgradePublicKey;
|
||||
RSA_PUBLIC_KEY u8RSAImagePublicKey;
|
||||
U8 u8AESBootKey[AES_KEY_LEN];
|
||||
U8 u8AESUpgradeKey[AES_KEY_LEN];
|
||||
U8 u8MagicID[16];
|
||||
U8 crc[4];
|
||||
}CUSTOMER_KEY_BANK;
|
||||
|
||||
==== End Key bank structures ===
|
||||
|
||||
'''
|
||||
|
||||
from ctypes import *
|
||||
import os
|
||||
import sys
|
||||
import utils
|
||||
|
||||
DEBUG = False
|
||||
|
||||
# Default values
|
||||
defOutFolder = "keys"
|
||||
defOffet = "0x168e00"
|
||||
defSize = "0x450"
|
||||
#defKey="hex:E01001FF0FAA55FC924D535441FF0700"
|
||||
|
||||
# Structures
|
||||
AES_IV_LEN = 16
|
||||
AES_KEY_LEN = 16
|
||||
HMAC_KEY_LEN = 32
|
||||
|
||||
SIGNATURE_LEN = 256
|
||||
RSA_PUBLIC_KEY_N_LEN = 256
|
||||
RSA_PUBLIC_KEY_E_LEN = 4
|
||||
RSA_PUBLIC_KEY_LEN = RSA_PUBLIC_KEY_N_LEN + RSA_PUBLIC_KEY_E_LEN
|
||||
|
||||
class IMAGE_INFO(Structure):
|
||||
_fields_ = [("u32Num", c_uint32),
|
||||
("u32Size", c_uint32)]
|
||||
|
||||
class SUB_SECURE_INFO(Structure):
|
||||
_fields_ = [("u8SecIdentify", c_uint8 * 8),
|
||||
("info", IMAGE_INFO),
|
||||
("u8Signature", c_uint8 * SIGNATURE_LEN)]
|
||||
|
||||
class RSA_PUBLIC_KEY(Structure):
|
||||
_fields_ = [("N", c_uint8 * RSA_PUBLIC_KEY_N_LEN),
|
||||
("E", c_uint8 * RSA_PUBLIC_KEY_E_LEN)]
|
||||
|
||||
class CUSTOMER_KEY_BANK(Structure):
|
||||
_fields_ = [("customer", SUB_SECURE_INFO),
|
||||
("u8RSABootPublicKey", RSA_PUBLIC_KEY),
|
||||
("u8RSAUpgradePublicKey", RSA_PUBLIC_KEY),
|
||||
("u8RSAImagePublicKey", RSA_PUBLIC_KEY),
|
||||
("u8AESBootKey", c_uint8 * AES_KEY_LEN),
|
||||
("u8AESUpgradeKey", c_uint8 * AES_KEY_LEN),
|
||||
("u8MagicID", c_uint8 * 16),
|
||||
("crc", c_uint8 * 4)]
|
||||
|
||||
|
||||
# Command line args
|
||||
if len(sys.argv) == 1:
|
||||
print ("Usage: extract_keys.py <path to mboot> [<folder to store keys>] [<key bank offset>] [<key bank size>]")
|
||||
print ("Defaults: ")
|
||||
print (" <folder to store keys> keys")
|
||||
print (" <key bank offset> 0x168e00")
|
||||
print (" <key bank size> 0x450")
|
||||
#print (" <custom decription key> Efuse Key")
|
||||
print ("Example: extract_keys.py ./unpacked/MBOOT.img")
|
||||
print ("Example: extract_keys.py ./unpacked/MBOOT.img ./keys 0x169e00 0x450")
|
||||
quit()
|
||||
|
||||
|
||||
mboot = sys.argv[1]
|
||||
outFolder = sys.argv[2] if len(sys.argv) >= 3 else defOutFolder
|
||||
offestStr = sys.argv[3] if len(sys.argv) >= 4 else defOffet
|
||||
sizeStr = sys.argv[4] if len(sys.argv) >= 5 else defSize
|
||||
#hwKey = sys.argv[5] if len(sys.argv) >= 6 else defKey
|
||||
|
||||
offset = int(offestStr, 16)
|
||||
size = int(sizeStr, 16)
|
||||
|
||||
# Create out directory
|
||||
print ("[i] Create output directory")
|
||||
utils.createDirectory(outFolder)
|
||||
|
||||
# Get the key bank section and store it
|
||||
outEncKeyBankFile = os.path.join(outFolder, 'key_bank.bin')
|
||||
print ("[i] Save mstar key bank to {}".format(outEncKeyBankFile))
|
||||
utils.copyPart(mboot, outEncKeyBankFile, offset, size)
|
||||
|
||||
# Unpack the key bank to key bank structure
|
||||
print ("[i] Unpack key bank structure")
|
||||
keyBankBytes = utils.loadPart(outEncKeyBankFile, 0, size)
|
||||
keyBank = utils.unpackStructure(CUSTOMER_KEY_BANK, keyBankBytes)
|
||||
|
||||
if (DEBUG):
|
||||
# Print all
|
||||
print ( "[i] u8SecIdentify:\n{}".format( utils.hexString(keyBank.customer.u8SecIdentify) ) )
|
||||
print ( "[i] u32Num: 0x{:08x}".format( keyBank.customer.info.u32Num ) )
|
||||
print ( "[i] u32Size: 0x{:08x}".format( keyBank.customer.info.u32Size ) )
|
||||
print ( "[i] u8Signature:\n{}".format( utils.hexString(keyBank.customer.u8Signature) ) )
|
||||
|
||||
print ( "[i] u8RSABootPublicKey N:\n{}".format( utils.hexString(keyBank.u8RSABootPublicKey.N) ) )
|
||||
print ( "[i] u8RSABootPublicKey E:\n{}".format( utils.hexString(keyBank.u8RSABootPublicKey.E) ) )
|
||||
print ( "[i] u8RSAUpgradePublicKey N:\n{}".format( utils.hexString(keyBank.u8RSAUpgradePublicKey.N) ) )
|
||||
print ( "[i] u8RSAUpgradePublicKey E:\n{}".format( utils.hexString(keyBank.u8RSAUpgradePublicKey.E) ) )
|
||||
print ( "[i] u8RSAImagePublicKey N:\n{}".format( utils.hexString(keyBank.u8RSAImagePublicKey.N) ) )
|
||||
print ( "[i] u8RSAImagePublicKey E:\n{}".format( utils.hexString(keyBank.u8RSAImagePublicKey.E) ) )
|
||||
print ( "[i] u8AESBootKey:\n{}".format( utils.hexString(keyBank.u8AESBootKey) ) )
|
||||
print ( "[i] u8AESUpgradeKey:\n{}".format( utils.hexString(keyBank.u8AESUpgradeKey) ) )
|
||||
|
||||
print ( "[i] u8MagicID:\n{}".format( utils.hexString(keyBank.u8MagicID) ) )
|
||||
print ( "[i] CRC:\n{}".format( utils.hexString(keyBank.crc) ) )
|
||||
|
||||
# Save keys
|
||||
print ("[i] Save keys")
|
||||
|
||||
# RSA Boot
|
||||
utils.writeFile(os.path.join(outFolder, 'RSAboot_pub.bin'), keyBank.u8RSABootPublicKey)
|
||||
utils.writeRSAPublicKey(os.path.join(outFolder, 'RSAboot_pub.txt'), keyBank.u8RSABootPublicKey)
|
||||
|
||||
# RSA Upgrade
|
||||
utils.writeFile(os.path.join(outFolder, 'RSAupgrade_pub.bin'), keyBank.u8RSAUpgradePublicKey)
|
||||
utils.writeRSAPublicKey(os.path.join(outFolder, 'RSAupgrade_pub.txt'), keyBank.u8RSAUpgradePublicKey)
|
||||
|
||||
# RSA Image
|
||||
utils.writeFile(os.path.join(outFolder, 'RSAimage_pub.bin'), keyBank.u8RSAImagePublicKey)
|
||||
utils.writeRSAPublicKey(os.path.join(outFolder, 'RSAimage_pub.txt'), keyBank.u8RSAImagePublicKey)
|
||||
|
||||
# AES
|
||||
utils.writeFile(os.path.join(outFolder, 'AESBoot.bin'), keyBank.u8AESBootKey)
|
||||
utils.writeFile(os.path.join(outFolder, 'AESUpgrade.bin'), keyBank.u8AESUpgradeKey)
|
||||
|
||||
print ("Done")
|
||||
337
mstar-bin-tool/pack.py
Normal file
337
mstar-bin-tool/pack.py
Normal file
@ -0,0 +1,337 @@
|
||||
'''
|
||||
Mstar bin firmware packer
|
||||
'''
|
||||
|
||||
'''
|
||||
Header structure
|
||||
-------
|
||||
Multi-line script which contains MBOOT commands
|
||||
The header script ends with line: '% <- this is end of file symbol'
|
||||
Line separator is '\n'
|
||||
The header is filled by 0xFF to 16KB
|
||||
The header size is always 16KB
|
||||
'''
|
||||
|
||||
'''
|
||||
Bin structure
|
||||
-------
|
||||
Basically it's merged parts:
|
||||
|
||||
[part 1]
|
||||
[part 2]
|
||||
....
|
||||
[part n]
|
||||
|
||||
Each part is 4 byte aligned (filled by 0xFF)
|
||||
'''
|
||||
|
||||
'''
|
||||
Footer structure
|
||||
|MAGIC|CRC1: SWAPPED HEADER CRC32|CRC2: SWAPPED BIN CRC32|FIRST 16 BYTES OF HEADER|
|
||||
|
||||
# NB XGIMI uses HEADER+BIN+MAGIC+HEADER_CRC to calculate crc2
|
||||
# Use USE_XGIMI_CRC2=True option to enable "XGIMI" mode
|
||||
'''
|
||||
|
||||
import configparser
|
||||
import sys
|
||||
import time
|
||||
import os
|
||||
import struct
|
||||
import utils
|
||||
import shutil
|
||||
|
||||
tmpDir = 'tmp'
|
||||
headerPart = os.path.join(tmpDir, '~header')
|
||||
binPart = os.path.join(tmpDir, '~bin')
|
||||
footerPart = os.path.join(tmpDir, '~footer')
|
||||
|
||||
# Command line args
|
||||
if len(sys.argv) == 1:
|
||||
print ("Usage: pack.py <config file>")
|
||||
print ("Example: pack.py configs/letv-x355pro.ini")
|
||||
quit()
|
||||
|
||||
configFile = sys.argv[1]
|
||||
|
||||
# Parse config file
|
||||
config = configparser.ConfigParser(interpolation=configparser.ExtendedInterpolation())
|
||||
#config = configparser.ConfigParser()
|
||||
config.read(configFile)
|
||||
|
||||
# Main
|
||||
main = config['Main'];
|
||||
firmwareFileName = main['FirmwareFileName']
|
||||
projectFolder = main['ProjectFolder']
|
||||
useHexValuesPrefix = utils.str2bool(main['useHexValuesPrefix'])
|
||||
|
||||
SCRIPT_FIRMWARE_FILE_NAME = main['SCRIPT_FIRMWARE_FILE_NAME']
|
||||
DRAM_BUF_ADDR = main['DRAM_BUF_ADDR']
|
||||
MAGIC_FOOTER = main['MAGIC_FOOTER']
|
||||
HEADER_SIZE = utils.sizeInt(main['HEADER_SIZE'])
|
||||
|
||||
# XGIMI uses HEADER+BIN+MAGIC+HEADER_CRC to calculate crc2
|
||||
if 'USE_XGIMI_CRC2' in main:
|
||||
USE_XGIMI_CRC2 = utils.str2bool(main['USE_XGIMI_CRC2'])
|
||||
else:
|
||||
USE_XGIMI_CRC2 = False
|
||||
|
||||
# Header
|
||||
header = config['HeaderScript'];
|
||||
headerScriptPrefix = config.get('HeaderScript', 'Prefix', raw = True)
|
||||
headerScriptSuffix = config.get('HeaderScript', 'Suffix', raw = True)
|
||||
|
||||
|
||||
# Parts
|
||||
parts = list(filter(lambda s: s.startswith('part/'), config.sections()))
|
||||
|
||||
print("\n")
|
||||
print ("[i] Date: {}".format(time.strftime("%d/%m/%Y %H:%M:%S")))
|
||||
print ("[i] Firmware file name: {}".format(firmwareFileName))
|
||||
print ("[i] Project folder: {}".format(projectFolder))
|
||||
print ("[i] Use hex values: {}".format(useHexValuesPrefix))
|
||||
print ("[i] Script firmware filename: {}".format(SCRIPT_FIRMWARE_FILE_NAME))
|
||||
print ("[i] DRAM_BUF_ADDR: {}".format(DRAM_BUF_ADDR))
|
||||
print ("[i] MAGIC_FOOTER: {}".format(MAGIC_FOOTER))
|
||||
print ("[i] HEADER_SIZE: {}".format(HEADER_SIZE))
|
||||
|
||||
# Create working directory
|
||||
print ('[i] Create working directory ...')
|
||||
utils.createDirectory(tmpDir)
|
||||
|
||||
print ('[i] Generating header and bin ...')
|
||||
# Initial empty bin to store merged parts
|
||||
open(binPart, 'w').close()
|
||||
|
||||
with open(headerPart, 'wb') as header:
|
||||
|
||||
header.write('#\n'.encode())
|
||||
header.write('# Generated by mstar-bin-tools\n'.encode())
|
||||
header.write('# https://github.com/dipcore/mstar-bin-tool\n'.encode())
|
||||
header.write('# dipcore@gmail.com\n'.encode())
|
||||
header.write('#\n\n'.encode())
|
||||
|
||||
# Directive tool
|
||||
directive = utils.directive(header, DRAM_BUF_ADDR, useHexValuesPrefix)
|
||||
|
||||
header.write('# Header prefix'.encode())
|
||||
header.write(headerScriptPrefix.encode())
|
||||
header.write('\n\n'.encode())
|
||||
|
||||
header.write('# Partitions'.encode())
|
||||
for sectionName in parts:
|
||||
|
||||
part = config[sectionName]
|
||||
name = sectionName.replace('part/', '')
|
||||
create = utils.str2bool(utils.getConfigValue(part, 'create', ''))
|
||||
size = utils.getConfigValue(part, 'size', 'NOT_SET')
|
||||
erase = utils.str2bool(utils.getConfigValue(part, 'erase', ''))
|
||||
type = utils.getConfigValue(part, 'type', 'NOT_SET')
|
||||
imageFile = utils.getConfigValue(part, 'imageFile', 'NOT_SET')
|
||||
chunkSize = utils.sizeInt(utils.getConfigValue(part, 'chunkSize', '0'))
|
||||
lzo = utils.str2bool(utils.getConfigValue(part, 'lzo', ''))
|
||||
memoryOffset = utils.getConfigValue(part, 'memoryOffset', 'NOT_SET')
|
||||
emptySkip = utils.str2bool(utils.getConfigValue(part, 'emptySkip', 'True'))
|
||||
|
||||
print("\n")
|
||||
print("[i] Processing partition")
|
||||
print("[i] Name: {}".format(name))
|
||||
print("[i] Create: {}".format(create))
|
||||
print("[i] Size: {}".format(size))
|
||||
print("[i] Erase: {}".format(erase))
|
||||
print("[i] Type: {}".format(type))
|
||||
print("[i] Image: {}".format(imageFile))
|
||||
print("[i] LZO: {}".format(lzo))
|
||||
print("[i] Memory Offset: {}".format(memoryOffset))
|
||||
print("[i] Empty Skip: {}".format(emptySkip))
|
||||
|
||||
emptySkip = utils.bool2int(emptySkip) # 0 - False, 1 - True
|
||||
|
||||
header.write('\n'.encode())
|
||||
header.write('# {}\n'.format(name).encode())
|
||||
|
||||
if (create):
|
||||
directive.create(name, size)
|
||||
|
||||
if (erase and imageFile == 'NOT_SET'):
|
||||
directive.erase_p(name)
|
||||
|
||||
if (type == 'partitionImage'):
|
||||
|
||||
if (chunkSize > 0):
|
||||
print ('[i] Splitting ...')
|
||||
chunks = utils.splitFile(imageFile, tmpDir, chunksize = chunkSize)
|
||||
else:
|
||||
# It will contain whole image as a single chunk
|
||||
chunks = utils.splitFile(imageFile, tmpDir, chunksize = 0)
|
||||
|
||||
for index, inputChunk in enumerate(chunks):
|
||||
print ('[i] Processing chunk: {}'.format(inputChunk))
|
||||
(name1, ext1) = os.path.splitext(inputChunk)
|
||||
if lzo:
|
||||
outputChunk = name1 + '.lzo'
|
||||
print ('[i] LZO: {} -> {}'.format(inputChunk, outputChunk))
|
||||
utils.lzo(inputChunk, outputChunk)
|
||||
else:
|
||||
outputChunk = inputChunk
|
||||
|
||||
# Size, offset (hex)
|
||||
size = "{:02X}".format(os.path.getsize(outputChunk))
|
||||
offset = "{:02X}".format(os.path.getsize(binPart) + HEADER_SIZE)
|
||||
|
||||
directive.filepartload(SCRIPT_FIRMWARE_FILE_NAME, offset, size)
|
||||
if (index == 0 and erase):
|
||||
directive.erase_p(name)
|
||||
|
||||
print ('[i] Align chunk')
|
||||
utils.alignFile(outputChunk)
|
||||
|
||||
print ('[i] Append: {} -> {}'.format(outputChunk, binPart))
|
||||
utils.appendFile(outputChunk, binPart)
|
||||
|
||||
if lzo:
|
||||
if index == 0:
|
||||
directive.unlzo(name, size, DRAM_BUF_ADDR, emptySkip)
|
||||
else:
|
||||
directive.unlzo_cont(name, size, DRAM_BUF_ADDR, emptySkip)
|
||||
else:
|
||||
if len(chunks) == 1:
|
||||
directive.write_p(name, size, DRAM_BUF_ADDR, emptySkip)
|
||||
else:
|
||||
# filepartload 50000000 MstarUpgrade.bin e04000 c800000
|
||||
# mmc write.p.continue 50000000 system 0 c800000 1
|
||||
|
||||
# filepartload 50000000 MstarUpgrade.bin d604000 c800000
|
||||
# mmc write.p.continue 50000000 system 64000 c800000 1
|
||||
# Why offset is 64000 but not c800000 ???
|
||||
print ('[!] UNSUPPORTED: mmc write.p.continue')
|
||||
quit()
|
||||
|
||||
if (type == 'secureInfo'):
|
||||
|
||||
chunks = utils.splitFile(imageFile, tmpDir, chunksize = 0)
|
||||
outputChunk = chunks[0]
|
||||
|
||||
size = "{:02X}".format(os.path.getsize(outputChunk))
|
||||
offset = "{:02X}".format(os.path.getsize(binPart) + HEADER_SIZE)
|
||||
directive.filepartload(SCRIPT_FIRMWARE_FILE_NAME, offset, size)
|
||||
|
||||
print ('[i] Align')
|
||||
utils.alignFile(outputChunk)
|
||||
|
||||
print ('[i] Append: {} -> {}'.format(outputChunk, binPart))
|
||||
utils.appendFile(outputChunk, binPart)
|
||||
directive.store_secure_info(name)
|
||||
|
||||
if (type == 'nuttxConfig'):
|
||||
|
||||
chunks = utils.splitFile(imageFile, tmpDir, chunksize = 0)
|
||||
outputChunk = chunks[0]
|
||||
|
||||
size = "{:02X}".format(os.path.getsize(outputChunk))
|
||||
offset = "{:02X}".format(os.path.getsize(binPart) + HEADER_SIZE)
|
||||
directive.filepartload(SCRIPT_FIRMWARE_FILE_NAME, offset, size)
|
||||
|
||||
print ('[i] Align')
|
||||
utils.alignFile(outputChunk)
|
||||
|
||||
print ('[i] Append: {} -> {}'.format(outputChunk, binPart))
|
||||
utils.appendFile(outputChunk, binPart)
|
||||
directive.store_nuttx_config(name)
|
||||
|
||||
if (type == 'sboot'):
|
||||
|
||||
chunks = utils.splitFile(imageFile, tmpDir, chunksize = 0)
|
||||
outputChunk = chunks[0]
|
||||
|
||||
size = "{:02X}".format(os.path.getsize(outputChunk))
|
||||
offset = "{:02X}".format(os.path.getsize(binPart) + HEADER_SIZE)
|
||||
directive.filepartload(SCRIPT_FIRMWARE_FILE_NAME, offset, size)
|
||||
|
||||
print ('[i] Align')
|
||||
utils.alignFile(outputChunk)
|
||||
|
||||
print ('[i] Append: {} -> {}'.format(outputChunk, binPart))
|
||||
utils.appendFile(outputChunk, binPart)
|
||||
directive.write_boot(size, DRAM_BUF_ADDR, emptySkip)
|
||||
|
||||
if (type == 'inMemory'):
|
||||
|
||||
chunks = utils.splitFile(imageFile, tmpDir, chunksize = 0)
|
||||
outputChunk = chunks[0]
|
||||
|
||||
size = "{:02X}".format(os.path.getsize(outputChunk))
|
||||
offset = "{:02X}".format(os.path.getsize(binPart) + HEADER_SIZE)
|
||||
directive.filepartload(SCRIPT_FIRMWARE_FILE_NAME, offset, size, memoryOffset=memoryOffset)
|
||||
|
||||
print ('[i] Align')
|
||||
utils.alignFile(outputChunk)
|
||||
|
||||
print ('[i] Append: {} -> {}'.format(outputChunk, binPart))
|
||||
utils.appendFile(outputChunk, binPart)
|
||||
|
||||
|
||||
|
||||
header.write('\n'.encode())
|
||||
header.write('# Header suffix'.encode())
|
||||
header.write(headerScriptSuffix.encode())
|
||||
header.write('\n'.encode())
|
||||
|
||||
header.write('% <- this is end of file symbol\n'.encode())
|
||||
header.flush()
|
||||
|
||||
print ('[i] Fill header script to 16KB')
|
||||
header.write( ('\xff' * (HEADER_SIZE - os.path.getsize(headerPart))).encode(encoding='iso-8859-1') )
|
||||
|
||||
print ('[i] Generating footer ...')
|
||||
|
||||
if (USE_XGIMI_CRC2):
|
||||
# NB XGIMI uses HEADER+BIN+MAGIC+HEADER_CRC to calculate crc2
|
||||
headerCRC = utils.crc32(headerPart)
|
||||
header16bytes = utils.loadPart(headerPart, 0, 16)
|
||||
|
||||
# Step #1. Merge HEADER+BIN+MAGIC+HEADER_CRC to one file
|
||||
mergedPart = os.path.join(tmpDir, '~merged')
|
||||
open(mergedPart, 'w').close()
|
||||
utils.appendFile(headerPart, mergedPart)
|
||||
utils.appendFile(binPart, mergedPart)
|
||||
with open(mergedPart, 'ab') as part:
|
||||
print ('[i] Magic: {}'.format(MAGIC_FOOTER))
|
||||
part.write(MAGIC_FOOTER.encode())
|
||||
print ('[i] Header CRC: 0x{:02X}'.format(headerCRC))
|
||||
part.write(struct.pack('L', headerCRC))
|
||||
|
||||
# Step #2 Calculate CRC2
|
||||
mergedCRC = utils.crc32(mergedPart)
|
||||
with open(footerPart, 'wb') as footer:
|
||||
print ('[i] Merged CRC: 0x{:02X}'.format(mergedCRC))
|
||||
footer.write(struct.pack('L', mergedCRC))
|
||||
print ('[i] First 16 bytes of header: {}'.format(header16bytes))
|
||||
footer.write(header16bytes)
|
||||
|
||||
print ('[i] Merging parts ...')
|
||||
open(firmwareFileName, 'w').close()
|
||||
utils.appendFile(mergedPart, firmwareFileName)
|
||||
utils.appendFile(footerPart, firmwareFileName)
|
||||
else:
|
||||
headerCRC = utils.crc32(headerPart)
|
||||
binCRC = utils.crc32(binPart)
|
||||
header16bytes = utils.loadPart(headerPart, 0, 16)
|
||||
with open(footerPart, 'wb') as footer:
|
||||
print ('[i] Magic: {}'.format(MAGIC_FOOTER))
|
||||
footer.write(MAGIC_FOOTER.encode())
|
||||
print ('[i] Header CRC: 0x{:02X}'.format(headerCRC))
|
||||
footer.write(struct.pack('L', headerCRC)) # struct.pack('L', data) <- returns byte swapped data
|
||||
print ('[i] Bin CRC: 0x{:02X}'.format(binCRC))
|
||||
footer.write(struct.pack('L', binCRC))
|
||||
print ('[i] First 16 bytes of header: {}'.format(header16bytes))
|
||||
footer.write(header16bytes)
|
||||
|
||||
print ('[i] Merging header, bin, footer ...')
|
||||
open(firmwareFileName, 'w').close()
|
||||
utils.appendFile(headerPart, firmwareFileName)
|
||||
utils.appendFile(binPart, firmwareFileName)
|
||||
utils.appendFile(footerPart, firmwareFileName)
|
||||
|
||||
shutil.rmtree(tmpDir)
|
||||
print ('[i] Done')
|
||||
73
mstar-bin-tool/secure_partition.py
Normal file
73
mstar-bin-tool/secure_partition.py
Normal file
@ -0,0 +1,73 @@
|
||||
'''
|
||||
This tool is used to sign (aka generate "secureinfo") and encrypt partition
|
||||
|
||||
Almost all new Mstar builds I saw have SECURITY_BOOT option enebled. Which means it uses AES to
|
||||
encrypt boot.img and recovery.img and RSA to generate signature (Plus multiple internal security updates).
|
||||
|
||||
This script will generate two files: encrypted image and signature file
|
||||
|
||||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
# Command line args
|
||||
if len(sys.argv) == 1:
|
||||
print ("Usage: secure_partition.py <file to encrypt> <AES key file> <RSA private key file> <RSA public key file> <output encrypted file> <output signature file>")
|
||||
print ("Example: secure_partition.py ./pack/boot.img ./keys/AESbootKey ./keys/RSAboot_priv.txt ./keys/RSAboot_pub.txt ./pack/boot.img.aes ./pack/boot.signature.bin")
|
||||
quit()
|
||||
|
||||
INPUT_FILE_NAME = sys.argv[1]
|
||||
AES_KEY = sys.argv[2]
|
||||
RSA_PRIVATE_KEY = sys.argv[3]
|
||||
RSA_PUBLIC_KEY = sys.argv[4]
|
||||
OUTPUT_FILE_NAME = sys.argv[5]
|
||||
OUTPUT_SIGNATURE_FILE_NAME = sys.argv[6]
|
||||
|
||||
# Aditional SubSecureInfoGen params
|
||||
BLOCK_SIZE_FOR_INTERLEAVE = 2097152
|
||||
ENABLE_PARTIAL_AUTHENTICATION = 0 # 0 - disable, 1 - enable
|
||||
NUMBER_FOR_PARTIAL_AUTHENTICATION = 8 # ???
|
||||
ENABLE_INTERLEAVE_MODE = 1 # 0 - disable, 1 - enable
|
||||
DISPLAY_DEBUGGING_INFO = 1 # 0 - disable, 1 - enable
|
||||
|
||||
# Binary tools
|
||||
TOOLS_DIR = 'bin\\win32\\' if os.name == 'nt' else 'bin/linux-x86/'
|
||||
alignment = os.path.join(TOOLS_DIR, 'alignment')
|
||||
SubSecureInfoGen = os.path.join(TOOLS_DIR, 'SubSecureInfoGen')
|
||||
aescrypt2 = os.path.join(TOOLS_DIR, 'aescrypt2')
|
||||
|
||||
|
||||
# Alignment
|
||||
os.system(alignment + ' {}'.format(INPUT_FILE_NAME))
|
||||
|
||||
# Generate signature
|
||||
os.system(SubSecureInfoGen + ' {} {} {} {} {} {} {} {} {} {}'.format(
|
||||
OUTPUT_SIGNATURE_FILE_NAME,
|
||||
INPUT_FILE_NAME,
|
||||
RSA_PRIVATE_KEY,
|
||||
RSA_PUBLIC_KEY,
|
||||
ENABLE_PARTIAL_AUTHENTICATION,
|
||||
NUMBER_FOR_PARTIAL_AUTHENTICATION,
|
||||
ENABLE_INTERLEAVE_MODE,
|
||||
BLOCK_SIZE_FOR_INTERLEAVE,
|
||||
DISPLAY_DEBUGGING_INFO,
|
||||
TOOLS_DIR))
|
||||
|
||||
print (SubSecureInfoGen + ' {} {} {} {} {} {} {} {} {} {}'.format(
|
||||
OUTPUT_SIGNATURE_FILE_NAME,
|
||||
INPUT_FILE_NAME,
|
||||
RSA_PRIVATE_KEY,
|
||||
RSA_PUBLIC_KEY,
|
||||
ENABLE_PARTIAL_AUTHENTICATION,
|
||||
NUMBER_FOR_PARTIAL_AUTHENTICATION,
|
||||
ENABLE_INTERLEAVE_MODE,
|
||||
BLOCK_SIZE_FOR_INTERLEAVE,
|
||||
DISPLAY_DEBUGGING_INFO,
|
||||
TOOLS_DIR))
|
||||
|
||||
|
||||
# Crypt input image
|
||||
os.system(aescrypt2 + ' 0 {} {} {}'.format(INPUT_FILE_NAME, OUTPUT_FILE_NAME, AES_KEY))
|
||||
|
||||
print ("Done")
|
||||
154
mstar-bin-tool/unpack.py
Normal file
154
mstar-bin-tool/unpack.py
Normal file
@ -0,0 +1,154 @@
|
||||
import sys
|
||||
import os
|
||||
import re
|
||||
import shutil
|
||||
|
||||
import utils
|
||||
|
||||
DEBUG = False
|
||||
HEADER_SIZE = 16 * utils.KB # Header size is always 16KB
|
||||
|
||||
# Vars
|
||||
headerScript = ""
|
||||
headerScriptFound = False
|
||||
counter = {}
|
||||
env = {} # Environment variables, set by setenv command
|
||||
|
||||
# Parse args
|
||||
if len(sys.argv) == 1:
|
||||
print ("Usage: unpack.py <firmware> <output folder [default: ./unpacked/]>")
|
||||
quit()
|
||||
|
||||
inputFile = sys.argv[1]
|
||||
if not os.path.exists(inputFile):
|
||||
print ("No such file: {}".format(inputFile))
|
||||
quit()
|
||||
|
||||
if len(sys.argv) == 3:
|
||||
outputDirectory = sys.argv[2]
|
||||
else:
|
||||
outputDirectory = 'unpacked'
|
||||
|
||||
# Create output directory
|
||||
utils.createDirectory(outputDirectory)
|
||||
|
||||
# Find header script
|
||||
# Header size is 16KB
|
||||
# Non used part is filled by 0xFF
|
||||
print ("[i] Analizing header ...")
|
||||
header = utils.loadPart(inputFile, 0, HEADER_SIZE)
|
||||
utils.copyPart(inputFile, os.path.join(outputDirectory, "~header"), 0, HEADER_SIZE)
|
||||
|
||||
offset = header.find('\xff'.encode(encoding='iso-8859-1'))
|
||||
if offset != -1:
|
||||
headerScript = header[:offset].decode()
|
||||
headerScriptFound = True
|
||||
|
||||
if not headerScriptFound:
|
||||
print ("[!] Could not find header script!")
|
||||
quit()
|
||||
|
||||
if DEBUG:
|
||||
print (headerScript)
|
||||
|
||||
# Save the script
|
||||
print ("[i] Saving header script to " + os.path.join(outputDirectory, "~header_script") + " ...")
|
||||
with open(os.path.join(outputDirectory, "~header_script"), "w") as f:
|
||||
f.write(headerScript)
|
||||
|
||||
# Parse script
|
||||
print ("[i] Parsing script ...")
|
||||
# Supporting filepartload, mmc, store_secure_info, store_nuttx_config
|
||||
for line in headerScript.splitlines():
|
||||
|
||||
if DEBUG:
|
||||
print (line)
|
||||
|
||||
if re.match("^setenv", line):
|
||||
params = utils.processSetEnv(line)
|
||||
key = params["key"]
|
||||
if not "value" in params:
|
||||
del env[key]
|
||||
else:
|
||||
value = params["value"]
|
||||
env[key] = value
|
||||
print ("[i] Parsing setenv {} -> {}".format(key, value))
|
||||
|
||||
if re.match("^filepartload", line):
|
||||
line = utils.applyEnv(line, env)
|
||||
params = utils.processFilePartLoad(line)
|
||||
offset = params["offset"]
|
||||
size = params["size"]
|
||||
|
||||
if re.match("^store_secure_info", line):
|
||||
line = utils.applyEnv(line, env)
|
||||
params = utils.processStoreSecureInfo(line)
|
||||
outputFile = os.path.join(outputDirectory, params["partition_name"])
|
||||
utils.copyPart(inputFile, outputFile, int(offset, 16), int(size, 16))
|
||||
|
||||
if re.match("^store_nuttx_config", line):
|
||||
line = utils.applyEnv(line, env)
|
||||
params = utils.processStoreNuttxConfig(line)
|
||||
outputFile = os.path.join(outputDirectory, params["partition_name"])
|
||||
utils.copyPart(inputFile, outputFile, int(offset, 16), int(size, 16))
|
||||
|
||||
if re.match("^mmc", line):
|
||||
line = utils.applyEnv(line, env)
|
||||
params = utils.processMmc(line)
|
||||
|
||||
if params:
|
||||
|
||||
# if params["action"] == "create":
|
||||
# nothing here
|
||||
|
||||
if params["action"] == "write.boot":
|
||||
outputFile = utils.generateFileName(outputDirectory, params, ".img")
|
||||
utils.copyPart(inputFile, outputFile, int(offset, 16), int(size, 16))
|
||||
print ("[i] Partition: {}\tOffset: {}\tSize {} ({}) -> {}".format(params["partition_name"], offset, size, utils.sizeStr(int(size, 16)), outputFile))
|
||||
|
||||
if params["action"] == "write.p":
|
||||
outputFile = os.path.join(outputDirectory, params["partition_name"] + ".img")
|
||||
utils.copyPart(inputFile, outputFile, int(offset, 16), int(size, 16))
|
||||
print ("[i] Partition: {}\tOffset: {}\tSize {} ({}) -> {}".format(params["partition_name"], offset, size, utils.sizeStr(int(size, 16)), outputFile))
|
||||
|
||||
if params["action"] == "write.p.continue":
|
||||
outputFile = os.path.join(outputDirectory, params["partition_name"] + ".img")
|
||||
utils.copyPart(inputFile, outputFile, int(offset, 16), int(size, 16), append = True)
|
||||
print ("[i] Partition: {}\tOffset: {}\tSize {} ({}) append to {}".format(params["partition_name"], offset, size, utils.sizeStr(int(size, 16)), outputFile))
|
||||
|
||||
if params["action"] == "unlzo":
|
||||
outputLzoFile = utils.generateFileName(outputDirectory, params, ".lzo")
|
||||
outputImgFile = utils.generateFileName(outputDirectory, params, ".img")
|
||||
# save .lzo
|
||||
print ("[i] Partition: {}\tOffset: {}\tSize {} ({}) -> {}".format(params["partition_name"], offset, size, utils.sizeStr(int(size, 16)), outputLzoFile))
|
||||
utils.copyPart(inputFile, outputLzoFile, int(offset, 16), int(size, 16))
|
||||
# unpack .lzo -> .img
|
||||
print ("[i] Unpacking LZO (Please be patient) {} -> {}".format(outputLzoFile, outputImgFile))
|
||||
utils.unlzo(outputLzoFile, outputImgFile)
|
||||
# delete .lzo
|
||||
os.remove(outputLzoFile)
|
||||
|
||||
if params["action"] == "unlzo.continue":
|
||||
if not params["partition_name"] in counter:
|
||||
counter[params["partition_name"]] = 0
|
||||
counter[params["partition_name"]] += 1
|
||||
|
||||
outputImgFile = os.path.join(outputDirectory, params["partition_name"] + ".img")
|
||||
outputChunkLzoFile = os.path.join(outputDirectory, params["partition_name"] + str(counter[params["partition_name"]]) + ".lzo")
|
||||
outputChunkImgFile = os.path.join(outputDirectory, params["partition_name"] + str(counter[params["partition_name"]]) + ".img")
|
||||
# save .lzo
|
||||
print ("[i] Partition: {}\tOffset: {}\tSize {} ({}) -> {}".format(params["partition_name"], offset, size, utils.sizeStr(int(size, 16)), outputChunkLzoFile))
|
||||
utils.copyPart(inputFile, outputChunkLzoFile, int(offset, 16), int(size, 16))
|
||||
# unpack chunk .lzo -> .img
|
||||
print ("[i] Unpacking LZO (Please be patient) {} -> {}".format(outputChunkLzoFile, outputChunkImgFile))
|
||||
utils.unlzo(outputChunkLzoFile, outputChunkImgFile)
|
||||
# append the chunk to main .img
|
||||
print ("[i] {} append to {}".format(outputChunkImgFile, outputImgFile))
|
||||
utils.appendFile(outputChunkImgFile, outputImgFile)
|
||||
# delete chunk
|
||||
os.remove(outputChunkLzoFile)
|
||||
os.remove(outputChunkImgFile)
|
||||
|
||||
|
||||
|
||||
|
||||
348
mstar-bin-tool/utils.py
Normal file
348
mstar-bin-tool/utils.py
Normal file
@ -0,0 +1,348 @@
|
||||
import re
|
||||
import os
|
||||
import shutil
|
||||
import string
|
||||
import binascii
|
||||
import math
|
||||
import ctypes
|
||||
|
||||
B = 2**00
|
||||
KB = 2**10
|
||||
MB = 2**20
|
||||
GB = 2**30
|
||||
|
||||
def sizeInt(s):
|
||||
|
||||
value = int(s.strip(string.ascii_letters))
|
||||
unit = s.strip(string.digits)
|
||||
if not unit:
|
||||
unit = 'B'
|
||||
return value * globals()[unit]
|
||||
|
||||
def sizeStr(s):
|
||||
if (s == 0):
|
||||
return '0B'
|
||||
size_name = ('B', 'KB', 'MB', 'GB')
|
||||
i = int(math.floor(math.log(s, 1024)))
|
||||
p = math.pow(1024 ,i)
|
||||
s = round(s / p, 2)
|
||||
return '%s %s' % (s,size_name[i])
|
||||
|
||||
def str2bool(v):
|
||||
return v.lower() in ("yes", "true", "True", "1")
|
||||
|
||||
def bool2int(v):
|
||||
return 1 if v else 0
|
||||
|
||||
def getConfigValue(config, name, defValue):
|
||||
try:
|
||||
value = config[name]
|
||||
except Exception as e:
|
||||
value = defValue
|
||||
return value
|
||||
|
||||
def createDirectory(dir):
|
||||
if not os.path.exists(dir): # if the directory does not exist
|
||||
os.makedirs(dir) # make the directory
|
||||
else: # the directory exists
|
||||
#removes all files in a folder
|
||||
for the_file in os.listdir(dir):
|
||||
file_path = os.path.join(dir, the_file)
|
||||
try:
|
||||
if os.path.isfile(file_path):
|
||||
os.unlink(file_path) # unlink (delete) the file
|
||||
except e:
|
||||
print (e)
|
||||
|
||||
def splitFile(file, destdir, chunksize):
|
||||
(name, ext) = os.path.splitext(os.path.basename(file))
|
||||
chunks = []
|
||||
|
||||
# Just copy file if its size is less than chunk size
|
||||
if os.path.getsize(file) < chunksize or chunksize == 0:
|
||||
chunk = os.path.join(destdir, name + ext)
|
||||
shutil.copyfile(file, chunk)
|
||||
return [chunk]
|
||||
|
||||
# Split in chunks and copy
|
||||
data = True
|
||||
while data:
|
||||
data = loadPart(file, len(chunks) * chunksize, chunksize)
|
||||
if data:
|
||||
chunk = os.path.join(destdir, ('%s.%04d%s' % (name, len(chunks), ext)))
|
||||
chunks.append(chunk)
|
||||
with open(chunk, 'wb') as f2:
|
||||
f2.write(data)
|
||||
|
||||
assert len(chunks) <= 9999
|
||||
return chunks
|
||||
|
||||
# Append src file to dest file
|
||||
# bufsize - chunk size
|
||||
def appendFile(src, dest, bufsize = 16 * MB):
|
||||
with open(src, 'rb') as f1:
|
||||
with open(dest, 'ab') as f2:
|
||||
data = True
|
||||
while data:
|
||||
data = f1.read(bufsize)
|
||||
f2.write(data)
|
||||
|
||||
# Copy part of src file to dest file.
|
||||
# offset - beginning of the part to copy
|
||||
# size - length of the part to copy
|
||||
# bufsize - chunk size
|
||||
# append - if True then append to dest file
|
||||
# if dest file does not exist it will be created
|
||||
def copyPart(src, dest, offset, size, bufsize = 16 * MB, append = False):
|
||||
if not os.path.exists(dest):
|
||||
append = False
|
||||
|
||||
with open(src, 'rb') as f1:
|
||||
f1.seek(offset)
|
||||
with open(dest, 'ab' if append else 'wb') as f2:
|
||||
while size:
|
||||
chunk = min(bufsize, size)
|
||||
data = f1.read(chunk)
|
||||
f2.write(data)
|
||||
size -= chunk
|
||||
|
||||
# Load and return part
|
||||
# file - source file
|
||||
# offset - beginning of the part
|
||||
# size - length of the part
|
||||
def loadPart(file, offset, size):
|
||||
with open(file, 'rb') as f:
|
||||
f.seek(offset)
|
||||
return f.read(size)
|
||||
|
||||
# Align file
|
||||
# file - input file to align
|
||||
# base - alignment base
|
||||
def alignFile(file, base = 0x1000):
|
||||
result = base - os.path.getsize(file) % base
|
||||
if result:
|
||||
with open(file, 'ab') as f:
|
||||
f.write(('\xff' * result).encode(encoding='iso-8859-1'))
|
||||
|
||||
# unlzo
|
||||
# if NT then use ./bin/lzo.exe
|
||||
def unlzo(src, dest):
|
||||
lzop = 'bin\\win32\\lzop.exe' if os.name == 'nt' else 'bin/linux-x86/lzop'
|
||||
os.system(lzop + ' -o {} -d {}'.format(dest, src))
|
||||
|
||||
# lzo
|
||||
# if NT then use ./bin/lzo.exe
|
||||
def lzo(src, dest):
|
||||
lzop = 'bin\\win32\\lzop.exe' if os.name == 'nt' else 'bin/linux-x86/lzop'
|
||||
os.system(lzop + ' -o {} -1 {}'.format(dest, src))
|
||||
|
||||
# Calculate crc32
|
||||
# file - filename of a file to calculate
|
||||
def crc32(file):
|
||||
buf = open(file,'rb').read()
|
||||
buf = (binascii.crc32(buf) & 0xFFFFFFFF)
|
||||
return buf
|
||||
|
||||
# Apply env variable to line, i.e.
|
||||
# setenv imageSize 0x13800
|
||||
# setenv imageOffset 0x4000
|
||||
# filepartload 0x20200000 LetvUpgrade938.bin $(imageOffset) $(imageSize)
|
||||
# So we replace it to filepartload 0x20200000 LetvUpgrade938.bin 0x4000 0x13800
|
||||
def applyEnv(line, env):
|
||||
keys = re.findall('\$\((\w+)\)', line)
|
||||
for key in keys:
|
||||
if key in env and env[key]:
|
||||
line = line.replace("$({})".format(key), env[key])
|
||||
return line
|
||||
|
||||
def processSetEnv(line):
|
||||
args = re.findall('([^\s]+)\s+([^\s]+)\s*(.*)', line)
|
||||
args = args[0]
|
||||
if len(args) == 3:
|
||||
return {'cmd': args[0], 'key': args[1], 'value': args[2]}
|
||||
else:
|
||||
return {'cmd': args[0], 'key': args[1]}
|
||||
|
||||
def parceArgs(string):
|
||||
return re.findall('([^\s]+)', string)
|
||||
|
||||
def processFilePartLoad(line):
|
||||
args = parceArgs(line)
|
||||
return {'cmd': args[0], 'addr': args[1], 'sourceFile': args[2], 'offset': args[3], 'size': args[4]}
|
||||
|
||||
def processStoreSecureInfo(line):
|
||||
args = parceArgs(line)
|
||||
return {'cmd': args[0], 'partition_name': args[1], 'addr': args[2]}
|
||||
|
||||
def processStoreNuttxConfig(line):
|
||||
args = parceArgs(line)
|
||||
return {'cmd': args[0], 'partition_name': args[1], 'addr': args[2]}
|
||||
|
||||
def processMmc(line):
|
||||
args = parceArgs(line)
|
||||
|
||||
if args[1] == 'create':
|
||||
# mmc create [name] [size]- create/change mmc partition [name]
|
||||
return {'cmd': args[0], 'action': args[1], 'partition_name': args[2], 'size': args[3]}
|
||||
|
||||
if args[1] == 'erase.p':
|
||||
# mmc erase.p partition_name
|
||||
return {'cmd': args[0], 'action': args[1], 'partition_name': args[2]}
|
||||
# TODO Add support:
|
||||
# mmc create.gp part_no size enh_attr ext_attr relwr_attr - create/change eMMC GP partition No.[part_no(0~3)] with size and enhance/extended/reliable_write attribute
|
||||
# mmc create.enhusr start_addr size enha_attr relwr_atrr - create/change eMMC enhance user partition(slc mode) from start_addr with size and enhance/reliable_write attribute
|
||||
# mmc create.complete - complete eMMC gp, enhance user, reliable write partition setting
|
||||
|
||||
|
||||
elif args[1] == 'write.p':
|
||||
# mmc write.p addr partition_name size [empty_skip:0-disable,1-enable]
|
||||
res = {'cmd': args[0], 'action': args[1], 'addr': args[2], 'partition_name': args[3], 'size': args[4]}
|
||||
try:
|
||||
res['empty_skip'] = args[5]
|
||||
except IndexError:
|
||||
res['empty_skip'] = 0
|
||||
return res
|
||||
|
||||
elif args[1] == 'write.p.continue' or args[1] == 'write.p.cont':
|
||||
# mmc write.p(.continue|.cont) addr partition_name offset size [empty_skip:0-disable,1-enable]\n
|
||||
res = {'cmd': args[0], 'action': 'write.p.continue', 'addr': args[2], 'partition_name': args[3], 'offset': args[4], 'size': args[5]}
|
||||
try:
|
||||
res['empty_skip'] = args[6]
|
||||
except IndexError:
|
||||
res['empty_skip'] = 0
|
||||
return res
|
||||
|
||||
|
||||
elif args[1] == 'write.boot' or args[1] == 'write':
|
||||
# mmc write[.boot] bootpart addr blk# size [empty_skip:0-disable,1-enable]
|
||||
res = {'cmd': args[0], 'action': args[1], 'bootpart': args[2], 'addr': args[3], 'blk#': args[4], 'size': args[5], 'partition_name': 'sboot'}
|
||||
try:
|
||||
res['empty_skip'] = args[6]
|
||||
except IndexError:
|
||||
res['empty_skip'] = 0
|
||||
return res
|
||||
|
||||
elif args[1] == 'unlzo':
|
||||
# mmc unlzo[.continue|.cont] addr size partition_name [empty_skip:0-disable,1-enable]- decompress lzo file and write to mmc partition
|
||||
res = {'cmd': args[0], 'action': args[1], 'addr': args[2], 'size': args[3], 'partition_name': args[4]}
|
||||
try:
|
||||
res['empty_skip'] = args[5]
|
||||
except IndexError:
|
||||
res['empty_skip'] = 0
|
||||
return res
|
||||
|
||||
elif args[1] == 'unlzo.continue' or args[1] == 'unlzo.cont':
|
||||
# mmc unlzo[.continue|.cont] addr size partition_name [empty_skip:0-disable,1-enable]- decompress lzo file and write to mmc partition
|
||||
res = {'cmd': args[0], 'action': 'unlzo.continue', 'addr': args[2], 'size': args[3], 'partition_name': args[4]}
|
||||
try:
|
||||
res['empty_skip'] = args[5]
|
||||
except IndexError:
|
||||
res['empty_skip'] = 0
|
||||
return res
|
||||
|
||||
# else:
|
||||
# print 'Unknown mmc action'
|
||||
# print args
|
||||
|
||||
|
||||
# TODO rewrite it
|
||||
fileNameCounter = {}
|
||||
def generateFileName(outputDirectory, part, ext):
|
||||
fileName = os.path.join(outputDirectory, part['partition_name'] + ext)
|
||||
if os.path.exists(fileName):
|
||||
try:
|
||||
fileNameCounter[part['partition_name']] += 1
|
||||
except:
|
||||
fileNameCounter[part['partition_name']] = 1
|
||||
fileName = os.path.join(outputDirectory, part['partition_name'] + str(fileNameCounter[part['partition_name']]) + ext)
|
||||
return fileName
|
||||
|
||||
def directive(header, dramBufAddr, useHexValuesPrefix):
|
||||
|
||||
def filepartload(filename, offset, size, memoryOffset=dramBufAddr):
|
||||
if (useHexValuesPrefix):
|
||||
header.write('filepartload 0x{} {} 0x{} 0x{}\n'.format(memoryOffset, filename, offset, size).encode())
|
||||
else:
|
||||
header.write('filepartload {} {} {} {}\n'.format(memoryOffset, filename, offset, size).encode())
|
||||
|
||||
# Create directive always uses 0x format
|
||||
def create(name, size):
|
||||
#if (useHexValuesPrefix):
|
||||
header.write('mmc create {} 0x{}\n'.format(name, size).encode())
|
||||
#else:
|
||||
# header.write('mmc create {} {}\n'.format(name, size).encode())
|
||||
|
||||
def erase_p(name):
|
||||
header.write('mmc erase.p {}\n'.format(name).encode())
|
||||
|
||||
# mmc unlzo[.continue|.cont] addr size partition_name [empty_skip:0-disable,1-enable]- decompress lzo file and write to mmc partition
|
||||
def unlzo(name, size, memoryOffset=dramBufAddr, emptySkip = 1):
|
||||
if (useHexValuesPrefix):
|
||||
header.write('mmc unlzo 0x{} 0x{} {} {}\n'.format(memoryOffset, size, name, emptySkip).encode())
|
||||
else:
|
||||
header.write('mmc unlzo {} {} {} {}\n'.format(memoryOffset, size, name, emptySkip).encode())
|
||||
|
||||
# mmc unlzo[.continue|.cont] addr size partition_name [empty_skip:0-disable,1-enable]- decompress lzo file and write to mmc partition
|
||||
def unlzo_cont(name, size, memoryOffset=dramBufAddr, emptySkip = 1):
|
||||
if (useHexValuesPrefix):
|
||||
header.write('mmc unlzo.cont 0x{} 0x{} {} {}\n'.format(memoryOffset, size, name, emptySkip).encode())
|
||||
else:
|
||||
header.write('mmc unlzo.cont {} {} {} {}\n'.format(memoryOffset, size, name, emptySkip).encode())
|
||||
|
||||
# mmc write.p addr partition_name size [empty_skip:0-disable,1-enable]
|
||||
def write_p(name, size, memoryOffset=dramBufAddr, emptySkip = 1):
|
||||
if (useHexValuesPrefix):
|
||||
header.write('mmc write.p 0x{} {} 0x{} {}\n'.format(memoryOffset, name, size, emptySkip).encode())
|
||||
else:
|
||||
header.write('mmc write.p {} {} {} {}\n'.format(memoryOffset, name, size, emptySkip).encode())
|
||||
|
||||
# TODO Add support
|
||||
# mmc write.p(.continue|.cont) addr partition_name offset size [empty_skip:0-disable,1-enable]
|
||||
|
||||
def store_secure_info(name, memoryOffset=dramBufAddr):
|
||||
if (useHexValuesPrefix):
|
||||
header.write('store_secure_info {} 0x{}\n'.format(name, memoryOffset).encode())
|
||||
else:
|
||||
header.write('store_secure_info {} {}\n'.format(name, memoryOffset).encode())
|
||||
|
||||
def store_nuttx_config(name, memoryOffset=dramBufAddr):
|
||||
if (useHexValuesPrefix):
|
||||
header.write('store_nuttx_config {} 0x{}\n'.format(name, memoryOffset).encode())
|
||||
else:
|
||||
header.write('store_nuttx_config {} {}\n'.format(name, memoryOffset).encode())
|
||||
|
||||
# mmc write[.boot|.gp] [bootpart|gppart] addr blk# size [empty_skip:0-disable,1-enable]
|
||||
def write_boot(size, memoryOffset=dramBufAddr, emptySkip = 0):
|
||||
if (useHexValuesPrefix):
|
||||
header.write('mmc write.boot 1 0x{} 0 0x{} {}\n'.format(memoryOffset, size, emptySkip).encode())
|
||||
else:
|
||||
header.write('mmc write.boot 1 {} 0 {} {}\n'.format(memoryOffset, size, emptySkip).encode())
|
||||
|
||||
#####
|
||||
|
||||
directive.filepartload = filepartload
|
||||
directive.create = create
|
||||
directive.erase_p = erase_p
|
||||
directive.unlzo = unlzo
|
||||
directive.unlzo_cont = unlzo_cont
|
||||
directive.write_p = write_p
|
||||
directive.store_secure_info = store_secure_info
|
||||
directive.store_nuttx_config = store_nuttx_config
|
||||
directive.write_boot = write_boot
|
||||
return directive
|
||||
|
||||
def hexString(v, delimiter = ' '):
|
||||
return (delimiter.join([format(i, '02X') for i in v]))
|
||||
|
||||
def unpackStructure(s, b):
|
||||
result = s()
|
||||
ctypes.memmove(ctypes.addressof(result), b, ctypes.sizeof(s))
|
||||
return result
|
||||
|
||||
def writeFile(file, data):
|
||||
with open(file, 'wb') as f:
|
||||
f.write(data)
|
||||
|
||||
def writeRSAPublicKey(file, key):
|
||||
writeFile(file,
|
||||
str.encode( "N = {}\nE = {}".format(hexString(key.N, ''), hexString(key.E, '')) ))
|
||||
Loading…
Reference in New Issue
Block a user