You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
96 lines
2.7 KiB
Python
96 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
# -*- coding: utf-8 -*-
|
|
|
|
import os
|
|
import sys
|
|
|
|
import xmir_base
|
|
import gateway
|
|
from gateway import die
|
|
import read_info
|
|
|
|
|
|
if len(sys.argv) <= 1:
|
|
die("Bootloader name not specified!")
|
|
bl_name = sys.argv[1]
|
|
bl_name = bl_name.strip().lower()
|
|
|
|
|
|
gw = gateway.Gateway()
|
|
dn = gw.device_name
|
|
if not gw.device_name:
|
|
die("Xiaomi Mi Wi-Fi device not found! (IP: {})".format(gateway.ip_addr))
|
|
|
|
fn_dir = 'bootloader/'
|
|
fn_remote = '/tmp/bootloader.bin'
|
|
fn_local = None
|
|
|
|
if bl_name == 'breed':
|
|
supported_devices = ['R3G', 'R3P', 'RM2100', 'RA71', 'CR6606', 'CR6608', 'CR6609', 'TR609', 'TR608']
|
|
if dn not in supported_devices:
|
|
die("Breed bootloader cannot be installed on this device!")
|
|
if dn in ['CR6606', 'CR6608', 'CR6609', 'TR609', 'TR608']:
|
|
fn_local = fn_dir + 'pb-boot-cr660x.img'
|
|
else:
|
|
fn_local = fn_dir + 'breed_r3g_eng.bin'
|
|
|
|
if bl_name == 'uboot':
|
|
fn_local = fn_dir + 'uboot_{}.bin'.format(dn)
|
|
|
|
if not fn_local:
|
|
die('Incorrect bootloader name!')
|
|
|
|
if not os.path.exists(fn_local):
|
|
die('File "{}" not found'.format(fn_local))
|
|
|
|
dev = read_info.DevInfo(verbose = 0, infolevel = 1)
|
|
if dev.info.cpu_arch != 'mips':
|
|
die("Currently support only MIPS arch!")
|
|
|
|
dev.get_bootloader()
|
|
if not dev.bl.img:
|
|
die("Can't dump current bootloader!")
|
|
|
|
if dev.bl.spi_rom:
|
|
die("Not support SPI Flash ROM! (now supported only NAND)")
|
|
|
|
addr = None
|
|
name = None
|
|
size = None
|
|
|
|
# Find bootloader partition (typically at address 0, but skip large "ALL" partitions)
|
|
for p, part in enumerate(dev.partlist):
|
|
if part['addr'] == 0 and part['size'] > 0x00800000: # 8MiB
|
|
continue # skip "ALL" part
|
|
if part['addr'] == 0:
|
|
name = part['name']
|
|
fname = ''.join(e for e in name if e.isalnum())
|
|
addr = part['addr']
|
|
size = part['size']
|
|
break # Take the first valid partition found
|
|
|
|
if addr is None:
|
|
die("No matching partition found!")
|
|
|
|
# Validate that we have a proper partition name before proceeding
|
|
if not name:
|
|
die("Invalid partition name found!")
|
|
|
|
print('Selected partition: "{}" at address 0x{:08X} (size: 0x{:08X})'.format(name, addr, size))
|
|
|
|
# Upload bootloader file to device
|
|
try:
|
|
gw.upload(fn_local, fn_remote)
|
|
except Exception as e:
|
|
die('Failed to upload bootloader file: {}'.format(str(e)))
|
|
|
|
print('Writing data to partition "{}" (addr: {}) ...'.format(name, "0x%08X" % addr))
|
|
|
|
# Write bootloader to partition with error handling
|
|
try:
|
|
gw.run_cmd('mtd write {bin} "{name}"'.format(bin=fn_remote, name=name))
|
|
except Exception as e:
|
|
die('Failed to write bootloader to partition: {}'.format(str(e)))
|
|
|
|
print('Ready! Bootloader "{}" installation is complete.'.format(bl_name))
|