Files
SDK_SG200x_V2/build/tools/common/image_tool/XmlParser.py
forum_service 0ca73f9917 build: weekly-rls-2024-01-05
Change-Id: Idaacdb06e9b7bd435f1928d62d8b1204747380b6
2024-05-31 14:35:32 +08:00

128 lines
3.9 KiB
Python

#!/usr/bin/python3
# -*- coding: utf-8 -*-
import logging
import os
import re
import sys
import xml.etree.ElementTree as ET
FORMAT = "%(levelname)s: %(message)s"
logging.basicConfig(level=logging.INFO, format=FORMAT)
Storage_EMMC = 0
Storage_SPINAND = 1
Storage_SPINOR = 2
LBA_SIZE = 512
class XmlParser:
@staticmethod
def parse_size(size):
units = {"B": 1, "K": 2 ** 10, "M": 2 ** 20, "G": 2 ** 30, "T": 2 ** 40}
size = size.upper()
logging.debug("parsing size %s" % size)
if not re.match(r" ", size):
size = re.sub(r"([BKMGT])", r" \1", size)
try:
number, unit = [string.strip() for string in size.split()]
except ValueError:
number = size
unit = "B"
ret = int(float(number) * units[unit])
return ret
def parse(self, install=None):
try:
tree = ET.parse(self.xml)
except Exception:
logging.error(self.xml + " is not a vaild xml file")
raise
root = tree.getroot()
self.storage = root.attrib["type"]
install_dir = install
parts = []
for part in root:
p = dict()
if "size_in_kb" in part.attrib:
p["part_size"] = int(part.attrib["size_in_kb"]) * 1024
elif "size_in_b" in part.attrib:
p["part_size"] = int(part.attrib["size_in_b"])
else:
p["part_size"] = sys.maxsize
# Assign 0 means biggest number
if part.attrib["file"] and install_dir is not None:
path = os.path.join(install_dir, part.attrib["file"])
try:
file_size = os.stat(path).st_size
except Exception:
file_size = 0
if file_size > p["part_size"]:
logging.error(
"Image: %s(%d) is larger than partition size(%d)"
% (part.attrib["file"], file_size, p["part_size"])
)
raise OverflowError
p["file_path"] = path
logging.debug("size of " + path + " : " + str(file_size))
else:
file_size = 0
p["file_size"] = int(file_size)
p["file_name"] = part.attrib["file"]
p["label"] = part.attrib["label"]
p["mountpoint"] = (
part.attrib["mountpoint"] if "mountpoint" in part.attrib else None
)
p["type"] = part.attrib["type"] if "type" in part.attrib else ""
p["options"] = part.attrib["options"] if "options" in part.attrib else None
parts.append(p)
if self.storage == "emmc":
self.__calEmmcOffset(parts)
elif self.storage == "spinor":
self.__calNorOffset(parts)
elif self.storage == "spinand":
self.__calNandOffset(parts)
elif self.storage == "sd":
self.__calNandOffset(parts)
elif self.storage == "none":
self.__calNandOffset(parts)
else:
logging.error("Unknown storage type")
raise ValueError(self.storage)
for p in parts:
self.parts[p["label"]] = p
return parts
def __calEmmcOffset(self, parts):
# EMMC will program gpt in the beggining of the emmc, start from 8192
start = 0
for p in parts:
p["offset"] = start
start += p["part_size"]
def __calNandOffset(self, parts):
start = 0
for p in parts:
p["offset"] = start
start += p["part_size"]
def __calNorOffset(self, parts):
start = 0
for p in parts:
p["offset"] = start
start += p["part_size"]
def getStorage(self):
return self.storage
def __init__(self, xml):
self.xml = xml
self.storage = "emmc"
self.parts = dict()