diff options
author | Jiyong Park <jiyong@google.com> | 2022-06-13 20:39:29 +0900 |
---|---|---|
committer | Jiyong Park <jiyong@google.com> | 2022-06-17 13:28:25 +0000 |
commit | 87283c202e38fd009b4a0dacee8542e559732af7 (patch) | |
tree | bc222b85e2297c342a614db2d64b87457a5b38db | |
parent | 31ccc779a1133b2252d64120aab31dfec3273642 (diff) | |
download | build-87283c202e38fd009b4a0dacee8542e559732af7.tar.gz |
download_from_ci: get_binary_kernel_version works for arm64 and x86
So far, get_binary_kernel_version worked only for arm64 and not for
x86_64. This was because the function was implemented by grep'ing a
specific string literal 'Linux version ' embedded somewhere in the file.
Unfortunately, that string literal doesn't exist in x86_64.
This change fixes the problem by following the x86 kernel image
format https://www.kernel.org/doc/Documentation/x86/boot.txt to locate
and extract the version string correctly.
The code then falls back to grep'ing the 'Linux version ' for the arm64
kernel.
Bug: N/A
Test: run download_from_ci
Change-Id: I05f19a78377a6a07ba96ee894a0796af461f56df
-rwxr-xr-x | gki/download_from_ci | 30 |
1 files changed, 25 insertions, 5 deletions
diff --git a/gki/download_from_ci b/gki/download_from_ci index 946802ec..6340fa39 100755 --- a/gki/download_from_ci +++ b/gki/download_from_ci @@ -26,6 +26,7 @@ import pathlib import re import shlex import shutil +import struct import subprocess import sys import tarfile @@ -169,15 +170,34 @@ def commit_prebuilts(output_dir, gitlog, name="kernel"): print("Use the following command from your Android repository to upload your changes:") print(" repo upload -t --br {}".format(branch_name)) +def extract_version_from_kernel(path): + """Extracts version string from kernel following https://www.kernel.org/doc/Documentation/x86/boot.txt""" + # Note that this works only for x86 kernel image + with open(path, mode='rb') as file: + # 4 byte magic string HdrS at 0x202 + file.seek(0x202) + magic = file.read(4) + if magic != b"HdrS": + # fallback to grep (for the arm64 case) + return str(subprocess.check_output(["grep", "-a", "Linux version ", path])) + # 2 byte offset to the version string at 0x20e + file.seek(0x20e) + offset = struct.unpack('h', file.read(2))[0] + # The offset is actually from the header which is at 0x200 + file.seek(offset+0x200) + # read the first null-terminated string with a reasonable assumption that + # it isn't longer than 1023 bytes + return file.read(1024).split(b'\0')[0].decode() + def get_binary_kernel_version(path): """Returns a tuple of strings of the x.y.z (LTS) version and the SHA.""" - rawdata = subprocess.check_output(["grep", "-a", "Linux version ", path]) - pattern = b"Linux version (?P<release>(?P<version>[0-9]+[.][0-9]+[.][0-9]+)(-rc\d+)?(-\w+(-\d+)?)?-\d+-g(?P<sha>\w+)-ab\d+) \(.*@.*\) \((?P<compiler>.*)\) .*\n" - result = re.search(pattern, rawdata) + version = extract_version_from_kernel(path) + pattern = "(?P<release>(?P<version>[0-9]+[.][0-9]+[.][0-9]+)(-rc\d+)?(-\w+(-\d+)?)?-\d+-g(?P<sha>\w+)-ab\d+)" + result = re.search(pattern, version) + if not result: raise Exception("Could not determine version in kernel binary " + path) - return (result.group("version").decode('ascii'), - result.group("sha").decode('ascii')) + return (result.group("version"), result.group("sha")) def get_binary_u_boot_version(path): """Returns a tuple of strings of the YYYY.MM(-rcXX) version and the SHA.""" |