Compare commits
10 Commits
80d6120246
...
3b73d64861
Author | SHA1 | Date | |
---|---|---|---|
![]() |
3b73d64861 | ||
![]() |
c4eee52fb9 | ||
![]() |
285f9a516e | ||
![]() |
e1fbee6ef1 | ||
![]() |
a5a514b752 | ||
![]() |
a749155a8b | ||
![]() |
2ded79544b | ||
![]() |
e86adb63c9 | ||
![]() |
e2649fd66e | ||
![]() |
faa480ed9f |
@@ -10,3 +10,8 @@
|
||||
2024.10.15
|
||||
烧录文件可能会加密,bin的第一个字节表示加密方式 第二个字节表示加密种子,加密算法根据这个种子来计算
|
||||
好像加密方式都用的方式3 异或,所以取第一个字节与3异或就能得到加密种子
|
||||
|
||||
2025.8.11
|
||||
添加计算bootram password的脚本 进入bootram之后,输入 f i 查看chip id
|
||||
然后运行python pass.py chip_id 计算password
|
||||
然后在bootram中输入 PSS password 来解除限制
|
@@ -47,6 +47,7 @@ _DevType={
|
||||
0x01:"devV1kunlun1",
|
||||
0x02:"devV1kunlun2",
|
||||
0x03:"devV1kunlun3",
|
||||
0x04:"devV1Pangu",
|
||||
0xFF:"devV1Max"
|
||||
}
|
||||
|
||||
|
BIN
bin/bootram_kl4.bin
Normal file
BIN
bin/bootram_kl4.bin
Normal file
Binary file not shown.
113
bin/get_log.py
Normal file
113
bin/get_log.py
Normal file
@@ -0,0 +1,113 @@
|
||||
import os
|
||||
import sys
|
||||
import struct
|
||||
import dataclasses
|
||||
from bin.log import myprint
|
||||
from bin.log import mywrite
|
||||
|
||||
STR_YELLOW="\033[0;33m"
|
||||
STR_END="\033[0m"
|
||||
|
||||
|
||||
@dataclasses.dataclass
|
||||
class cli_msg_hdr_t:
|
||||
src_mac:bytearray
|
||||
target_mac:bytearray
|
||||
module_id:int
|
||||
cli_crc:int
|
||||
msg_id:int
|
||||
auto_ack:int
|
||||
reserved2:int
|
||||
msg_len:int
|
||||
sn:int
|
||||
@classmethod
|
||||
def __init__(self, data:bytearray):
|
||||
self.src_mac=data[0:6]
|
||||
self.target_mac=data[6:12]
|
||||
self.module_id=struct.unpack("<H", data[12:14])[0]
|
||||
self.cli_crc=struct.unpack("<H", data[14:16])[0]
|
||||
self.msg_id=struct.unpack("<H", data[16:18])[0]
|
||||
self.auto_ack=struct.unpack("<B", data[18:19])[0]&0x01
|
||||
self.reserved2=struct.unpack("<B", data[19:20])[0]
|
||||
self.msg_len=struct.unpack("<H", data[20:22])[0]
|
||||
self.sn=struct.unpack("<H", data[22:24])[0]
|
||||
|
||||
@dataclasses.dataclass
|
||||
class payload_t:
|
||||
fw_version:int
|
||||
time_stamp:int
|
||||
seq:int
|
||||
mod_msg:int
|
||||
payload_len:int
|
||||
@classmethod
|
||||
def __init__(self, data:bytearray):
|
||||
self.fw_version=struct.unpack("<I", data[0:4])[0]
|
||||
self.time_stamp=struct.unpack("<I", data[4:8])[0]
|
||||
self.seq=struct.unpack("<I", data[8:12])[0]
|
||||
self.mod_msg=struct.unpack("<I", data[12:16])[0]
|
||||
self.payload_len=struct.unpack("<I", data[16:20])[0]>>16
|
||||
|
||||
|
||||
|
||||
|
||||
def get_log(log_file:str):
|
||||
with open(log_file, 'rb') as f:
|
||||
data=f.read()
|
||||
save=data[0x143000:0x144580]
|
||||
with open("save.bin", 'wb+') as f:
|
||||
f.write(save)
|
||||
|
||||
def find_log(data):
|
||||
for i in range(0, len(data), 0x20):
|
||||
if data[i:i+2]==b'$$':
|
||||
myprint(f"log offset={hex(i)}")
|
||||
return i
|
||||
return -1
|
||||
|
||||
|
||||
def print_log(log_file:str):
|
||||
with open(log_file, 'rb') as f:
|
||||
data=f.read()
|
||||
off=0
|
||||
# addr表示相对于bin文件的地址
|
||||
addr=off
|
||||
if(off<0):
|
||||
myprint("not found log")
|
||||
return
|
||||
data=data[off:]
|
||||
while len(data)>0:
|
||||
off=data.find(b'$$')
|
||||
if(off<0):
|
||||
break
|
||||
addr+=off
|
||||
myprint(f"off={hex(addr)}")
|
||||
data=data[off+2:]
|
||||
addr+=2
|
||||
end=data.find(b'&&')
|
||||
if(end<0):
|
||||
break
|
||||
a=cli_msg_hdr_t(data[0:24])
|
||||
# msg_len减去的是payload的长度
|
||||
myprint(f"msg_len={a.msg_len-20}")
|
||||
if(a.msg_len!=end-24):
|
||||
myprint(f"msg_len error")
|
||||
continue
|
||||
# a=payload_t(data[24:44])
|
||||
# print(a)
|
||||
pstr=data[44:end]
|
||||
for i in range(len(pstr)):
|
||||
if(pstr[i]&0x80):
|
||||
pstr=pstr[:i]
|
||||
break
|
||||
try:
|
||||
mywrite(f"{pstr.decode('utf-8')}")
|
||||
except:
|
||||
mywrite(f"{pstr}")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) != 2:
|
||||
print("Usage: python get_log.py <log_file>")
|
||||
sys.exit(1)
|
||||
log_file = sys.argv[1]
|
||||
print_log(log_file)
|
Binary file not shown.
Binary file not shown.
BIN
bin/kl4_ram_build.bin
Normal file
BIN
bin/kl4_ram_build.bin
Normal file
Binary file not shown.
@@ -5,6 +5,11 @@ import sys
|
||||
# 同一个进程中所有调用这个文件的 .py 文件都使用这个变量
|
||||
_log_fp=None
|
||||
|
||||
STR_RED="\033[0;31m"
|
||||
STR_BLUE="\033[0;34m"
|
||||
STR_YELLOW="\033[0;33m"
|
||||
STR_END="\033[0m"
|
||||
|
||||
def _time():
|
||||
return '['+time.strftime("%Y-%m-%d %H:%M:%S")+']'
|
||||
|
||||
@@ -30,7 +35,7 @@ def mywrite(data:str):
|
||||
txt=txt.replace('\n\n','\n')
|
||||
_log_fp.write(txt)
|
||||
_log_fp.flush()
|
||||
sys.stdout.write(data)
|
||||
sys.stdout.write(f"{STR_YELLOW}{data}{STR_END}")
|
||||
sys.stdout.flush()
|
||||
|
||||
def log_init(file_name:str):
|
||||
|
103
kunlun.py
103
kunlun.py
@@ -12,6 +12,7 @@ import os
|
||||
import binascii
|
||||
import threading
|
||||
import argparse
|
||||
import base64
|
||||
from bin.log import myprint
|
||||
from bin.log import log_init
|
||||
from bin.log import mywrite
|
||||
@@ -22,6 +23,9 @@ from bin.bin_to_hex import load_flash_info
|
||||
from bin.bin_to_hex import check_bin_type
|
||||
from bin.base import bin_path
|
||||
from bin.factory_mode import ftm_handle
|
||||
from bin.crc import CRC16
|
||||
from bin.get_log import print_log
|
||||
from password import bootram_pssword
|
||||
|
||||
|
||||
def init_send(s_port:serial.Serial, send_str:str):
|
||||
@@ -29,7 +33,7 @@ def init_send(s_port:serial.Serial, send_str:str):
|
||||
send_str=send_str.encode('utf-8')
|
||||
key_words={
|
||||
b"WQKL":b"Recieving RAM-IMAGE in xmodem : C",
|
||||
b"HZPG":b"waiting recieve image: C"
|
||||
b"HZPG":b"waiting receive image: C"
|
||||
}
|
||||
while True:
|
||||
s_port.write(send_str)
|
||||
@@ -73,7 +77,7 @@ def burn_flash_bin(s_port:serial.Serial, x_modem:xmodem.XMODEM, f_file):
|
||||
continue
|
||||
print_device_str(tmp)
|
||||
s_info += tmp
|
||||
if(s_info.find(b'CCC')>=0 and bytes2read==1):
|
||||
if(s_info.find(b'CCC')>=0 and bytes2read==1) or (s_info.find(b'Recieving FLASH-IMAGE in xmodem : C')>=0):
|
||||
m_flash=True
|
||||
else:
|
||||
m_flash=False
|
||||
@@ -119,13 +123,20 @@ def download_callback(total_packets, success_count, error_count):
|
||||
|
||||
# 打印串口收到的字符
|
||||
def print_device_str(data:bytearray):
|
||||
data:list[bytearray]=data.split(b"\r\n")
|
||||
for item in data:
|
||||
try:
|
||||
d=item.decode('utf-8')
|
||||
myprint("DEVICE:",d.strip())
|
||||
except Exception as e:
|
||||
myprint("DEVICE:",item)
|
||||
data=data.replace(b"\r\n",b"\n")
|
||||
index=0
|
||||
while index<len(data):
|
||||
if(bytes([data[index]]).isascii()):
|
||||
index+=1
|
||||
else:
|
||||
break
|
||||
try:
|
||||
d=data[:index].decode('utf-8')
|
||||
mywrite(d)
|
||||
if(index<len(data)):
|
||||
mywrite(f"{data[index:]}")
|
||||
except Exception as e:
|
||||
mywrite(f"{data}\n")
|
||||
|
||||
|
||||
|
||||
@@ -244,6 +255,16 @@ def calc_flash_info_name():
|
||||
|
||||
|
||||
|
||||
# 计算bootram密码
|
||||
def calc_bootram_pssword(info_file:str):
|
||||
with open(info_file,mode='r',encoding='utf-8') as f:
|
||||
lines=f.readlines()
|
||||
for line in lines:
|
||||
if(line.startswith('Chip Id')):
|
||||
chip_id=line.split(':')[-1].strip()
|
||||
password=bootram_pssword(chip_id)
|
||||
return f"{password:08x}"
|
||||
|
||||
|
||||
# 上传固件
|
||||
def upload_fun():
|
||||
@@ -254,6 +275,12 @@ def upload_fun():
|
||||
print_device_str(ser_read_data)
|
||||
with open(calc_flash_info_name(),mode='w+',encoding='utf-8') as f:
|
||||
f.writelines(ser_read_data.decode('utf-8').split('\r\n'))
|
||||
# 输入密码
|
||||
password=calc_bootram_pssword(calc_flash_info_name())
|
||||
ser.write(f"PSS {password}\n".encode("utf-8"))
|
||||
time.sleep(0.5)
|
||||
ser_read_data=ser.read(4096)
|
||||
print_device_str(ser_read_data)
|
||||
# 显示image信息
|
||||
ser.write(b"f s\n")
|
||||
time.sleep(1)
|
||||
@@ -273,9 +300,30 @@ def upload_fun():
|
||||
myprint("Transform to hex end.")
|
||||
|
||||
|
||||
|
||||
# 发送配置信息
|
||||
def send_cfg_fun():
|
||||
global nb_rate
|
||||
rate_table={
|
||||
115200:0,
|
||||
460800:1,
|
||||
1500000:2
|
||||
}
|
||||
baud_cfg=f"u_baud={rate_table.get(nb_rate,0)}"
|
||||
cfg_str=base64.b64encode(baud_cfg.encode(encoding='utf-8')).decode(encoding='utf-8')
|
||||
text=f"ram_config:{cfg_str}:gifnoc_mar"
|
||||
crc=CRC16(text.encode('utf-8'))
|
||||
cfg_text=f"{text}#crc={crc}"
|
||||
# print(cfg_text)
|
||||
ser.write(f"{cfg_text}\n".encode("utf-8"))
|
||||
|
||||
|
||||
|
||||
# 烧录固件
|
||||
def burn_fun():
|
||||
time.sleep(3)
|
||||
# time.sleep(1)
|
||||
send_cfg_fun()
|
||||
# time.sleep(0.02)
|
||||
ser_read_data=ser.read(4096)
|
||||
print_device_str(ser_read_data)
|
||||
ser.baudrate=nb_rate
|
||||
@@ -349,6 +397,7 @@ def global_def():
|
||||
global layout_index
|
||||
global log_file
|
||||
global skip_ram
|
||||
global extract_log
|
||||
args = parser.parse_args()
|
||||
|
||||
init_str="WQKL"
|
||||
@@ -359,23 +408,28 @@ def global_def():
|
||||
log_timeout=args.timeout
|
||||
layout_index=args.layout_index
|
||||
skip_ram=args.skip_ram
|
||||
extract_log=args.extract_log
|
||||
|
||||
|
||||
# 上传或者下载flash镜像
|
||||
if(args.flash_file is not None):
|
||||
iot_flash_file=args.flash_file
|
||||
log_file=iot_flash_file
|
||||
if(args.ram_file is not None):
|
||||
ram_file=ram_file_redirect(args.ram_file)
|
||||
if(os.path.exists(iot_flash_file)):
|
||||
function_type='download'
|
||||
iot_flash_file=bin_file_decrypt(iot_flash_file)
|
||||
if args.kunlun_version is None:
|
||||
args.kunlun_version=check_bin_type(iot_flash_file)
|
||||
ram_file=f'kl{args.kunlun_version}_ram_build.bin'
|
||||
ram_file=os.path.join(bin_path(),ram_file)
|
||||
if ram_file is None:
|
||||
ram_file=f'kl{args.kunlun_version}_ram_build.bin'
|
||||
ram_file=ram_file_redirect(ram_file)
|
||||
else:
|
||||
function_type='upload'
|
||||
ram_file=f'bootram_kl{args.kunlun_version}.bin'
|
||||
ram_file=os.path.join(bin_path(),ram_file)
|
||||
if ram_file is None:
|
||||
ram_file=f'bootram_kl{args.kunlun_version}.bin'
|
||||
ram_file=ram_file_redirect(ram_file)
|
||||
if(args.kunlun_version is None):
|
||||
print("请指定参数 -k")
|
||||
sys.exit(-1)
|
||||
@@ -389,6 +443,11 @@ def global_def():
|
||||
function_type='ram'
|
||||
ram_file=ram_file_redirect(args.ram_file)
|
||||
log_file=args.ram_file
|
||||
if(args.kunlun_version is None):
|
||||
print("请指定参数 -k")
|
||||
sys.exit(-1)
|
||||
elif(args.kunlun_version == "4"):
|
||||
init_str="HZPG"
|
||||
elif(args.bin_convert is not None):
|
||||
function_type='convert'
|
||||
iot_flash_file=args.bin_convert
|
||||
@@ -421,10 +480,11 @@ def parser_init():
|
||||
parser.add_argument('-t','--timeout',action='store',type=float,default=5,help='启用log时接收log的时间')
|
||||
parser.add_argument('-i','--layout_index',action='store',type=int,help='解析接收到的flash文件或转换bin文件时使用的layout,不指定则不解析')
|
||||
parser.add_argument('--b_rate',action='store',type=int,default=115200,help='下载ram程序 上传flash数据 控制台 接收log等 使用的串口波特率')
|
||||
parser.add_argument('--nb_rate',action='store',type=int,default=1500000,help='下载flash程序使用的串口波特率')
|
||||
parser.add_argument('--nb_rate',action='store',type=int,default=1500000,help='下载flash程序使用的串口波特率,支持115200,460800,1500000')
|
||||
parser.add_argument('--ftm',action='store_true',default=False,help='进入工厂模式')
|
||||
parser.add_argument('--list',action='store_true',default=False,help='列出所有.bin文件')
|
||||
parser.add_argument('--skip_ram',action='store_true',default=False,help='下载flash文件时是否跳过下载ram.bin的步骤,默认否')
|
||||
parser.add_argument('--extract_log',action='store_true',default=False,help='是否提取bin中的log信息,默认否')
|
||||
|
||||
|
||||
|
||||
@@ -438,15 +498,11 @@ def print_help():
|
||||
'''
|
||||
print(help)
|
||||
|
||||
# 如果不指定上传还是下载 脚本会根据输入文件是否存在来决定上传还是下载
|
||||
# kunlun.py [com] [kl1/kl3] [upload.bin/download.bin] <key>
|
||||
# kunlun.py [com] [ram.bin]
|
||||
# kunlun.py [file.bin] <enc>
|
||||
if __name__ == '__main__':
|
||||
function_type=None # 功能类型 "download" 下载,"upload" 上传,"ram" 下载ram,"convert"" 转换bin
|
||||
time_stamp_start, time_stamp_end = 0, 0
|
||||
init_str, serial_com, b_rate, nb_rate, ram_file, iot_flash_file, ser = None, None, None, None, None, None, None
|
||||
upload_key, parser, layout_index, log_file=None, None, None, None
|
||||
upload_key, parser, layout_index, log_file, extract_log=None, None, None, None, False
|
||||
user_log=False
|
||||
log_timeout=0
|
||||
skip_ram=False
|
||||
@@ -459,6 +515,8 @@ if __name__ == '__main__':
|
||||
log_init(calc_log_file_name())
|
||||
if(function_type=='convert'):
|
||||
bin_to_hex_file(iot_flash_file,calc_hex_name(),layout_index)
|
||||
if(extract_log):
|
||||
print_log(iot_flash_file)
|
||||
sys.exit(0)
|
||||
if(function_type=="list"):
|
||||
l=list_bin_file()
|
||||
@@ -491,6 +549,8 @@ if __name__ == '__main__':
|
||||
|
||||
if(function_type=='upload'):
|
||||
upload_fun()
|
||||
if(extract_log):
|
||||
print_log(calc_upload_name())
|
||||
elif(function_type=='download'):
|
||||
burn_fun()
|
||||
clear_tmp()
|
||||
@@ -511,4 +571,5 @@ if __name__ == '__main__':
|
||||
read_input(ser)
|
||||
|
||||
# if __name__ == "__main__":
|
||||
# read_input(None)
|
||||
# nb_rate=115200
|
||||
# send_cfg_fun()
|
||||
|
25
password.py
Normal file
25
password.py
Normal file
@@ -0,0 +1,25 @@
|
||||
|
||||
import sys
|
||||
from bin.crc import CRC32
|
||||
|
||||
|
||||
|
||||
|
||||
def bootram_pssword(chip_id:str):
|
||||
data=bytearray(b'Aerospace C.Power')
|
||||
data+=bytearray(chip_id.encode('utf-8'))
|
||||
off=64-len(data)
|
||||
if(off>0):
|
||||
data+=bytearray(b'\x5A'*off)
|
||||
pss=CRC32(data)
|
||||
# print(f"data={data} len={len(data)}")
|
||||
print(f"bootram_pssword:{pss:08x}")
|
||||
return pss
|
||||
print(f"chip_id err.")
|
||||
return 0
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
bootram_pssword(sys.argv[1])
|
||||
|
Reference in New Issue
Block a user