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; def workdir='build/unzip_boot' 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 -> doLast { ByteArrayOutputStream mkbootfs_out = new ByteArrayOutputStream() task.project.exec { commandLine = [ 'build/exe/mkbootfs/mkbootfs', workdir + "/root" ] 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 { Properties prop = new Properties(); InputStream fis = new FileInputStream(inWorkdir+ "/bootimg.cfg") prop.load(fis); ret = prop.getProperty(inKey); if (fis != null) { fis.close(); } } catch (IOException e) { throw new RuntimeException("IOException"); } 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 '.' }