~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/make_fit.py

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/make_fit.py (Architecture i386) and /scripts/make_fit.py (Architecture alpha)


  1 #!/usr/bin/env python3                              1 #!/usr/bin/env python3
  2 # SPDX-License-Identifier: GPL-2.0+                 2 # SPDX-License-Identifier: GPL-2.0+
  3 #                                                   3 #
  4 # Copyright 2024 Google LLC                         4 # Copyright 2024 Google LLC
  5 # Written by Simon Glass <sjg@chromium.org>          5 # Written by Simon Glass <sjg@chromium.org>
  6 #                                                   6 #
  7                                                     7 
  8 """Build a FIT containing a lot of devicetree       8 """Build a FIT containing a lot of devicetree files
  9                                                     9 
 10 Usage:                                             10 Usage:
 11     make_fit.py -A arm64 -n 'Linux-6.6' -O lin     11     make_fit.py -A arm64 -n 'Linux-6.6' -O linux
 12         -o arch/arm64/boot/image.fit -k /tmp/k     12         -o arch/arm64/boot/image.fit -k /tmp/kern/arch/arm64/boot/image.itk
 13         @arch/arm64/boot/dts/dtbs-list -E -c g     13         @arch/arm64/boot/dts/dtbs-list -E -c gzip
 14                                                    14 
 15 Creates a FIT containing the supplied kernel a     15 Creates a FIT containing the supplied kernel and a set of devicetree files,
 16 either specified individually or listed in a f     16 either specified individually or listed in a file (with an '@' prefix).
 17                                                    17 
 18 Use -E to generate an external FIT (where the      18 Use -E to generate an external FIT (where the data is placed after the
 19 FIT data structure). This allows parsing of th     19 FIT data structure). This allows parsing of the data without loading
 20 the entire FIT.                                    20 the entire FIT.
 21                                                    21 
 22 Use -c to compress the data, using bzip2, gzip     22 Use -c to compress the data, using bzip2, gzip, lz4, lzma, lzo and
 23 zstd algorithms.                                   23 zstd algorithms.
 24                                                    24 
 25 Use -D to decompose "composite" DTBs into thei     25 Use -D to decompose "composite" DTBs into their base components and
 26 deduplicate the resulting base DTBs and DTB ov     26 deduplicate the resulting base DTBs and DTB overlays. This requires the
 27 DTBs to be sourced from the kernel build direc     27 DTBs to be sourced from the kernel build directory, as the implementation
 28 looks at the .cmd files produced by the kernel     28 looks at the .cmd files produced by the kernel build.
 29                                                    29 
 30 The resulting FIT can be booted by bootloaders     30 The resulting FIT can be booted by bootloaders which support FIT, such
 31 as U-Boot, Linuxboot, Tianocore, etc.              31 as U-Boot, Linuxboot, Tianocore, etc.
 32                                                    32 
 33 Note that this tool does not yet support addin     33 Note that this tool does not yet support adding a ramdisk / initrd.
 34 """                                                34 """
 35                                                    35 
 36 import argparse                                    36 import argparse
 37 import collections                                 37 import collections
 38 import os                                          38 import os
 39 import subprocess                                  39 import subprocess
 40 import sys                                         40 import sys
 41 import tempfile                                    41 import tempfile
 42 import time                                        42 import time
 43                                                    43 
 44 import libfdt                                      44 import libfdt
 45                                                    45 
 46                                                    46 
 47 # Tool extension and the name of the command-l     47 # Tool extension and the name of the command-line tools
 48 CompTool = collections.namedtuple('CompTool',      48 CompTool = collections.namedtuple('CompTool', 'ext,tools')
 49                                                    49 
 50 COMP_TOOLS = {                                     50 COMP_TOOLS = {
 51     'bzip2': CompTool('.bz2', 'bzip2'),            51     'bzip2': CompTool('.bz2', 'bzip2'),
 52     'gzip': CompTool('.gz', 'pigz,gzip'),          52     'gzip': CompTool('.gz', 'pigz,gzip'),
 53     'lz4': CompTool('.lz4', 'lz4'),                53     'lz4': CompTool('.lz4', 'lz4'),
 54     'lzma': CompTool('.lzma', 'lzma'),             54     'lzma': CompTool('.lzma', 'lzma'),
 55     'lzo': CompTool('.lzo', 'lzop'),               55     'lzo': CompTool('.lzo', 'lzop'),
 56     'zstd': CompTool('.zstd', 'zstd'),             56     'zstd': CompTool('.zstd', 'zstd'),
 57 }                                                  57 }
 58                                                    58 
 59                                                    59 
 60 def parse_args():                                  60 def parse_args():
 61     """Parse the program ArgumentParser            61     """Parse the program ArgumentParser
 62                                                    62 
 63     Returns:                                       63     Returns:
 64         Namespace object containing the argume     64         Namespace object containing the arguments
 65     """                                            65     """
 66     epilog = 'Build a FIT from a directory tre     66     epilog = 'Build a FIT from a directory tree containing .dtb files'
 67     parser = argparse.ArgumentParser(epilog=ep     67     parser = argparse.ArgumentParser(epilog=epilog, fromfile_prefix_chars='@')
 68     parser.add_argument('-A', '--arch', type=s     68     parser.add_argument('-A', '--arch', type=str, required=True,
 69           help='Specifies the architecture')       69           help='Specifies the architecture')
 70     parser.add_argument('-c', '--compress', ty     70     parser.add_argument('-c', '--compress', type=str, default='none',
 71           help='Specifies the compression')        71           help='Specifies the compression')
 72     parser.add_argument('-D', '--decompose-dtb     72     parser.add_argument('-D', '--decompose-dtbs', action='store_true',
 73           help='Decompose composite DTBs into      73           help='Decompose composite DTBs into base DTB and overlays')
 74     parser.add_argument('-E', '--external', ac     74     parser.add_argument('-E', '--external', action='store_true',
 75           help='Convert the FIT to use externa     75           help='Convert the FIT to use external data')
 76     parser.add_argument('-n', '--name', type=s     76     parser.add_argument('-n', '--name', type=str, required=True,
 77           help='Specifies the name')               77           help='Specifies the name')
 78     parser.add_argument('-o', '--output', type     78     parser.add_argument('-o', '--output', type=str, required=True,
 79           help='Specifies the output file (.fi     79           help='Specifies the output file (.fit)')
 80     parser.add_argument('-O', '--os', type=str     80     parser.add_argument('-O', '--os', type=str, required=True,
 81           help='Specifies the operating system     81           help='Specifies the operating system')
 82     parser.add_argument('-k', '--kernel', type     82     parser.add_argument('-k', '--kernel', type=str, required=True,
 83           help='Specifies the (uncompressed) k     83           help='Specifies the (uncompressed) kernel input file (.itk)')
 84     parser.add_argument('-v', '--verbose', act     84     parser.add_argument('-v', '--verbose', action='store_true',
 85                         help='Enable verbose o     85                         help='Enable verbose output')
 86     parser.add_argument('dtbs', type=str, narg     86     parser.add_argument('dtbs', type=str, nargs='*',
 87           help='Specifies the devicetree files     87           help='Specifies the devicetree files to process')
 88                                                    88 
 89     return parser.parse_args()                     89     return parser.parse_args()
 90                                                    90 
 91                                                    91 
 92 def setup_fit(fsw, name):                          92 def setup_fit(fsw, name):
 93     """Make a start on writing the FIT             93     """Make a start on writing the FIT
 94                                                    94 
 95     Outputs the root properties and the 'image     95     Outputs the root properties and the 'images' node
 96                                                    96 
 97     Args:                                          97     Args:
 98         fsw (libfdt.FdtSw): Object to use for      98         fsw (libfdt.FdtSw): Object to use for writing
 99         name (str): Name of kernel image           99         name (str): Name of kernel image
100     """                                           100     """
101     fsw.INC_SIZE = 65536                          101     fsw.INC_SIZE = 65536
102     fsw.finish_reservemap()                       102     fsw.finish_reservemap()
103     fsw.begin_node('')                            103     fsw.begin_node('')
104     fsw.property_string('description', f'{name    104     fsw.property_string('description', f'{name} with devicetree set')
105     fsw.property_u32('#address-cells', 1)         105     fsw.property_u32('#address-cells', 1)
106                                                   106 
107     fsw.property_u32('timestamp', int(time.tim    107     fsw.property_u32('timestamp', int(time.time()))
108     fsw.begin_node('images')                      108     fsw.begin_node('images')
109                                                   109 
110                                                   110 
111 def write_kernel(fsw, data, args):                111 def write_kernel(fsw, data, args):
112     """Write out the kernel image                 112     """Write out the kernel image
113                                                   113 
114     Writes a kernel node along with the requir    114     Writes a kernel node along with the required properties
115                                                   115 
116     Args:                                         116     Args:
117         fsw (libfdt.FdtSw): Object to use for     117         fsw (libfdt.FdtSw): Object to use for writing
118         data (bytes): Data to write (possibly     118         data (bytes): Data to write (possibly compressed)
119         args (Namespace): Contains necessary s    119         args (Namespace): Contains necessary strings:
120             arch: FIT architecture, e.g. 'arm6    120             arch: FIT architecture, e.g. 'arm64'
121             fit_os: Operating Systems, e.g. 'l    121             fit_os: Operating Systems, e.g. 'linux'
122             name: Name of OS, e.g. 'Linux-6.6.    122             name: Name of OS, e.g. 'Linux-6.6.0-rc7'
123             compress: Compression algorithm to    123             compress: Compression algorithm to use, e.g. 'gzip'
124     """                                           124     """
125     with fsw.add_node('kernel'):                  125     with fsw.add_node('kernel'):
126         fsw.property_string('description', arg    126         fsw.property_string('description', args.name)
127         fsw.property_string('type', 'kernel_no    127         fsw.property_string('type', 'kernel_noload')
128         fsw.property_string('arch', args.arch)    128         fsw.property_string('arch', args.arch)
129         fsw.property_string('os', args.os)        129         fsw.property_string('os', args.os)
130         fsw.property_string('compression', arg    130         fsw.property_string('compression', args.compress)
131         fsw.property('data', data)                131         fsw.property('data', data)
132         fsw.property_u32('load', 0)               132         fsw.property_u32('load', 0)
133         fsw.property_u32('entry', 0)              133         fsw.property_u32('entry', 0)
134                                                   134 
135                                                   135 
136 def finish_fit(fsw, entries):                     136 def finish_fit(fsw, entries):
137     """Finish the FIT ready for use               137     """Finish the FIT ready for use
138                                                   138 
139     Writes the /configurations node and subnod    139     Writes the /configurations node and subnodes
140                                                   140 
141     Args:                                         141     Args:
142         fsw (libfdt.FdtSw): Object to use for     142         fsw (libfdt.FdtSw): Object to use for writing
143         entries (list of tuple): List of confi    143         entries (list of tuple): List of configurations:
144             str: Description of model             144             str: Description of model
145             str: Compatible stringlist            145             str: Compatible stringlist
146     """                                           146     """
147     fsw.end_node()                                147     fsw.end_node()
148     seq = 0                                       148     seq = 0
149     with fsw.add_node('configurations'):          149     with fsw.add_node('configurations'):
150         for model, compat, files in entries:      150         for model, compat, files in entries:
151             seq += 1                              151             seq += 1
152             with fsw.add_node(f'conf-{seq}'):     152             with fsw.add_node(f'conf-{seq}'):
153                 fsw.property('compatible', byt    153                 fsw.property('compatible', bytes(compat))
154                 fsw.property_string('descripti    154                 fsw.property_string('description', model)
155                 fsw.property('fdt', bytes(''.j    155                 fsw.property('fdt', bytes(''.join(f'fdt-{x}\x00' for x in files), "ascii"))
156                 fsw.property_string('kernel',     156                 fsw.property_string('kernel', 'kernel')
157     fsw.end_node()                                157     fsw.end_node()
158                                                   158 
159                                                   159 
160 def compress_data(inf, compress):                 160 def compress_data(inf, compress):
161     """Compress data using a selected algorith    161     """Compress data using a selected algorithm
162                                                   162 
163     Args:                                         163     Args:
164         inf (IOBase): Filename containing the     164         inf (IOBase): Filename containing the data to compress
165         compress (str): Compression algorithm,    165         compress (str): Compression algorithm, e.g. 'gzip'
166                                                   166 
167     Return:                                       167     Return:
168         bytes: Compressed data                    168         bytes: Compressed data
169     """                                           169     """
170     if compress == 'none':                        170     if compress == 'none':
171         return inf.read()                         171         return inf.read()
172                                                   172 
173     comp = COMP_TOOLS.get(compress)               173     comp = COMP_TOOLS.get(compress)
174     if not comp:                                  174     if not comp:
175         raise ValueError(f"Unknown compression    175         raise ValueError(f"Unknown compression algorithm '{compress}'")
176                                                   176 
177     with tempfile.NamedTemporaryFile() as comp    177     with tempfile.NamedTemporaryFile() as comp_fname:
178         with open(comp_fname.name, 'wb') as ou    178         with open(comp_fname.name, 'wb') as outf:
179             done = False                          179             done = False
180             for tool in comp.tools.split(','):    180             for tool in comp.tools.split(','):
181                 try:                              181                 try:
182                     subprocess.call([tool, '-c    182                     subprocess.call([tool, '-c'], stdin=inf, stdout=outf)
183                     done = True                   183                     done = True
184                     break                         184                     break
185                 except FileNotFoundError:         185                 except FileNotFoundError:
186                     pass                          186                     pass
187             if not done:                          187             if not done:
188                 raise ValueError(f'Missing too    188                 raise ValueError(f'Missing tool(s): {comp.tools}\n')
189             with open(comp_fname.name, 'rb') a    189             with open(comp_fname.name, 'rb') as compf:
190                 comp_data = compf.read()          190                 comp_data = compf.read()
191     return comp_data                              191     return comp_data
192                                                   192 
193                                                   193 
194 def output_dtb(fsw, seq, fname, arch, compress    194 def output_dtb(fsw, seq, fname, arch, compress):
195     """Write out a single devicetree to the FI    195     """Write out a single devicetree to the FIT
196                                                   196 
197     Args:                                         197     Args:
198         fsw (libfdt.FdtSw): Object to use for     198         fsw (libfdt.FdtSw): Object to use for writing
199         seq (int): Sequence number (1 for firs    199         seq (int): Sequence number (1 for first)
200         fname (str): Filename containing the D    200         fname (str): Filename containing the DTB
201         arch: FIT architecture, e.g. 'arm64'      201         arch: FIT architecture, e.g. 'arm64'
202         compress (str): Compressed algorithm,     202         compress (str): Compressed algorithm, e.g. 'gzip'
203     """                                           203     """
204     with fsw.add_node(f'fdt-{seq}'):              204     with fsw.add_node(f'fdt-{seq}'):
205         fsw.property_string('description', os.    205         fsw.property_string('description', os.path.basename(fname))
206         fsw.property_string('type', 'flat_dt')    206         fsw.property_string('type', 'flat_dt')
207         fsw.property_string('arch', arch)         207         fsw.property_string('arch', arch)
208         fsw.property_string('compression', com    208         fsw.property_string('compression', compress)
209                                                   209 
210         with open(fname, 'rb') as inf:            210         with open(fname, 'rb') as inf:
211             compressed = compress_data(inf, co    211             compressed = compress_data(inf, compress)
212         fsw.property('data', compressed)          212         fsw.property('data', compressed)
213                                                   213 
214                                                   214 
215 def process_dtb(fname, args):                     215 def process_dtb(fname, args):
216     """Process an input DTB, decomposing it if    216     """Process an input DTB, decomposing it if requested and is possible
217                                                   217 
218     Args:                                         218     Args:
219         fname (str): Filename containing the D    219         fname (str): Filename containing the DTB
220         args (Namespace): Program arguments       220         args (Namespace): Program arguments
221     Returns:                                      221     Returns:
222         tuple:                                    222         tuple:
223             str: Model name string                223             str: Model name string
224             str: Root compatible string           224             str: Root compatible string
225             files: list of filenames correspon    225             files: list of filenames corresponding to the DTB
226     """                                           226     """
227     # Get the compatible / model information      227     # Get the compatible / model information
228     with open(fname, 'rb') as inf:                228     with open(fname, 'rb') as inf:
229         data = inf.read()                         229         data = inf.read()
230     fdt = libfdt.FdtRo(data)                      230     fdt = libfdt.FdtRo(data)
231     model = fdt.getprop(0, 'model').as_str()      231     model = fdt.getprop(0, 'model').as_str()
232     compat = fdt.getprop(0, 'compatible')         232     compat = fdt.getprop(0, 'compatible')
233                                                   233 
234     if args.decompose_dtbs:                       234     if args.decompose_dtbs:
235         # Check if the DTB needs to be decompo    235         # Check if the DTB needs to be decomposed
236         path, basename = os.path.split(fname)     236         path, basename = os.path.split(fname)
237         cmd_fname = os.path.join(path, f'.{bas    237         cmd_fname = os.path.join(path, f'.{basename}.cmd')
238         with open(cmd_fname, 'r', encoding='as    238         with open(cmd_fname, 'r', encoding='ascii') as inf:
239             cmd = inf.read()                      239             cmd = inf.read()
240                                                   240 
241         if 'scripts/dtc/fdtoverlay' in cmd:       241         if 'scripts/dtc/fdtoverlay' in cmd:
242             # This depends on the structure of    242             # This depends on the structure of the composite DTB command
243             files = cmd.split()                   243             files = cmd.split()
244             files = files[files.index('-i') +     244             files = files[files.index('-i') + 1:]
245         else:                                     245         else:
246             files = [fname]                       246             files = [fname]
247     else:                                         247     else:
248         files = [fname]                           248         files = [fname]
249                                                   249 
250     return (model, compat, files)                 250     return (model, compat, files)
251                                                   251 
252 def build_fit(args):                              252 def build_fit(args):
253     """Build the FIT from the provided files a    253     """Build the FIT from the provided files and arguments
254                                                   254 
255     Args:                                         255     Args:
256         args (Namespace): Program arguments       256         args (Namespace): Program arguments
257                                                   257 
258     Returns:                                      258     Returns:
259         tuple:                                    259         tuple:
260             bytes: FIT data                       260             bytes: FIT data
261             int: Number of configurations gene    261             int: Number of configurations generated
262             size: Total uncompressed size of d    262             size: Total uncompressed size of data
263     """                                           263     """
264     seq = 0                                       264     seq = 0
265     size = 0                                      265     size = 0
266     fsw = libfdt.FdtSw()                          266     fsw = libfdt.FdtSw()
267     setup_fit(fsw, args.name)                     267     setup_fit(fsw, args.name)
268     entries = []                                  268     entries = []
269     fdts = {}                                     269     fdts = {}
270                                                   270 
271     # Handle the kernel                           271     # Handle the kernel
272     with open(args.kernel, 'rb') as inf:          272     with open(args.kernel, 'rb') as inf:
273         comp_data = compress_data(inf, args.co    273         comp_data = compress_data(inf, args.compress)
274     size += os.path.getsize(args.kernel)          274     size += os.path.getsize(args.kernel)
275     write_kernel(fsw, comp_data, args)            275     write_kernel(fsw, comp_data, args)
276                                                   276 
277     for fname in args.dtbs:                       277     for fname in args.dtbs:
278         # Ignore non-DTB (*.dtb) files            278         # Ignore non-DTB (*.dtb) files
279         if os.path.splitext(fname)[1] != '.dtb    279         if os.path.splitext(fname)[1] != '.dtb':
280             continue                              280             continue
281                                                   281 
282         (model, compat, files) = process_dtb(f    282         (model, compat, files) = process_dtb(fname, args)
283                                                   283 
284         for fn in files:                          284         for fn in files:
285             if fn not in fdts:                    285             if fn not in fdts:
286                 seq += 1                          286                 seq += 1
287                 size += os.path.getsize(fn)       287                 size += os.path.getsize(fn)
288                 output_dtb(fsw, seq, fn, args.    288                 output_dtb(fsw, seq, fn, args.arch, args.compress)
289                 fdts[fn] = seq                    289                 fdts[fn] = seq
290                                                   290 
291         files_seq = [fdts[fn] for fn in files]    291         files_seq = [fdts[fn] for fn in files]
292                                                   292 
293         entries.append([model, compat, files_s    293         entries.append([model, compat, files_seq])
294                                                   294 
295     finish_fit(fsw, entries)                      295     finish_fit(fsw, entries)
296                                                   296 
297     # Include the kernel itself in the returne    297     # Include the kernel itself in the returned file count
298     return fsw.as_fdt().as_bytearray(), seq +     298     return fsw.as_fdt().as_bytearray(), seq + 1, size
299                                                   299 
300                                                   300 
301 def run_make_fit():                               301 def run_make_fit():
302     """Run the tool's main logic"""               302     """Run the tool's main logic"""
303     args = parse_args()                           303     args = parse_args()
304                                                   304 
305     out_data, count, size = build_fit(args)       305     out_data, count, size = build_fit(args)
306     with open(args.output, 'wb') as outf:         306     with open(args.output, 'wb') as outf:
307         outf.write(out_data)                      307         outf.write(out_data)
308                                                   308 
309     ext_fit_size = None                           309     ext_fit_size = None
310     if args.external:                             310     if args.external:
311         mkimage = os.environ.get('MKIMAGE', 'm    311         mkimage = os.environ.get('MKIMAGE', 'mkimage')
312         subprocess.check_call([mkimage, '-E',     312         subprocess.check_call([mkimage, '-E', '-F', args.output],
313                               stdout=subproces    313                               stdout=subprocess.DEVNULL)
314                                                   314 
315         with open(args.output, 'rb') as inf:      315         with open(args.output, 'rb') as inf:
316             data = inf.read()                     316             data = inf.read()
317         ext_fit = libfdt.FdtRo(data)              317         ext_fit = libfdt.FdtRo(data)
318         ext_fit_size = ext_fit.totalsize()        318         ext_fit_size = ext_fit.totalsize()
319                                                   319 
320     if args.verbose:                              320     if args.verbose:
321         comp_size = len(out_data)                 321         comp_size = len(out_data)
322         print(f'FIT size {comp_size:#x}/{comp_    322         print(f'FIT size {comp_size:#x}/{comp_size / 1024 / 1024:.1f} MB',
323               end='')                             323               end='')
324         if ext_fit_size:                          324         if ext_fit_size:
325             print(f', header {ext_fit_size:#x}    325             print(f', header {ext_fit_size:#x}/{ext_fit_size / 1024:.1f} KB',
326                   end='')                         326                   end='')
327         print(f', {count} files, uncompressed     327         print(f', {count} files, uncompressed {size / 1024 / 1024:.1f} MB')
328                                                   328 
329                                                   329 
330 if __name__ == "__main__":                        330 if __name__ == "__main__":
331     sys.exit(run_make_fit())                      331     sys.exit(run_make_fit())
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php