From 9da920b9c8464ca953aed1de2cbf838acfbb0825 Mon Sep 17 00:00:00 2001 From: Denis 'GNUtoo' Carikli Date: Wed, 29 Sep 2021 17:54:07 +0200 Subject: add_adb_root: bootimages: Add support for xz compressed ramdisks Since Linux 3.0.101 which is used in Replicant 6.0, the kernel size increased a lot. Because of that, in Replicant 11, the recovery initramfs is compressed with xz to fit in the 8MiB RECOVERY partition of the Galaxy SIII (GT-I9300) and Galaxy SIII 4G (GT-I9305). Having the ability to add root to Replicant 11 recovery images helps a lot with the development or configuration of the recovery and install procedure as with this script we can have a shell in the recovery (to look at partitions, retrieve logs, etc) without needing to boot and setup Replicant. This script was also tested a Replicant 11 recovery on a Galaxy SIII (GT-I9300), and once flashed the recovery boots and we can get a shell with 'sudo adb shell'. Signed-off-by: Denis 'GNUtoo' Carikli --- images/add_adb_root/add_adb_root.py | 60 ++++++++++++++++++++++++++++++++----- 1 file changed, 52 insertions(+), 8 deletions(-) diff --git a/images/add_adb_root/add_adb_root.py b/images/add_adb_root/add_adb_root.py index 8dc6d34..4063576 100755 --- a/images/add_adb_root/add_adb_root.py +++ b/images/add_adb_root/add_adb_root.py @@ -14,6 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . import enum +import magic import os import re import sh @@ -30,6 +31,7 @@ class ImageType(enum.Enum): class CompressionType(enum.Enum): none = 0 gz = 1 + xz = 2 class Bootimage(object): def __init__(self, path): @@ -39,7 +41,9 @@ class Bootimage(object): self._tmpdir = tempfile.mkdtemp() self._kernel = self._tmpdir + os.sep + "kernel.img" - self._ramdisk = self._tmpdir + os.sep + "ramdisk.cpio.gz" + # We don't know yet the compression type of the ramdisk so we use + # a generic .img instead of a specific extension like .gz or .xz + self._ramdisk = self._tmpdir + os.sep + "ramdisk.cpio.img" self._config = self._tmpdir + os.sep + "bootimg.cfg" def _get_metadata(self): @@ -98,8 +102,8 @@ class Bootimage(object): def add_adb_root(self, output_file_path): self.extract() - self._ramdisk = Ramdisk(self._ramdisk, - CompressionType.gz).add_adb_root() + compression = identify_compression_type(self._ramdisk) + self._ramdisk = Ramdisk(self._ramdisk, compression).add_adb_root() self.recreate(output_file_path) return output_file_path @@ -208,14 +212,39 @@ class Ramdisk(object): def compress(self): if self._compression_type is not CompressionType.none: - sh.gzip("--no-name", self._path) - self._path = self._path + ".gz" + if self._compression_type == CompressionType.gz: + sh.gzip("--no-name", self._path) + self._path = self._path + ".gz" + elif self._compression_type == CompressionType.xz: + # TODO: also support other architectures than ARM + # See scripts/xz_wrap.sh in Linux source code for more details + sh.xz("--check=crc32", "--arm", "--lzma2=dict=32M", self._path) + self._path = self._path + ".xz" + return self._path def uncompress(self): - if self._compression_type is not CompressionType.none: - sh.gunzip(self._path) - self._path = re.sub("\.gz$", "", self._path) + # The path looks like that: [...]/ramdisk.cpio.img. The .img is there + # because we needed to extract the file before finding out how it was + # compressed or if it was not compressed. + new_path = None + if self._compression_type == CompressionType.none: + new_path = re.sub("\.img$", "", self._path) + elif self._compression_type == CompressionType.gz: + new_path = re.sub("\.img$", ".gz", self._path) + elif self._compression_type == CompressionType.xz: + new_path = re.sub("\.img$", ".xz", self._path) + + os.rename(self._path, new_path) + self._path = new_path + + if self._compression_type == CompressionType.gz: + sh.gunzip(self._path) + self._path = re.sub("\.gz$", "", self._path) + elif self._compression_type == CompressionType.xz: + sh.unxz(self._path) + self._path = re.sub("\.xz$", "", self._path) + return self._path def add_adb_root(self): @@ -237,6 +266,21 @@ def usage(progname): progname)) sys.exit(1) +def identify_compression_type(path): + m = magic.detect_from_filename(path) + if not m: + print("/!\ MIME type not found for {}".format(path)) + sys.exit(1) + mime_type = m.mime_type + if mime_type == 'application/gzip': + return CompressionType.gz + elif mime_type == 'application/x-xz': + return CompressionType.xz + else: + print("/!\ TODO: MIME type {} (of file {}) is not implemented".format( + m.mime_type, path)) + sys.exit(1) + def identify_image_type(path): try: output = sh.abootimg("-i", path) -- cgit v1.2.3