xref: /aosp_15_r20/tools/treble/gki/repack_gki_lib.py (revision 105f628577ac4ba0e277a494fbb614ed8c12a994)
1*105f6285SAndroid Build Coastguard Worker"""Helper library for repacking GKI boot images."""
2*105f6285SAndroid Build Coastguard Workerimport os
3*105f6285SAndroid Build Coastguard Workerimport shutil
4*105f6285SAndroid Build Coastguard Workerimport subprocess
5*105f6285SAndroid Build Coastguard Workerimport tempfile
6*105f6285SAndroid Build Coastguard Worker
7*105f6285SAndroid Build Coastguard Workerfrom treble.fetcher import fetcher_lib
8*105f6285SAndroid Build Coastguard Worker
9*105f6285SAndroid Build Coastguard Worker
10*105f6285SAndroid Build Coastguard Workerdef fetch_bootimg(client, out_dir, build_id, kernel_version, target):
11*105f6285SAndroid Build Coastguard Worker  """Fetches boot.img artifacts from a given build ID."""
12*105f6285SAndroid Build Coastguard Worker  fetcher_lib.fetch_artifacts(
13*105f6285SAndroid Build Coastguard Worker      client=client,
14*105f6285SAndroid Build Coastguard Worker      build_id=build_id,
15*105f6285SAndroid Build Coastguard Worker      target=target,
16*105f6285SAndroid Build Coastguard Worker      pattern=r'(gki_.*-img-.*\.zip|gki_.*-target_files-.*\.zip|otatools.zip)'
17*105f6285SAndroid Build Coastguard Worker      .format(version=kernel_version),
18*105f6285SAndroid Build Coastguard Worker      out_dir=out_dir)
19*105f6285SAndroid Build Coastguard Worker
20*105f6285SAndroid Build Coastguard Worker
21*105f6285SAndroid Build Coastguard Workerdef fetch_kernel(client, out_dir, build_id, kernel_target, kernel_debug_target):
22*105f6285SAndroid Build Coastguard Worker  """Fetches kernel artifacts from a given build ID."""
23*105f6285SAndroid Build Coastguard Worker  kernel_dir = os.path.join(out_dir, 'kernel')
24*105f6285SAndroid Build Coastguard Worker  kernel_debug_dir = os.path.join(out_dir, 'kernel_debug')
25*105f6285SAndroid Build Coastguard Worker  os.makedirs(kernel_dir)
26*105f6285SAndroid Build Coastguard Worker  os.makedirs(kernel_debug_dir)
27*105f6285SAndroid Build Coastguard Worker
28*105f6285SAndroid Build Coastguard Worker  fetcher_lib.fetch_artifacts(
29*105f6285SAndroid Build Coastguard Worker      client=client,
30*105f6285SAndroid Build Coastguard Worker      build_id=build_id,
31*105f6285SAndroid Build Coastguard Worker      target=kernel_target,
32*105f6285SAndroid Build Coastguard Worker      pattern=r'(Image|Image.lz4|System\.map|abi_symbollist|vmlinux|vmlinux.symvers)',
33*105f6285SAndroid Build Coastguard Worker      out_dir=kernel_dir)
34*105f6285SAndroid Build Coastguard Worker  fetcher_lib.fetch_artifacts(
35*105f6285SAndroid Build Coastguard Worker      client=client,
36*105f6285SAndroid Build Coastguard Worker      build_id=build_id,
37*105f6285SAndroid Build Coastguard Worker      target=kernel_debug_target,
38*105f6285SAndroid Build Coastguard Worker      pattern=r'(Image|Image.lz4|System\.map|abi-generated.xml|abi-full-generated.xml|vmlinux|vymlinx.symvers)',
39*105f6285SAndroid Build Coastguard Worker      out_dir=kernel_debug_dir)
40*105f6285SAndroid Build Coastguard Worker
41*105f6285SAndroid Build Coastguard Worker  print('Compressing kernels')
42*105f6285SAndroid Build Coastguard Worker
43*105f6285SAndroid Build Coastguard Worker  def compress_kernel(kernel_path):
44*105f6285SAndroid Build Coastguard Worker    zipped_kernel_path = os.path.join(os.path.dirname(kernel_path), 'Image.gz')
45*105f6285SAndroid Build Coastguard Worker    with open(zipped_kernel_path, 'wb') as zipped_kernel:
46*105f6285SAndroid Build Coastguard Worker      cmd = [
47*105f6285SAndroid Build Coastguard Worker          'gzip',
48*105f6285SAndroid Build Coastguard Worker          '-nc',
49*105f6285SAndroid Build Coastguard Worker          kernel_path,
50*105f6285SAndroid Build Coastguard Worker      ]
51*105f6285SAndroid Build Coastguard Worker      print(' '.join(cmd))
52*105f6285SAndroid Build Coastguard Worker      subprocess.check_call(cmd, stdout=zipped_kernel)
53*105f6285SAndroid Build Coastguard Worker
54*105f6285SAndroid Build Coastguard Worker  compress_kernel(os.path.join(kernel_dir, 'Image'))
55*105f6285SAndroid Build Coastguard Worker  compress_kernel(os.path.join(kernel_debug_dir, 'Image'))
56*105f6285SAndroid Build Coastguard Worker
57*105f6285SAndroid Build Coastguard Worker  return kernel_dir, kernel_debug_dir
58*105f6285SAndroid Build Coastguard Worker
59*105f6285SAndroid Build Coastguard Worker
60*105f6285SAndroid Build Coastguard Workerdef _replace_kernel(bootimg_path, kernel_path):
61*105f6285SAndroid Build Coastguard Worker  """Unpacks a boot.img, replaces the kernel, then repacks."""
62*105f6285SAndroid Build Coastguard Worker  with tempfile.TemporaryDirectory() as unpack_dir:
63*105f6285SAndroid Build Coastguard Worker    print('Unpacking bootimg %s' % bootimg_path)
64*105f6285SAndroid Build Coastguard Worker    cmd = [
65*105f6285SAndroid Build Coastguard Worker        'out/host/linux-x86/bin/unpack_bootimg',
66*105f6285SAndroid Build Coastguard Worker        '--boot_img',
67*105f6285SAndroid Build Coastguard Worker        bootimg_path,
68*105f6285SAndroid Build Coastguard Worker        '--out',
69*105f6285SAndroid Build Coastguard Worker        unpack_dir,
70*105f6285SAndroid Build Coastguard Worker        '--format',
71*105f6285SAndroid Build Coastguard Worker        'mkbootimg',
72*105f6285SAndroid Build Coastguard Worker    ]
73*105f6285SAndroid Build Coastguard Worker    print(' '.join(cmd))
74*105f6285SAndroid Build Coastguard Worker    mkbootimg_args = subprocess.check_output(cmd).decode('utf-8').split(' ')
75*105f6285SAndroid Build Coastguard Worker    print('Copying kernel %s' % kernel_path)
76*105f6285SAndroid Build Coastguard Worker    shutil.copy(kernel_path, os.path.join(unpack_dir, 'kernel'))
77*105f6285SAndroid Build Coastguard Worker    print('Repacking with mkbootimg')
78*105f6285SAndroid Build Coastguard Worker    cmd = [
79*105f6285SAndroid Build Coastguard Worker        'out/host/linux-x86/bin/mkbootimg',
80*105f6285SAndroid Build Coastguard Worker        '--output',
81*105f6285SAndroid Build Coastguard Worker        bootimg_path,
82*105f6285SAndroid Build Coastguard Worker    ] + mkbootimg_args
83*105f6285SAndroid Build Coastguard Worker    print(' '.join(cmd))
84*105f6285SAndroid Build Coastguard Worker    subprocess.check_call(cmd)
85*105f6285SAndroid Build Coastguard Worker
86*105f6285SAndroid Build Coastguard Worker
87*105f6285SAndroid Build Coastguard Workerdef repack_bootimgs(bootimg_dir, kernel_dir, kernel_debug_dir):
88*105f6285SAndroid Build Coastguard Worker  """Repacks all boot images in a given dir using the provided kernels."""
89*105f6285SAndroid Build Coastguard Worker  for bootimg_path in os.listdir(bootimg_dir):
90*105f6285SAndroid Build Coastguard Worker    bootimg_path = os.path.join(bootimg_dir, bootimg_path)
91*105f6285SAndroid Build Coastguard Worker    if not bootimg_path.endswith('.img'):
92*105f6285SAndroid Build Coastguard Worker      continue
93*105f6285SAndroid Build Coastguard Worker
94*105f6285SAndroid Build Coastguard Worker    kernel_name = 'Image'
95*105f6285SAndroid Build Coastguard Worker    if '-gz' in bootimg_path:
96*105f6285SAndroid Build Coastguard Worker      kernel_name = 'Image.gz'
97*105f6285SAndroid Build Coastguard Worker    elif '-lz4' in bootimg_path:
98*105f6285SAndroid Build Coastguard Worker      kernel_name = 'Image.lz4'
99*105f6285SAndroid Build Coastguard Worker
100*105f6285SAndroid Build Coastguard Worker    kernel_path = os.path.join(kernel_dir, kernel_name)
101*105f6285SAndroid Build Coastguard Worker    if bootimg_path.endswith('-allsyms.img'):
102*105f6285SAndroid Build Coastguard Worker      kernel_path = os.path.join(kernel_debug_dir, kernel_name)
103*105f6285SAndroid Build Coastguard Worker
104*105f6285SAndroid Build Coastguard Worker    _replace_kernel(bootimg_path, kernel_path)
105*105f6285SAndroid Build Coastguard Worker
106*105f6285SAndroid Build Coastguard Worker
107*105f6285SAndroid Build Coastguard Workerdef repack_img_zip(img_zip_path, kernel_dir, kernel_debug_dir, kernel_version):
108*105f6285SAndroid Build Coastguard Worker  """Repacks boot images within an img.zip archive."""
109*105f6285SAndroid Build Coastguard Worker  with tempfile.TemporaryDirectory() as unzip_dir:
110*105f6285SAndroid Build Coastguard Worker    pattern = 'boot-{}*'.format(kernel_version)
111*105f6285SAndroid Build Coastguard Worker    print('Unzipping %s to repack bootimgs' % img_zip_path)
112*105f6285SAndroid Build Coastguard Worker    cmd = [
113*105f6285SAndroid Build Coastguard Worker        'unzip',
114*105f6285SAndroid Build Coastguard Worker        '-d',
115*105f6285SAndroid Build Coastguard Worker        unzip_dir,
116*105f6285SAndroid Build Coastguard Worker        img_zip_path,
117*105f6285SAndroid Build Coastguard Worker        pattern,
118*105f6285SAndroid Build Coastguard Worker    ]
119*105f6285SAndroid Build Coastguard Worker    print(' '.join(cmd))
120*105f6285SAndroid Build Coastguard Worker    subprocess.check_call(cmd)
121*105f6285SAndroid Build Coastguard Worker    repack_bootimgs(unzip_dir, kernel_dir, kernel_debug_dir)
122*105f6285SAndroid Build Coastguard Worker    cmd = [
123*105f6285SAndroid Build Coastguard Worker        'zip',
124*105f6285SAndroid Build Coastguard Worker        img_zip_path,
125*105f6285SAndroid Build Coastguard Worker        pattern,
126*105f6285SAndroid Build Coastguard Worker    ]
127*105f6285SAndroid Build Coastguard Worker    print(' '.join(cmd))
128*105f6285SAndroid Build Coastguard Worker    subprocess.check_call(cmd, cwd=unzip_dir)
129*105f6285SAndroid Build Coastguard Worker
130*105f6285SAndroid Build Coastguard Worker
131*105f6285SAndroid Build Coastguard Workerdef replace_target_files_zip_kernels(target_files_zip_path, kernel_out_dir,
132*105f6285SAndroid Build Coastguard Worker                                     kernel_version):
133*105f6285SAndroid Build Coastguard Worker  """Replaces the BOOT/kernel-* kernels within a target_files.zip archive."""
134*105f6285SAndroid Build Coastguard Worker  with tempfile.TemporaryDirectory() as unzip_dir:
135*105f6285SAndroid Build Coastguard Worker    pattern = 'BOOT/kernel-{}*'.format(kernel_version)
136*105f6285SAndroid Build Coastguard Worker    print(
137*105f6285SAndroid Build Coastguard Worker        'Unzipping %s to replace kernels in preparation for signing' %
138*105f6285SAndroid Build Coastguard Worker        target_files_zip_path,)
139*105f6285SAndroid Build Coastguard Worker    cmd = [
140*105f6285SAndroid Build Coastguard Worker        'unzip',
141*105f6285SAndroid Build Coastguard Worker        '-d',
142*105f6285SAndroid Build Coastguard Worker        unzip_dir,
143*105f6285SAndroid Build Coastguard Worker        target_files_zip_path,
144*105f6285SAndroid Build Coastguard Worker        pattern,
145*105f6285SAndroid Build Coastguard Worker    ]
146*105f6285SAndroid Build Coastguard Worker    print(' '.join(cmd))
147*105f6285SAndroid Build Coastguard Worker    subprocess.check_call(cmd)
148*105f6285SAndroid Build Coastguard Worker    for kernel in os.listdir(kernel_out_dir):
149*105f6285SAndroid Build Coastguard Worker      if kernel.startswith('kernel-{}'.format(kernel_version)):
150*105f6285SAndroid Build Coastguard Worker        print('Copying %s' % kernel)
151*105f6285SAndroid Build Coastguard Worker        shutil.copy(
152*105f6285SAndroid Build Coastguard Worker            os.path.join(kernel_out_dir, kernel),
153*105f6285SAndroid Build Coastguard Worker            os.path.join(unzip_dir, 'BOOT'))
154*105f6285SAndroid Build Coastguard Worker    cmd = [
155*105f6285SAndroid Build Coastguard Worker        'zip',
156*105f6285SAndroid Build Coastguard Worker        target_files_zip_path,
157*105f6285SAndroid Build Coastguard Worker        pattern,
158*105f6285SAndroid Build Coastguard Worker    ]
159*105f6285SAndroid Build Coastguard Worker    print(' '.join(cmd))
160*105f6285SAndroid Build Coastguard Worker    subprocess.check_call(cmd, cwd=unzip_dir)
161