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

#!/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
'''