WIP: rewrite single sd_fusing.py
[platform/kernel/u-boot.git] / scripts / tizen / sd_fusing.py
1 #!/usr/bin/env python3
2
3 import argparse
4 import atexit
5 import logging
6 import os
7 import stat
8 import subprocess
9 import sys
10
11 __version__ = "1.0.0"
12
13 Format = False
14
15 Device = ""
16 File = ""
17
18 class Rpi3:
19     long_name = "Raspberry Pi 3"
20     pass
21
22 class Rpi4:
23     long_name = "Raspberry Pi 4"
24     pass
25
26 class VF2:
27     long_name = "VisionFive2"
28     pass
29
30 class RV64:
31     long_name = "QEMU RISC-V 64-bit"
32     pass
33
34 TARGETS = {
35     'rpi3': Rpi3,
36     'rpi4': Rpi4,
37     'vf2': VF2,
38     'rv64': RV64    
39 }
40
41 def check_args(args):
42     logging.info(f"Device: {args.device}")
43
44     if args.binaries and len(args.binaries) > 0:
45         logging.info("Fusing binar{}: {}".format("y" if len(args.binaries) == 1 else "ies",
46                      ", ".join(args.binaries)))
47
48     if args.format:
49         response = input(f"{args.device} will be formatted. Is it OK? [y/N]")
50         if response.lower() in ('y', 'yes'):
51             Format = True
52
53 def check_device(args):
54     Device = args.device
55     if not os.path.exists(Device) and args.create:
56         logging.debug(f"dd if=/dev/zero of={Device} conv=sparse bs=1M count={args.size}")
57         rc = subprocess.run(["dd", "if=/dev/zero", f"of={Device}",
58                              "conv=sparse", "bs=1M", f"count={args.size}"])
59         if rc.returncode != 0:
60             logging.error("Failed to create the backing file")
61             sys.exit(1)
62         
63     if os.path.isfile(Device):
64         File = Device
65         logging.debug(f"losetup --show --partscan --find {File}")
66         rc = subprocess
67
68         proc = subprocess.Popen(["losetup", "--show", "--partscan",
69                                  "--find", f"{File}"],
70                                 stdout=subprocess.PIPE)
71         Device = proc.communicate()[0].decode('utf-8').strip()
72         logging.debug(f"Loop device found: {Device}")
73         atexit.register(lambda: subprocess.run(["losetup", "-d", Device]))
74
75     try:
76         s = os.stat(Device)
77         if not stat.S_ISBLK(s.st_mode):
78             raise TypeError
79     except FileNotFoundError:
80         logging.error(f"No such device: {Device}")
81         sys.exit(1)
82     except TypeError:
83         logging.error(f"{Device} is not a block device")
84         sys.exit(1)
85     
86 def check_partition_format():
87     pass
88
89 def check_ddversion():
90     pass
91
92 def fuse_image():
93     pass
94
95 if __name__ == '__main__':
96     parser = argparse.ArgumentParser(description="For {}, version {}".format(
97         ", ".join([v.long_name for k,v in TARGETS.items()]),
98         __version__
99     ))
100     parser.add_argument("-b", "--binary", action="append", dest="binaries",
101                         help="binary to flash")
102     parser.add_argument("--create", action="store_true",
103                         help="create the backing file and format the loopback device")
104     parser.add_argument("-d", "--device", required=True,
105                         help="device node or loopback backing file")
106     parser.add_argument("--format", action="store_true",
107                         help="create new partition table on the target device")
108     parser.add_argument("--log-level", dest="log_level", default="warning",
109                         help="Verbosity, possible values: debug, info, warning, "
110                         "error, critical (default: warning)")
111     parser.add_argument("-s", "--size", type=int, default=8192,
112                         help="size of the backing file to create")
113     parser.add_argument("-t", "--target",
114                         help="target device model")
115     parser.add_argument("--version", action="version",
116                         version=f"%(prog)s {__version__}")
117     args = parser.parse_args()
118
119     print(repr(args))
120
121     logging.basicConfig(format='%(asctime)s.%(msecs)03d %(levelname)s:%(message)s',
122                         level=args.log_level.upper())
123
124     check_args(args)
125     check_device(args)
126     check_partition_format()
127     check_ddversion()
128     fuse_image()