diff --git a/tasmota/berry/modules/partition.be b/tasmota/berry/modules/partition.be new file mode 100644 index 000000000..f5df5e549 --- /dev/null +++ b/tasmota/berry/modules/partition.be @@ -0,0 +1,175 @@ +#------------------------------------------------------------- + - Parser for ESP32 partition + - + -------------------------------------------------------------# +partition = module('partition') + +import flash +import string + +def remove_trailing_zeroes(b) + while size(b) > 0 + if b.get(size(b)-1,1) == 0 + b.resize(size(b)-1) + else + break + end + end + return b +end + +#------------------------------------------------------------- + - Class for a partition table entry + -------------------------------------------------------------# +class Partition_info + var type + var subtype + var start + var size + var label + var flags + + def init(raw) + import string + + if raw == nil || !issubclass(bytes, raw) + self.type = 0 + self.subtype = 0 + self.start = 0 + self.size = 0 + self.label = '' + self.flags = 0 + return + end + + #- parse -# + var magic = raw.get(0,2) + if magic == 0x50AA #- partition entry -# + + self.type = raw.get(2,1) + self.subtype = raw.get(3,1) + self.start = raw.get(4,4) + self.size = raw.get(8,4) + self.label = remove_trailing_zeroes(raw[12..27]).asstring() + self.flags = raw.get(28,4) + + elif magic == 0xEBEB #- MD5 -# + else + raise "internal_error", string.format("invalid magic number %02X", magic) + end + + end + + def tostring() + import string + return string.format("", + self.type, self.subtype, self.start, self.size, + self.label, self.flags) + end + + def tobytes() + #- convert to raw bytes -# + var b = bytes('AA50') #- set magic number -# + b.resize(32).resize(2) #- pre-reserve 32 bytes -# + b.add(self.type, 1) + b.add(self.subtype, 1) + b.add(self.start, 4) + b.add(self.size, 4) + var label = bytes().fromstring(self.label) + label.resize(16) + b = b + label + b.add(self.flags, 4) + return b + end + +end + +#------------------------------------------------------------- + - Class for a partition table entry + -------------------------------------------------------------# +class Partition + var raw #- raw bytes of the partition table in flash -# + var md5 #- md5 hash of partition list -# + var slots + + def init() + self.slots = [] + self.load() + self.parse() + end + + def load() + #- load partition table from flash -# + self.raw = flash.read(0x8000,0x1000) + end + + #- parse the raw bytes to a structured list of partition items -# + def parse() + var i + for i:0..94 # there are maximum 95 slots + md5 (0xC00) + var item_raw = self.raw[i*32..(i+1)*32-1] + var magic = item_raw.get(0,2) + if magic == 0x50AA #- partition entry -# + var slot = Partition_info(item_raw) + self.slots.push(slot) + elif magic == 0xEBEB #- MD5 -# + self.md5 = self.raw[i*32+16..i*33-1] + break + else + break + end + end + end + + #- convert to human readble -# + def tostring() + var ret = " 95 raise "value_error", "Too many partiition slots" end + var b = bytes() + for slot: self.slots + b += slot.tobytes() + end + #- compute MD5 -# + var md5 = MD5() + md5.update(b) + #- add the last segment -# + b += bytes("EBEBFFFFFFFFFFFFFFFFFFFFFFFFFFFF") + b += md5.finish() + #- complete -# + return b + end + + #- write back to flash -# + def save() + var b = self.tobytes() + #- erase flash area and write -# + flash.erase(0x8000,0x1000) + flash.write(0x8000, b) + end +end + +partition.Partition = Partition + +return partition +#Example +#- + +import partition +Partition = partition.Partition + +# read +p = Partition() +print(p) + +-# \ No newline at end of file