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