apply plugin: 'c' apply plugin: 'java' import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.util.zip.GZIPInputStream; import java.util.zip.GZIPOutputStream; import java.util.regex.Matcher; import java.util.regex.Pattern; def workdir='build/unzip_boot' def defaultRootDir = workdir + "/root" model { buildTypes { release } components { abootimg(NativeExecutableSpec) { binaries.all { cppCompiler.define 'HAS_BLKID' linker.args "-lblkid" } } } components { mkbootfs(NativeExecutableSpec) { binaries.all { } } } components { libmincrypt(NativeLibrarySpec) { binaries.all { } } mkbootimg(NativeExecutableSpec) { binaries.all { cCompiler.args '-std=c11' lib library: "libmincrypt", linkage: 'static' } } } } task unpack_bootimg(type: Exec, dependsOn: 'abootimgExecutable') { doFirst { def rootdir = new File(workdir) if (rootdir.exists()) { rootdir.deleteDir() } rootdir.mkdirs() } workingDir '.' executable 'build/exe/abootimg/abootimg' args = ['-x', 'boot.img', workdir+'/bootimg.cfg', workdir+'/kernel', workdir+'/ramdisk.img.gz'] } 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) { delete workdir + "/ramdisk.img.gz" delete workdir + "/ramdisk.img" } task pack_ramdisk_and_gz { Task task -> def rootDir = defaultRootDir if (null != System.getenv("ANDROID_PRODUCT_OUT")) { rootDir = System.getenv("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') task pack_clear(type: Exec, dependsOn: [pack_ramdisk_and_gz, 'mkbootimgExecutable']) { def theCmdLine = getRamdiskConfig(workdir, 'cmdline') def theBaseAddr = getBaseAddress(workdir) workingDir '.' executable 'build/exe/mkbootimg/mkbootimg' args = [ '--kernel', workdir + "/kernel", '--ramdisk', workdir + "/ramdisk.img.gz", '--cmdline', theCmdLine, '--base', theBaseAddr, '--output', 'boot.img.clear'] } if (!new File(workdir + "/bootimg.cfg").exists()) { pack_clear.enabled = false; } 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; } } String getBaseAddress(String inWorkdir) { Long ret; try { ret = Long.parseLong(getRamdiskConfig(inWorkdir, "kerneladdr").substring(2), 16) - 0x8000L; } catch (NumberFormatException e) { throw new RuntimeException("NumberFormatException: invalid kerneladdr value") } return Long.toHexString(ret); } String getRamdiskConfig(String inWorkdir, String inKey) { String ret; if (!new File(inWorkdir+ "/bootimg.cfg").exists()) { return "0x0"; } try { BufferedReader br = new BufferedReader(new FileReader(inWorkdir + "/bootimg.cfg")); String item; while (true) { item = br.readLine(); if (null == item) { break; } Pattern r = Pattern.compile("(?<=" + inKey + " = ).*"); Matcher m = r.matcher(item); if (m.find()) { ret = m.group(0) } } } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("Fatal Error"); } return ret; } task pack(type: JavaExec, dependsOn: [pack_clear, 'boot_signer:jar']) { main = 'com.android.verity.BootSignature' classpath = files("boot_signer/build/libs/boot_signer.jar") maxHeapSize '512m' args '/boot','boot.img.clear', 'security/verity.pk8', 'security/verity.x509.pem', 'boot.img.signed' } task _setup(type: Copy) { from 'src/test/resources/boot.img' into '.' } void Run(List inCmd) { println("CMD: " + inCmd) ProcessBuilder pb = new ProcessBuilder(inCmd) .directory(new File(".")) .redirectErrorStream(true); Process p = pb.start() p.inputStream.eachLine {println it} p.waitFor(); assert 0 == p.exitValue() } void Run(String inCmd) { Run(Arrays.asList(inCmd.split())) } void updateBootImage() { Run("adb root") Run("adb push boot.img.signed /cache/") List cmd2 = ["adb", "shell", "dd if=/cache/boot.img.signed of=/dev/block/by-name/boot"]; Run(cmd2) cmd2 = ["adb", "shell", "rm -f /cache/boot.img.signed"]; Run(cmd2) } task flash << { updateBootImage() }