You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Android_boot_image_editor/build.gradle

307 lines
11 KiB
Groovy

apply plugin: 'c'
apply plugin: 'java'
apply plugin: 'groovy'
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.RuntimeException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// ----------------------------------------------------------------------------
model {
buildTypes {
release
}
components {
mkbootfs(NativeExecutableSpec) {
binaries.all {
}
}
}
}
// ----------------------------------------------------------------------------
// global
// ----------------------------------------------------------------------------
def workdir='build/unzip_boot'
project.ext.rootWorkDir = new File(workdir).getAbsolutePath()
def defaultRootDir = workdir + "/root"
String[] bins = [ "sh", "logcat", "logd", "linker", "toolbox", "toybox", "applypatch" ]
String[] libs = [ "libdl.so", "libutils.so", "libc++.so", "libc.so", "libm.so", "libz.so", "libstdc++.so", "libcutils.so", "libselinux.so", "liblog.so", "libpcre.so", "libsysutils.so", "libnl.so", "libbase.so", "libbacktrace.so", "libunwind.so" ]
boolean gDebug=true
String activeImg = null;
if (new File("boot.img").exists()) {
activeImg = "boot.img";
} else if (new File("recovery.img").exists()) {
activeImg = "recovery.img";
}
project.ext.outClearIMg = new File(String.format("%s.clear", activeImg)).getAbsolutePath()
project.ext.mkbootimgBin = new File("src/mkbootimg/mkbootimg").getAbsolutePath()
println("Active image target: " + activeImg);
// ----------------------------------------------------------------------------
// tasks
// ----------------------------------------------------------------------------
task unpack_bootimg(type: JavaExec, dependsOn: ['abootimg:abootimg']) {
doFirst {
def rootdir = new File(workdir)
if (rootdir.exists()) {
rootdir.deleteDir()
}
rootdir.mkdirs()
}
main = 'cfig.bootimg.abootimg'
classpath = files("abootimg/build/libs/abootimg.jar")
maxHeapSize '512m'
args String.format("%s", activeImg), workdir
}
task unpack_ramdisk_gz << {
unGnuzipFile(workdir+"/ramdisk.img.gz", workdir + "/ramdisk.img")
}
unpack_ramdisk_gz.dependsOn(unpack_bootimg)
task unpack_cpio(type: Exec, dependsOn: unpack_ramdisk_gz) {
doFirst {
def rootdir = new File(workdir+ "/root")
if (rootdir.exists()) {
rootdir.deleteDir()
}
rootdir.mkdirs()
}
workingDir workdir + "/root"
executable 'cpio'
args = ['-i', '-F', '../ramdisk.img']
}
task unpack(type: Delete, dependsOn: unpack_cpio) {
description "extract boot.img or recovery.img"
delete workdir + "/ramdisk.img.gz"
delete workdir + "/ramdisk.img"
}
task pack_ramdisk_and_gz { Task task ->
def rootDir = defaultRootDir
if (null != System.getProperty("ANDROID_PRODUCT_OUT")) {
rootDir = System.getProperty("ANDROID_PRODUCT_OUT") + "/root"
}
doLast {
if (!rootDir.equals(defaultRootDir)) {
println("Warning:")
println("Warning:")
println("Warning:\tUsing [" + rootDir + "] for target root")
println("Warning:")
println("Warning:")
}
ByteArrayOutputStream mkbootfs_out = new ByteArrayOutputStream()
task.project.exec {
commandLine = [ 'build/exe/mkbootfs/mkbootfs', rootDir ]
standardOutput = mkbootfs_out
}
def ByteArrayInputStream gzip_in = new ByteArrayInputStream(mkbootfs_out.buf)
gnuZipFile(workdir + "/ramdisk.img.gz", gzip_in)
}
}
pack_ramdisk_and_gz.dependsOn('mkbootfsExecutable')
void unGnuzipFile(String compressedFile, String decompressedFile) throws IOException {
byte[] buffer = new byte[1024];
try {
FileInputStream fileIn = new FileInputStream(compressedFile);
GZIPInputStream gZIPInputStream = new GZIPInputStream(fileIn);
FileOutputStream fileOutputStream = new FileOutputStream(decompressedFile);
int bytes_read;
while ((bytes_read = gZIPInputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, bytes_read);
}
gZIPInputStream.close();
fileOutputStream.close();
System.out.println("The file was decompressed successfully!");
} catch (IOException ex) {
throw ex;
}
}
void gnuZipFile(String compressedFile, InputStream fis) throws IOException {
byte[] buffer = new byte[1024];
try {
FileOutputStream fos = new FileOutputStream(compressedFile);
GZIPOutputStream gos = new GZIPOutputStream(fos);
int bytes_read;
while ((bytes_read = fis.read(buffer)) > 0) {
gos .write(buffer, 0, bytes_read);
}
gos.finish();
gos.close();
System.out.println("The file compressed successfully!");
} catch (IOException ex) {
throw ex;
}
}
void gnuZipFile(String compressedFile, String decompressedFile) throws IOException {
byte[] buffer = new byte[1024];
try {
FileOutputStream fos = new FileOutputStream(compressedFile);
GZIPOutputStream gos = new GZIPOutputStream(fos);
FileInputStream fis = new FileInputStream(decompressedFile);
int bytes_read;
while ((bytes_read = fis.read(buffer)) > 0) {
gos .write(buffer, 0, bytes_read);
}
fis.close();
gos.finish();
gos.close();
System.out.println("The file compressed successfully!");
} catch (IOException ex) {
throw ex;
}
}
task pack(type: JavaExec, dependsOn: ['abootimg:pack_clear', 'abootimg:pack_clear2', 'abootimg:pack_clear3', 'boot_signer:jar']) {
main = 'com.android.verity.BootSignature'
classpath = files("boot_signer/build/libs/boot_signer.jar")
maxHeapSize '512m'
args '/boot', activeImg + '.clear', 'security/verity.pk8', 'security/verity.x509.pem', activeImg + '.signed'
}
task _setup(type: Copy) {
from 'src/test/resources/boot.img'
into '.'
}
void Run(List<String> inCmd, String inWorkdir = null) {
println("CMD:" + inCmd)
if (inWorkdir == null) {
inWorkdir = ".";
}
ProcessBuilder pb = new ProcessBuilder(inCmd)
.directory(new File(inWorkdir))
.redirectErrorStream(true);
Process p = pb.start()
p.inputStream.eachLine {println it}
p.waitFor();
assert 0 == p.exitValue()
}
void Run(String inCmd, String inWorkdir = null) {
Run(Arrays.asList(inCmd.split()), inWorkdir);
}
boolean RunFunc(List<String> inCmd, String inWorkdir = null) {
println("CMD:" + inCmd)
if (inWorkdir == null) {
inWorkdir = ".";
}
ProcessBuilder pb = new ProcessBuilder(inCmd)
.directory(new File(inWorkdir))
.redirectErrorStream(true);
Process p = pb.start()
p.inputStream.eachLine {println it}
p.waitFor();
return 0 == p.exitValue();
}
void RunFunc(String inCmd, String inWorkdir = null) {
RunFunc(Arrays.asList(inCmd.split()), inWorkdir);
}
void updateBootImage(String activeImg) {
String flashTarget = null;
switch (activeImg) {
case "boot.img":
flashTarget = "/dev/block/by-name/boot";
break;
case "recovery.img":
flashTarget = "/dev/block/by-name/recovery";
break;
}
Run("adb root")
Run("adb push " + activeImg + ".signed /cache/")
List<String> cmd2 = ["adb", "shell", "dd if=/cache/" + activeImg + ".signed of=" + flashTarget];
Run(cmd2)
cmd2 = ["adb", "shell", "rm -f /cache/" + activeImg + ".signed"];
Run(cmd2)
}
task flash << {
updateBootImage(activeImg)
}
void rebootRecovery() {
Run("adb reboot recovery")
}
task rr << {
rebootRecovery()
}
void updateLinks(String inWorkdir) {
String sysBinDir = inWorkdir + "/root/system/bin";
String[] toolboxLinks = [ "df", "getevent", "iftop", "ioctl", "ionice", "log", "ls", "lsof", "mount", "nandread", "newfs_msdos", "ps", "prlimit", "renice", "sendevent", "start", "stop", "top", "uptime", "watchprops", "dd", "du" ];
String[] toyboxLinks = [ "acpi", "basename", "blockdev", "bzcat", "cal", "cat", "chcon", "chgrp", "chmod", "chown", "chroot", "cksum", "clear", "comm", "cmp", "cp", "cpio", "cut", "date", "dirname", "dmesg", "dos2unix", "echo", "env", "expand", "expr", "fallocate", "false", "find", "free", "getenforce", "getprop", "groups", "head", "hostname", "hwclock", "id", "ifconfig", "inotifyd", "insmod", "kill", "load_policy", "ln", "logname", "losetup", "lsmod", "lsusb", "md5sum", "mkdir", "mknod", "mkswap", "mktemp", "modinfo", "more", "mountpoint", "mv", "netstat", "nice", "nl", "nohup", "od", "paste", "patch", "pgrep", "pidof", "pkill", "pmap", "printenv", "printf", "pwd", "readlink", "realpath", "restorecon", "rm", "rmdir", "rmmod", "route", "runcon", "sed", "seq", "setenforce", "setprop", "setsid", "sha1sum", "sleep", "sort", "split", "stat", "strings", "swapoff", "swapon", "sync", "sysctl", "tac", "tail", "tar", "taskset", "tee", "time", "timeout", "touch", "tr", "true", "truncate", "umount", "uname", "uniq", "unix2dos", "usleep", "vmstat", "wc", "which", "whoami", "xargs", "yes" ];
for (String item : toolboxLinks) {
RunFunc("unlink " + item, sysBinDir);
}
for (String item : toyboxLinks) {
RunFunc("unlink " + item, sysBinDir);
}
for (String item : toolboxLinks) {
Run("/bin/ln -s toolbox " + item, sysBinDir);
}
for (String item : toyboxLinks) {
Run("/bin/ln -s toybox " + item, sysBinDir);
}
}
task debug(dependsOn: ['addSystemBin', 'addSystemLib']) {
description "add debug tools into recovery rootfs from ANDROID_PRODUCT_OUT"
doLast {
updateLinks(workdir);
}
}
task addSystemBin(type: Copy) {
from System.getProperty("ANDROID_PRODUCT_OUT") + '/system/bin'
into workdir + "/root/system/bin"
include { details ->
inTargetList(details.file.name, bins)
}
}
task addSystemLib(type: Copy) {
from System.getProperty("ANDROID_PRODUCT_OUT") + '/system/lib'
into workdir + "/root/system/lib"
include { details ->
inTargetList(details.file.name, libs)
}
}
boolean inTargetList(String file, String[] inArray) {
for (String item : inArray) {
if (item.equals(file)) {
return true;
}
}
return false;
}
// ----------------------------------------------------------------------------
// post configs
// ----------------------------------------------------------------------------
if (null == activeImg) {
pack.enabled = false
unpack.enabled = false
unpack_cpio.enabled = false
unpack_bootimg.enabled = false
unpack_ramdisk_gz.enabled = false
}