1#!/usr/bin/env python 2 3# Copyright (C) 2018-2022 Intel Corporation. 4# SPDX-License-Identifier: BSD-3-Clause 5 6import ConfigParser 7import uuid 8import struct 9import sys 10 11type_2_guid = { 12# official guid for gpt partition type 13 'fat' : 'ebd0a0a2-b9e5-4433-87c0-68b6b72699c7', 14 'esp' : 'c12a7328-f81f-11d2-ba4b-00a0c93ec93b', 15 'linux' : '0fc63daf-8483-4772-8e79-3d69d8477de4', 16 'linux-swap' : '0657fd6d-a4ab-43c4-84e5-0933c84b4f4f', 17# generated guid for android 18 'boot' : '49a4d17f-93a3-45c1-a0de-f50b2ebe2599', 19 'recovery' : '4177c722-9e92-4aab-8644-43502bfd5506', 20 'misc' : 'ef32a33b-a409-486c-9141-9ffb711f6266', 21 'metadata' : '20ac26be-20b7-11e3-84c5-6cfdb94711e9', 22 'tertiary' : '767941d0-2085-11e3-ad3b-6cfdb94711e9', 23 'factory' : '9fdaa6ef-4b3f-40d2-ba8d-bff16bfb887b' } 24 25def zero_pad(s, size): 26 if (len(s) > size): 27 print 'error', len(s) 28 s += '\0' * (size - len(s)) 29 return s 30 31def copy_section(cfg, a, b): 32 cfg.add_section(b) 33 for option in cfg.options(a): 34 cfg.set(b, option, cfg.get(a, option)) 35 36def preparse_slots(cfg, partitions): 37 if not cfg.has_option('base', 'nb_slot'): 38 return partitions 39 40 nb_slot = cfg.getint('base', 'nb_slot') 41 42 parts_with_slot = [] 43 for p in partitions: 44 section = "partition." + p 45 if cfg.has_option(section, 'has_slot'): 46 for i in range(ord('a'), ord('a') + nb_slot): 47 suffix = "_%c" % i 48 new_part = p + suffix 49 new_section = "partition." + new_part 50 51 copy_section(cfg, section, new_section) 52 cfg.set(new_section, 'label', cfg.get(section, 'label') + suffix) 53 parts_with_slot.append(new_part); 54 else: 55 parts_with_slot.append(p); 56 57 return parts_with_slot 58 59def preparse_partitions(gpt_in, cfg): 60 with open(gpt_in, 'r') as f: 61 data = f.read() 62 63 partitions = cfg.get('base', 'partitions').split() 64 65 for l in data.split('\n'): 66 words = l.split() 67 if len(words) > 2: 68 if words[0] == 'partitions' and words[1] == '+=': 69 partitions += words[2:] 70 71 return partitions 72 73def main(): 74 if len(sys.argv) != 2: 75 print 'Usage : ', sys.argv[0], 'gpt_in1.ini' 76 print ' write binary to stdout' 77 sys.exit(1) 78 79 gpt_in = sys.argv[1] 80 81 cfg = ConfigParser.SafeConfigParser() 82 83 cfg.read(gpt_in) 84 85 part = preparse_partitions(gpt_in, cfg) 86 part = preparse_slots(cfg, part) 87 88 magic = 0x6a8b0da1 89 start_lba = 0 90 if cfg.has_option('base', 'start_lba'): 91 start_lba = cfg.getint('base', 'start_lba') 92 npart = len(part) 93 94 out = sys.stdout 95 out.write(struct.pack('<I', magic)) 96 out.write(struct.pack('<I', start_lba)) 97 out.write(struct.pack('<I', npart)) 98 for p in part: 99 length = cfg.get('partition.' + p, 'len') 100 out.write(struct.pack('<i', int(length))) 101 102 label = cfg.get('partition.' + p, 'label').encode('utf-16le') 103 out.write(zero_pad(label, 36 * 2)) 104 105 guid_type = cfg.get('partition.' + p, 'type') 106 guid_type = uuid.UUID(type_2_guid[guid_type]) 107 out.write(guid_type.bytes_le) 108 109 guid = uuid.uuid4() 110 out.write(guid.bytes_le) 111 112if __name__ == "__main__": 113 main() 114