Files
zTC1/mico-os/makefiles/scripts/flash_pack.py
2025-03-11 15:54:45 +08:00

192 lines
4.5 KiB
Python

#!/usr/bin/env python
# The FTFS image will be created in the same folder from which this script
# is run.
import sys
import os
import struct
import crc32
import gzip
import tempfile
import shutil
import glob
if len(sys.argv) < 4:
print("usage: %s <backend_api_version> <image> <sourcedir> <recipe_file> <web_repo>" % sys.argv[0])
sys.exit(0)
MAGIC = "\x88\x88\x88\x88\x63\x6F\x7A\x79"
MAX_NAME_LEN = 23
VERSION = "0100"
VERBOSE=0
TMPDIR=tempfile.mkdtemp()
FTFS_IMG=os.path.abspath(sys.argv[2])
CURDIR=os.getcwd()
# List of file extensions to be compressed.
TO_GZIP_FILES= [""]
def pack_files(table):
summary = ""
buffer = ""
offset = (len(table)+1)*32 # each table entry is 32 bytes long
for i in range(0, len(table)):
h = open(table[i][0], "rb")
data = h.read()
h.close()
if i > 0:
table[i][2] += table[i-1][2]+table[i-1][3]
else:
table[i][2] = offset
table[i][3] = len(data)
buffer += data
summary += table[i][1] + \
'\0'*(MAX_NAME_LEN+1-len(table[i][1])) + \
struct.pack('ii', table[i][2], table[i][3])
summary += '\0'*32 # add terminating entry
pad = len(summary+buffer)%4
if pad > 0:
buffer += chr(0xFF)*(4-pad)
return summary+buffer
def compress_given_files(dir):
try:
path_list = os.listdir(dir)
except OSError:
print("error: cannot open source path \"%s\"" % dir)
sys.exit(1)
for path in path_list:
if os.path.isdir(path):
continue
if len(path) >= MAX_NAME_LEN:
print("error: file name \"%s\" is too long" % path)
return None
fileWOext, fileExtension = os.path.splitext(path)
for givenExt in TO_GZIP_FILES:
if fileExtension == givenExt and fileExtension != "":
gzPath = path + ".gz"
f_in = open(path, 'rb')
f_out = gzip.open(gzPath, 'wb')
f_out.writelines(f_in)
f_out.close()
f_in.close()
if VERBOSE == 1:
normal_size = size = os.path.getsize(path)
compressed_size = size = os.path.getsize(gzPath)
print("Compressed \"%s\" Size reduction %d%%" \
% (path, \
((normal_size - compressed_size) * 100)/normal_size))
os.remove(path);
def init_file_table(dir, paths):
file_table = []
for path in paths:
if os.path.isdir(path):
continue
if len(path) >= MAX_NAME_LEN:
print("error: file name \"%s\" is too long" % path)
return None
file_table.append([dir+path,path,0,0])
return file_table
def copy_files_from_dir(dest_dir, src_path):
for fname in glob.iglob(src_path):
if os.path.isfile(fname):
shutil.copy(fname,dest_dir)
else:
copy_files_from_dir(dest_dir, fname + "/*")
def copy_files_from_recipe(dest_dir, commondir_path , recipe_file):
fd = open(recipe_file)
for line in fd:
copy_files_from_dir(dest_dir, commondir_path+line.strip())
return None
if __name__ == '__main__':
# Copy the source tree
WORK_DIR=TMPDIR + "/ftfs-img/"
if VERBOSE == 1:
print("Temp. dir %s" % TMPDIR)
if not os.path.exists(TMPDIR):
print("error: cannot open source path \"%s\"" % TMPDIR)
sys.exit(1)
shutil.copytree(sys.argv[3], WORK_DIR)
recipe_file = None
# Check if user want to copy files from recipe
if len (sys.argv) > 4:
recipe_file = sys.argv[4]
if not os.path.exists(recipe_file):
print("error: cannot open recipe path \"%s\"" % recipe_file)
sys.exit(1)
if recipe_file != None :
if len (sys.argv) < 6:
print("error: missing common directory path")
sys.exit(1);
if not os.path.exists(sys.argv[5]):
print("error: cannot open source path \"%s\"" %sys.argv[5])
sys.exit(1)
commondir_path = os.path.abspath(sys.argv[5]) + "/"
copy_files_from_recipe(WORK_DIR,commondir_path,recipe_file)
#Remove recipe files
for rfile in glob.glob(WORK_DIR+"*.recipe"):
os.remove(rfile)
os.chdir(WORK_DIR)
compress_given_files(WORK_DIR)
try:
d = os.listdir(WORK_DIR)
except OSError:
print("error: cannot open path \"%s\"" % WORK_DIR)
sys.exit(1)
table = init_file_table(WORK_DIR, d)
if table == None:
sys.exit(2)
buffer = pack_files(table)
crc = crc32.crc32(buffer)
backend_version = sys.argv[1]
h = open(FTFS_IMG, "wb")
h.write(MAGIC)
h.write(struct.pack("I", crc & 0xffffffffL))
h.write(struct.pack("I", 0 & 0xffffffffL))
h.write(struct.pack("I", int(backend_version, 0) & 0xffffffffL))
h.write(VERSION)
h.write(buffer)
h.close()
st = os.stat(FTFS_IMG)
if VERBOSE == 1:
print("FTFS image created \"%s\"" % FTFS_IMG)
print("Removing temp dir %s" % TMPDIR)
# Navigate back to original directory so that the temporary
# directory can be removed.
os.chdir(CURDIR);
shutil.rmtree(TMPDIR);
sys.exit(0)