From 0dbf161ce81f226c1627e54e57263412c9766e07 Mon Sep 17 00:00:00 2001 From: cfig Date: Sun, 20 Dec 2020 00:40:59 +0800 Subject: [PATCH] extract_kernel: update from AOSP (with fix) --- aosp/build/tools/extract_kernel.py | 144 +++++++++++++++++++++-------- tools/release.mk | 39 ++++++++ 2 files changed, 143 insertions(+), 40 deletions(-) create mode 100644 tools/release.mk diff --git a/aosp/build/tools/extract_kernel.py b/aosp/build/tools/extract_kernel.py index 42561cf..df2d741 100755 --- a/aosp/build/tools/extract_kernel.py +++ b/aosp/build/tools/extract_kernel.py @@ -39,12 +39,12 @@ COMPRESSION_ALGO = ( # "Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@" # LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n"; LINUX_BANNER_PREFIX = b'Linux version ' -LINUX_BANNER_REGEX = LINUX_BANNER_PREFIX + \ - r'([0-9]+[.][0-9]+[.][0-9]+).* \(.*@.*\) \(.*\) .*\n' +LINUX_BANNER_REGEX = LINUX_BANNER_PREFIX.decode() + \ + r'(?P(?P[0-9]+[.][0-9]+[.][0-9]+).*) \(.*@.*\) \((?P.*)\) .*\n' -def get_version(input_bytes, start_idx): - null_idx = input_bytes.find('\x00', start_idx) +def get_from_release(input_bytes, start_idx, key): + null_idx = input_bytes.find(b'\x00', start_idx) if null_idx < 0: return None try: @@ -53,24 +53,51 @@ def get_version(input_bytes, start_idx): return None mo = re.match(LINUX_BANNER_REGEX, linux_banner) if mo: - return mo.group(1) + return mo.group(key) return None -def dump_version(input_bytes): +def dump_from_release(input_bytes, key): + """ + Helper of dump_version and dump_release + """ idx = 0 while True: idx = input_bytes.find(LINUX_BANNER_PREFIX, idx) if idx < 0: return None - version = get_version(input_bytes, idx) - if version: - return version + value = get_from_release(input_bytes, idx, key) + if value: + return value idx += len(LINUX_BANNER_PREFIX) +def dump_version(input_bytes): + """ + Dump kernel version, w.x.y, from input_bytes. Search for the string + "Linux version " and do pattern matching after it. See LINUX_BANNER_REGEX. + """ + return dump_from_release(input_bytes, "version") + + +def dump_compiler(input_bytes): + """ + Dump kernel version, w.x.y, from input_bytes. Search for the string + "Linux version " and do pattern matching after it. See LINUX_BANNER_REGEX. + """ + return dump_from_release(input_bytes, "compiler") + + +def dump_release(input_bytes): + """ + Dump kernel release, w.x.y-..., from input_bytes. Search for the string + "Linux version " and do pattern matching after it. See LINUX_BANNER_REGEX. + """ + return dump_from_release(input_bytes, "release") + + def dump_configs(input_bytes): """ Dump kernel configuration from input_bytes. This can be done when @@ -100,19 +127,25 @@ def dump_configs(input_bytes): return o -def try_decompress(cmd, search_bytes, input_bytes): - idx = input_bytes.find(search_bytes) - if idx < 0: - return None - - idx = 0 +def try_decompress_bytes(cmd, input_bytes): sp = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) - o, _ = sp.communicate(input=input_bytes[idx:]) + o, _ = sp.communicate(input=input_bytes) # ignore errors return o +def try_decompress(cmd, search_bytes, input_bytes): + idx = 0 + while True: + idx = input_bytes.find(search_bytes, idx) + if idx < 0: + return + + yield try_decompress_bytes(cmd, input_bytes[idx:]) + idx += 1 + + def decompress_dump(func, input_bytes): """ Run func(input_bytes) first; and if that fails (returns value evaluates to @@ -122,18 +155,38 @@ def decompress_dump(func, input_bytes): if o: return o for cmd, search_bytes in COMPRESSION_ALGO: - decompressed = try_decompress(cmd, search_bytes, input_bytes) - if decompressed: - o = func(decompressed) - if o: - return o + for decompressed in try_decompress(cmd, search_bytes, input_bytes): + if decompressed: + o = decompress_dump(func, decompressed) + if o: + return o # Force decompress the whole file even if header doesn't match - decompressed = try_decompress(cmd, b"", input_bytes) + decompressed = try_decompress_bytes(cmd, input_bytes) if decompressed: - o = func(decompressed) + o = decompress_dump(func, decompressed) if o: return o + +def dump_to_file(f, dump_fn, input_bytes, desc): + """ + Call decompress_dump(dump_fn, input_bytes) and write to f. If it fails, return + False; otherwise return True. + """ + if f is not None: + o = decompress_dump(dump_fn, input_bytes) + if o: + if isinstance(o, str): + f.write(o.encode()) + else: + f.write(o) + else: + sys.stderr.write( + "Cannot extract kernel {}".format(desc)) + return False + return True + + def main(): parser = argparse.ArgumentParser( formatter_class=argparse.RawTextHelpFormatter, @@ -159,6 +212,20 @@ def main(): nargs='?', type=argparse.FileType('wb'), const=sys.stdout) + parser.add_argument('--output-release', + help='If specified, write kernel release. Use stdout if ' + 'no file is specified.', + metavar='FILE', + nargs='?', + type=argparse.FileType('wb'), + const=sys.stdout) + parser.add_argument('--output-compiler', + help='If specified, write the compiler information. Use stdout if no file ' + 'is specified.', + metavar='FILE', + nargs='?', + type=argparse.FileType('wb'), + const=sys.stdout) parser.add_argument('--tools', help='Decompression tools to use. If not specified, PATH ' 'is searched.', @@ -175,25 +242,22 @@ def main(): input_bytes = args.input.read() ret = 0 - if args.output_configs is not None: - o = decompress_dump(dump_configs, input_bytes) - if o: - args.output_configs.write(o) - else: - sys.stderr.write( - "Cannot extract kernel configs in {}".format(args.input.name)) - ret = 1 - if args.output_version is not None: - o = decompress_dump(dump_version, input_bytes) - if o: - args.output_version.write(o) - else: - sys.stderr.write( - "Cannot extract kernel versions in {}".format(args.input.name)) - ret = 1 + if not dump_to_file(args.output_configs, dump_configs, input_bytes, + "configs in {}".format(args.input.name)): + ret = 1 + if not dump_to_file(args.output_version, dump_version, input_bytes, + "version in {}".format(args.input.name)): + ret = 1 + if not dump_to_file(args.output_release, dump_release, input_bytes, + "kernel release in {}".format(args.input.name)): + ret = 1 + + if not dump_to_file(args.output_compiler, dump_compiler, input_bytes, + "kernel compiler in {}".format(args.input.name)): + ret = 1 return ret if __name__ == '__main__': - exit(main()) + sys.exit(main()) diff --git a/tools/release.mk b/tools/release.mk new file mode 100644 index 0000000..75b81e9 --- /dev/null +++ b/tools/release.mk @@ -0,0 +1,39 @@ +# +# release.mk +# yu, 2020-12-20 00:19 +# + +define gw +#!/usr/bin/env sh\n +if [ "x$$1" = "xassemble" ]; then\n + echo "already assembled"\n + exit\n +fi\n +if [ "x$$1" = "xcheck" ]; then\n +echo "no check is needed"\n +exit 0\n +fi\n +if [ "x$$1" = "xclean" ]; then\n +echo "no cleaning is needed"\n +exit 0\n +fi\n +java -jar bbootimg/bbootimg.jar $$* + +endef +export gw +all: + cd ../bbootimg && gradle build + cp ../bbootimg/build/libs/bbootimg.jar . + cd ../aosp/boot_signer && gradle build + cp ../aosp/boot_signer/build/libs/boot_signer.jar . + cd .. && rm -fr avbImpl bbootimg build build.gradle.kts gradle gradlew gradlew.bat settings.gradle.kts + cd ../aosp && rm -r libavb1.1 libavb1.2 mkbootfs.10 mkbootfs.11 + rm -r ../aosp/boot_signer + mkdir -p ../aosp/boot_signer/build/libs/ && mv boot_signer.jar ../aosp/boot_signer/build/libs/ + mkdir ../bbootimg && mv bbootimg.jar ../bbootimg/ + echo $$gw > gradlew + chmod 755 gradlew + mv gradlew ../ + +# vim:ft=make +#