| #!/usr/bin/env python |
| # Copyright (C) 2019 Fabien Parent <fparent@baylibre.com> |
| |
| import random |
| import zlib |
| import struct |
| import argparse |
| import sys |
| |
| class UBootEnv: |
| def __init__(self, env_size): |
| self.env = []; |
| self.env_size = env_size |
| |
| def __init__(self, env_size, env_file): |
| self.env = []; |
| self.env_size = env_size |
| with open(env_file, "r") as env: |
| self.env = env.readlines() |
| |
| def add(self, name, value): |
| self.env.append("{}={}".format(name, value)) |
| |
| def update(self, name, value): |
| new_env = [] |
| for line in self.env: |
| if line.startswith(name + '='): |
| new_env.append("{}={}".format(name, value)) |
| else: |
| new_env.append(line) |
| self.env = new_env |
| |
| def write_binary(self, filename = "u-boot-env.bin"): |
| with open(filename, "w+b") as out: |
| out.seek(4) |
| |
| # Write environment |
| for line in self.env: |
| if line == '\n': |
| continue |
| data = line.rstrip("\n").encode() + b'\0' |
| out.write(data) |
| |
| while out.tell() < self.env_size: |
| out.write(chr(0x00)) |
| |
| # Compute CRC |
| out.seek(4) |
| crc = zlib.crc32(out.read(self.env_size - 4)) & 0xffffffff |
| |
| # Write CRC |
| out.seek(0) |
| out.write(struct.pack("I", crc)) |
| |
| def gen_mac_addr(self, oui, num_iface): |
| for i in range(num_iface): |
| macaddr = "{}:{:02X}:{:02X}:{:02X}".format( |
| oui, |
| random.randint(0, 255), |
| random.randint(0, 255), |
| random.randint(0, 255)) |
| varname = "eth{}addr".format(i) |
| if i == 0: |
| varname = "ethaddr" |
| self.add(varname, macaddr) |
| |
| if __name__ == "__main__": |
| parser = argparse.ArgumentParser() |
| parser.add_argument('-i', '--input', default = "u-boot-initial-env", |
| help = 'Path to U-boot environment file') |
| parser.add_argument('-s', '--size', default = 4096, type = int, |
| help = 'Size of the U-boot environment file') |
| parser.add_argument('-o', '--output', default = "u-boot-env.bin", |
| help = 'Path to U-boot binary environment') |
| parser.add_argument('--oui', |
| help = 'OUI to use when generating MAC addresses') |
| parser.add_argument('--num-ethaddr', default = 0, type = int, |
| help = "Number of ethaddr to add to the environment") |
| args = parser.parse_args() |
| |
| print("Initial environment: {}".format(args.input)) |
| print("Binary output environment: {}".format(args.output)) |
| print("OUI: {}".format(args.oui)) |
| print("Size: {}".format(args.size)) |
| |
| if args.num_ethaddr > 0 and args.oui == None: |
| sys.stderr.write("\nerror: --oui must be specified when --num-ethaddr is set\n") |
| parser.print_help(sys.stderr) |
| sys.exit(1) |
| |
| env = UBootEnv(args.size, args.input) |
| if args.num_ethaddr > 0: |
| env.gen_mac_addr(args.oui, args.num_ethaddr) |
| env.write_binary(args.output) |