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.
244 lines
6.7 KiB
Python
244 lines
6.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
|
|
from envbuffer import EnvBuffer
|
|
|
|
|
|
def breed_boot_change(gw, dev, fw_num, fw_addr, fw_name):
|
|
if dev is None:
|
|
dev = read_info.DevInfo(verbose = 0, infolevel = 1)
|
|
if fw_num is not None:
|
|
pname = 'kernel%d' % fw_num
|
|
p = dev.get_part_num(pname)
|
|
if p < 0:
|
|
die('Partition "{}" not found!)'.format(pname))
|
|
fw_addr = dev.partlist[p]['addr']
|
|
if not fw_addr:
|
|
if len(fw_name) < 4:
|
|
die('Incorrect boot partition name! (len: {})'.format(len(fw_name)))
|
|
p = dev.get_part_num(fw_name)
|
|
if p <= 0:
|
|
die('Partition "{}" not found!)'.format(fw_name))
|
|
fw_addr = dev.partlist[p]['addr']
|
|
#dev.verbose = 2
|
|
if dev.env.breed.data is None:
|
|
dev.get_env_list()
|
|
env = dev.env.breed
|
|
if env.data is None or env.max_size is None:
|
|
die("Can't found breed env address!")
|
|
env.var['autoboot.command'] = "boot flash 0x%X" % fw_addr
|
|
cmdline = 'uart_en=1'
|
|
if 'linux.cmdline' in env.var:
|
|
cmdline = env.var['linux.cmdline']
|
|
if 'uart_en=' in cmdline:
|
|
cmdline = cmdline.replace('uart_en=0', 'uart_en=1')
|
|
else:
|
|
cmdline += ' uart_en=1'
|
|
env.var['linux.cmdline'] = cmdline
|
|
print("Breed ENV params for update:")
|
|
for i, (k, v) in enumerate(env.var.items()):
|
|
v = '' if (v is None) else ('=' + v)
|
|
print(" " + k + v)
|
|
bufsize = env.max_size
|
|
buf = env.pack(bufsize)
|
|
buf = b'ENV\x00' + buf[4:]
|
|
#print("env =", buf[:128])
|
|
data = env.data[0:env.offset] + buf + env.data[(env.offset + len(buf)):]
|
|
fn_local = 'tmp/env_breed.bin'
|
|
fn_remote = '/tmp/env_breed.bin'
|
|
with open(fn_local, "wb") as file:
|
|
file.write(data)
|
|
gw.upload(fn_local, fn_remote)
|
|
pe = dev.get_part_num(env.addr, '#')
|
|
if pe < 0:
|
|
die('Partition for writing ENV {} not found!'.format("0x%08X" % env.addr))
|
|
part_addr = dev.partlist[pe]['addr']
|
|
part_name = dev.partlist[pe]['name']
|
|
cmd = 'mtd write {bin} "{part}"'.format(bin=fn_remote, part=part_name)
|
|
print("Send command: {}".format(cmd))
|
|
gw.run_cmd(cmd)
|
|
print('Breed ENV changed! Boot from {} activated.'.format("0x%08X" % fw_addr))
|
|
gw.run_cmd("rm -f " + fn_remote)
|
|
return fw_addr
|
|
|
|
|
|
def uboot_boot_change(gw, fw_num):
|
|
if fw_num != 0 and fw_num != 1:
|
|
die("Boot partition number not correct! Must be 0 or 1!")
|
|
cmd = []
|
|
cmd.append("nvram set flag_ota_reboot=0")
|
|
cmd.append("nvram set flag_boot_success=1")
|
|
cmd.append("nvram set flag_last_success={}".format(fw_num))
|
|
cmd.append("nvram set flag_try_sys1_failed=0")
|
|
cmd.append("nvram set flag_try_sys2_failed=0")
|
|
cmd.append("nvram set flag_boot_rootfs={}".format(fw_num))
|
|
cmd.append("nvram commit")
|
|
gw.run_cmd(cmd)
|
|
return True
|
|
|
|
|
|
if __name__ == "__main__":
|
|
gw = gateway.Gateway()
|
|
dev = read_info.DevInfo(verbose = 0, infolevel = 1)
|
|
dev.get_bootloader()
|
|
if not dev.bl.img:
|
|
die("Can't dump current bootloader!")
|
|
|
|
for i, part in enumerate(dev.partlist):
|
|
print(' %2d > addr: 0x%08X size: 0x%08X name: "%s"' % (i, part['addr'], part['size'], part['name']))
|
|
|
|
if len(sys.argv) > 1:
|
|
fw_name = sys.argv[1]
|
|
else:
|
|
if dev.bl.type == 'breed':
|
|
print("The device has an Breed bootloader installed.")
|
|
print("It is possible to specify a specific kernel boot address (HEX-number).")
|
|
print("It is also possible to specify the kernel number or the name of its partition.")
|
|
fw_name = input("Enter kernel (number, address or name): ")
|
|
else:
|
|
fw_name = input("Enter kernel number (0 or 1): ")
|
|
|
|
fw_name = fw_name.strip()
|
|
if fw_name == "":
|
|
die("Boot partition not specified!")
|
|
|
|
fw_num = None
|
|
fw_addr = None
|
|
if len(fw_name) >= 6 and fw_name.lower().startswith('0x'):
|
|
fw_addr = int(fw_name, 16)
|
|
else:
|
|
try:
|
|
fw_num = int(fw_name)
|
|
if fw_num != 0 and fw_num != 1:
|
|
die("Boot partition number not correct! Must be 0 or 1!")
|
|
except Exception:
|
|
pass
|
|
|
|
#if dev.bl.type == 'pandora':
|
|
# die('Pandora bootloader not supported!')
|
|
|
|
if dev.bl.type == 'breed':
|
|
fw_addr = breed_boot_change(gw, dev, fw_num, fw_addr, fw_name)
|
|
if fw_name != '0' and fw_name != '1':
|
|
sys.exit(0)
|
|
fw_addr = None
|
|
|
|
fw_num = None
|
|
try:
|
|
fw_num = int(fw_name)
|
|
except Exception:
|
|
pass
|
|
|
|
if fw_addr:
|
|
die('Required Breed bootloader for set custom boot address!')
|
|
|
|
if fw_num is None:
|
|
die("Boot partition not specified!")
|
|
|
|
print("Run scripts for change NVRAM params...")
|
|
uboot_boot_change(gw, fw_num)
|
|
print('Ready! Boot from partition "kernel{}" activated.'.format(fw_num))
|
|
|
|
|
|
'''
|
|
/*** Algorithm from stock uboot: ***/
|
|
|
|
#define OK 0
|
|
|
|
if ( flag_try_sys1_failed > 1 || flag_try_sys2_failed > 1 || flag_ota_reboot > 1 || flag_last_success > 1 )
|
|
goto boot_rootfs0;
|
|
|
|
if ( flag_try_sys1_failed == 1 && flag_try_sys2_failed == 1 )
|
|
{
|
|
if ( verifying_kernel0() == OK )
|
|
goto boot_rootfs0;
|
|
|
|
if ( verifying_kernel1() == OK )
|
|
goto boot_rootfs1;
|
|
}
|
|
|
|
if ( flag_ota_reboot == 1 )
|
|
{
|
|
flag_last_success = 1 - flag_last_success;
|
|
}
|
|
else
|
|
{
|
|
if ( flag_last_success == 0 )
|
|
flag_try_sys2_failed = flag_try_sys1_failed;
|
|
|
|
if ( flag_try_sys2_failed == 1 )
|
|
flag_last_success = 1 - flag_last_success;
|
|
}
|
|
|
|
if ( flag_last_success == 0 )
|
|
goto boot_rootfs0;
|
|
else
|
|
goto boot_rootfs1;
|
|
|
|
boot_rootfs1:
|
|
img_addr = 0x600000 // kernel1
|
|
flag_boot_rootfs = 1;
|
|
goto boot;
|
|
|
|
boot_rootfs0:
|
|
img_addr = 0x200000 // kernel0
|
|
flag_boot_rootfs = 0;
|
|
goto boot;
|
|
|
|
boot:
|
|
setenv("flag_boot_rootfs", flag_boot_rootfs);
|
|
factory_mode = 0;
|
|
crash_log_magic = 0;
|
|
ranand_read(&crash_log_magic, 0x140000, 4);
|
|
if ( crash_log_magic == 0x5AA5 )
|
|
{
|
|
factory_mode = 1;
|
|
printf("System is in factory mode.\n");
|
|
setenv("uart_en", "1");
|
|
setenv("boot_wait", "on");
|
|
}
|
|
saveenv();
|
|
ranand_read(img_header, img_addr, 64);
|
|
img_header_magic = ntohl(*(uint32_t *)img_header)
|
|
if ( img_header_magic != 0x27051956 )
|
|
{
|
|
printf("Bad Magic Number,%08X, try to reboot\n", img_header_magic);
|
|
goto bad_data;
|
|
}
|
|
if ( getenv("verify") != 'n' ) {
|
|
if ( verify_image(img_addr) != OK )
|
|
printf("Bad Data CRC\n");
|
|
goto bad_data;
|
|
}
|
|
}
|
|
|
|
do_bootm_linux(...)
|
|
|
|
bad_data:
|
|
if ( flag_boot_rootfs == 0 )
|
|
setenv("flag_try_sys1_failed", "1");
|
|
else
|
|
setenv("flag_try_sys2_failed", "1");
|
|
|
|
setenv("flag_ota_reboot", "0");
|
|
saveenv();
|
|
if ( factory_mode )
|
|
{
|
|
printf("System is in factory mode. U-Boot BOOT ERROR! \n");
|
|
nullsub_4();
|
|
while ( 1 ) // HARD CPU RESTART
|
|
;
|
|
}
|
|
return CRITICAL_ERROR
|
|
|
|
'''
|
|
|
|
|