From 38dd70a5fd51b5cc0c41a5da2c921ce05a36d6ce Mon Sep 17 00:00:00 2001 From: cfig Date: Tue, 21 May 2024 23:21:00 +0800 Subject: [PATCH] vendor boot update for abe --- README.md | 5 -- .../src/main/kotlin/bootimg/v3/VendorBoot.kt | 63 +++++++++--------- .../src/main/kotlin/packable/BootImgParser.kt | 6 +- .../src/main/kotlin/packable/VBMetaParser.kt | 4 +- .../main/kotlin/packable/VendorBootParser.kt | 19 +++++- lazybox/tools/lazybox | Bin 70828 -> 72752 bytes tools/factory_image_parser.py | 10 +-- 7 files changed, 59 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index 2a2bf8a..679c0d6 100644 --- a/README.md +++ b/README.md @@ -362,8 +362,3 @@ https://developers.google.cn/android/images
-This project is developed with products by Jetbrains. - - - drawing - diff --git a/bbootimg/src/main/kotlin/bootimg/v3/VendorBoot.kt b/bbootimg/src/main/kotlin/bootimg/v3/VendorBoot.kt index f015740..12de14e 100644 --- a/bbootimg/src/main/kotlin/bootimg/v3/VendorBoot.kt +++ b/bbootimg/src/main/kotlin/bootimg/v3/VendorBoot.kt @@ -67,7 +67,8 @@ data class VendorBoot( ) data class MiscInfo( - var output: String = "", + var input: String = "", + var role: String = "", var json: String = "", var headerVersion: Int = 0, var product: String = "", @@ -182,7 +183,8 @@ data class VendorBoot( val ret = VendorBoot() FileInputStream(fileName).use { fis -> val header = VendorBootHeader(fis) - ret.info.output = File(fileName).name + ret.info.input = File(fileName).canonicalPath + ret.info.role = File(fileName).name ret.info.json = File(fileName).name.removeSuffix(".img") + ".json" ret.info.headerSize = header.headerSize ret.info.product = header.product @@ -192,14 +194,14 @@ data class VendorBoot( ret.info.pageSize = header.pageSize ret.info.headerVersion = header.headerVersion //ramdisk - ret.ramdisk.file = workDir + "ramdisk.img" + ret.ramdisk.file = Helper.joinPath(workDir!!, "ramdisk.img") ret.ramdisk.size = header.vndRamdiskTotalSize ret.ramdisk.loadAddr = header.ramdiskLoadAddr ret.ramdisk.position = Helper.round_to_multiple( VendorBootHeader.VENDOR_BOOT_IMAGE_HEADER_V3_SIZE, header.pageSize ).toLong() //dtb - ret.dtb.file = workDir + "dtb" + ret.dtb.file = Helper.joinPath(workDir, "dtb") ret.dtb.size = header.dtbSize ret.dtb.loadAddr = header.dtbLoadAddr ret.dtb.position = ret.ramdisk.position + Helper.round_to_multiple(ret.ramdisk.size, header.pageSize) @@ -209,10 +211,10 @@ data class VendorBoot( ret.ramdisk_table.eachEntrySize = header.vrtEntrySize ret.ramdisk_table.position = ret.dtb.position + Helper.round_to_multiple(ret.dtb.size, header.pageSize) - FileInputStream(ret.info.output).use { + FileInputStream(ret.info.input).use { it.skip(ret.ramdisk_table.position) for (item in 0 until header.vrtEntryNum) { - ret.ramdisk_table.ramdidks.add(VrtEntry(it, workDir + "ramdisk.${item + 1}")) + ret.ramdisk_table.ramdidks.add(VrtEntry(it, Helper.joinPath(workDir, "ramdisk.${item + 1}"))) } } ret.ramdisk_table.ramdidks.forEach { @@ -221,7 +223,7 @@ data class VendorBoot( } //bootconfig if (header.bootconfigSize > 0) { - ret.bootconfig.file = workDir + "bootconfig" + ret.bootconfig.file = Helper.joinPath(workDir, "bootconfig") ret.bootconfig.size = header.bootconfigSize ret.bootconfig.position = ret.ramdisk_table.position + Helper.round_to_multiple(ret.ramdisk_table.size, header.pageSize) @@ -235,7 +237,7 @@ data class VendorBoot( fun pack(): VendorBoot { when (this.info.headerVersion) { 3 -> { - if (File(workDir + this.ramdisk.file).exists() && !File(workDir + "root").exists()) { + if (File(workDir, this.ramdisk.file).exists() && !File(workDir, "root").exists()) { //do nothing if we have ramdisk.img.gz but no /root log.warn("Use prebuilt ramdisk file: ${this.ramdisk.file}") } else { @@ -251,8 +253,8 @@ data class VendorBoot( else -> { this.ramdisk_table.ramdidks.forEachIndexed { index, it -> File(it.file).deleleIfExists() - log.info(workDir + "root.${index + 1} -> " + it.file) - C.packRootfs(workDir + "root.${index + 1}", it.file, this.ramdisk.xzFlags) + log.info(Helper.joinPath(workDir!!, "/root.${index + 1}") + " -> " + it.file) + C.packRootfs(Helper.joinPath(workDir, "root.${index + 1}"), it.file, this.ramdisk.xzFlags) } this.ramdisk.size = this.ramdisk_table.ramdidks.sumOf { File(it.file).length() }.toInt() } @@ -263,7 +265,7 @@ data class VendorBoot( } this.dtb.size = File(this.dtb.file).length().toInt() //header - FileOutputStream(this.info.output + ".clear", false).use { fos -> + FileOutputStream(this.info.role + ".clear", false).use { fos -> val encodedHeader = this.toHeader().encode() fos.write(encodedHeader) fos.write(ByteArray(Helper.round_to_multiple(encodedHeader.size, this.info.pageSize) - encodedHeader.size)) @@ -301,34 +303,34 @@ data class VendorBoot( } } //write - FileOutputStream("${this.info.output}.clear", true).use { fos -> + FileOutputStream("${this.info.role}.clear", true).use { fos -> fos.write(bf.array(), 0, bf.position()) } //google way - this.toCommandLine().addArgument(this.info.output + ".google").let { + this.toCommandLine().addArgument(this.info.role + ".google").let { log.info(it.toString()) DefaultExecutor().execute(it) } - Helper.assertFileEquals(this.info.output + ".clear", this.info.output + ".google") + Helper.assertFileEquals(this.info.role + ".clear", this.info.role + ".google") return this } fun sign(): VendorBoot { val avbtool = String.format(Helper.prop("avbtool")!!, "v1.2") - File(Avb.getJsonFileName(info.output)).let { + File(Avb.getJsonFileName(info.role)).let { if (it.exists()) { - Signer.signAVB(info.output, this.info.imageSize, avbtool) + Signer.signAVB(info.role, this.info.imageSize, avbtool) } else { - log.warn("skip signing of ${info.output}") + log.warn("skip signing of ${info.role}") } } return this } fun updateVbmeta(): VendorBoot { - Avb.updateVbmeta(info.output) + Avb.updateVbmeta(info.role) return this } @@ -354,11 +356,11 @@ data class VendorBoot( fun extractImages(): VendorBoot { //header - ObjectMapper().writerWithDefaultPrettyPrinter().writeValue(File(workDir + this.info.json), this) + ObjectMapper().writerWithDefaultPrettyPrinter().writeValue(File(workDir, this.info.json), this) //ramdisk //@formatter:off val fmt = C.dumpRamdisk( - Helper.Slice(info.output, ramdisk.position.toInt(), ramdisk.size, ramdisk.file), File(workDir, "root").path, + Helper.Slice(info.input, ramdisk.position.toInt(), ramdisk.size, ramdisk.file), File(workDir, "root").path, this.ramdisk_table.ramdidks.isEmpty()) //@formatter:on this.ramdisk.file = this.ramdisk.file + ".$fmt" @@ -368,7 +370,7 @@ data class VendorBoot( } //dtb run { - C.dumpDtb(Helper.Slice(info.output, dtb.position.toInt(), dtb.size, dtb.file), false) + C.dumpDtb(Helper.Slice(info.input, dtb.position.toInt(), dtb.size, dtb.file), false) if (dtb.size > 0) { dtb.dtbList = DTC.parseMultiple(dtb.file) DTC.extractMultiple(dtb.file, dtb.dtbList) @@ -378,23 +380,23 @@ data class VendorBoot( this.ramdisk_table.ramdidks.forEachIndexed { index, it -> log.info("dumping vendor ramdisk ${index + 1}/${this.ramdisk_table.ramdidks.size} ...") val s = Helper.Slice(ramdisk.file, it.offset, it.size, it.file) - C.dumpRamdisk(s, workDir + "root.${index + 1}") + C.dumpRamdisk(s, File(workDir, "root.${index + 1}").toString()) it.file = it.file + ".$fmt" } //bootconfig if (bootconfig.size > 0) { - Helper.Slice(info.output, bootconfig.position.toInt(), bootconfig.size, bootconfig.file).let { s -> + Helper.Slice(info.input, bootconfig.position.toInt(), bootconfig.size, bootconfig.file).let { s -> Helper.extractFile(s.srcFile, s.dumpFile, s.offset.toLong(), s.length) } } //dump info again - ObjectMapper().writerWithDefaultPrettyPrinter().writeValue(File(workDir + this.info.json), this) + ObjectMapper().writerWithDefaultPrettyPrinter().writeValue(File(File(workDir, this.info.json).toString()), this) return this } fun extractVBMeta(): VendorBoot { try { - AVBInfo.parseFrom(Dumpling(info.output)).dumpDefault(info.output) + AVBInfo.parseFrom(Dumpling(info.input)).dumpDefault(info.role) } catch (e: Exception) { log.error("extraceVBMeta(): $e") } @@ -414,8 +416,9 @@ data class VendorBoot( } val tab = AsciiTable().let { it.addRule() - it.addRow("image info", workDir + info.output.removeSuffix(".img") + ".json") - prints.add(Pair("image info", workDir + info.output.removeSuffix(".img") + ".json")) + val imageInfoJsonFile = Helper.joinPath(workDir!!, info.role.removeSuffix(".img"), ".json") + it.addRow("image info", imageInfoJsonFile) + prints.add(Pair("image info", imageInfoJsonFile)) it.addRule() it.addRow("ramdisk", this.ramdisk.file) prints.add(Pair("ramdisk", this.ramdisk.file)) @@ -452,7 +455,7 @@ data class VendorBoot( prints.add(Pair("bootconfig", this.bootconfig.file)) } it.addRule() - Avb.getJsonFileName(info.output).let { jsonFile -> + Avb.getJsonFileName(info.role).let { jsonFile -> if (File(jsonFile).exists()) { it.addRow("AVB info", jsonFile) prints.add(Pair("AVB info", jsonFile)) @@ -483,14 +486,14 @@ data class VendorBoot( log.info("\n" + Common.table2String(prints)) } else { //@formatter:off - log.info("\n\t\t\tUnpack Summary of ${info.output}\n{}\n{}{}", tableHeader.render(), tab.render(), tabVBMeta) + log.info("\n\t\t\tUnpack Summary of ${info.role}\n{}\n{}{}", tableHeader.render(), tab.render(), tabVBMeta) //@formatter:on } return this } fun printPackSummary(): VendorBoot { - Common.printPackSummary(info.output) + Common.printPackSummary(info.role) return this } diff --git a/bbootimg/src/main/kotlin/packable/BootImgParser.kt b/bbootimg/src/main/kotlin/packable/BootImgParser.kt index 455db3a..bedda87 100644 --- a/bbootimg/src/main/kotlin/packable/BootImgParser.kt +++ b/bbootimg/src/main/kotlin/packable/BootImgParser.kt @@ -143,7 +143,7 @@ class BootImgParser : IPackable { packInternal(fileName, outDir, fileName) } - override fun flash(fileName: String, deviceName: String) { + fun flash(fileName: String) { val stem = fileName.substring(0, fileName.indexOf(".")) super.flash("$fileName.signed", stem) @@ -175,8 +175,8 @@ class BootImgParser : IPackable { super.`@verify`(fileName) } - override fun pull(fileName: String, deviceName: String) { - super.pull(fileName, deviceName) + fun pull(fileName: String) { + super.pull(fileName, File(fileName).nameWithoutExtension) try { super.pull("vbmeta.img", "vbmeta") } catch (e: Exception) { diff --git a/bbootimg/src/main/kotlin/packable/VBMetaParser.kt b/bbootimg/src/main/kotlin/packable/VBMetaParser.kt index 761cbf8..0f8059c 100644 --- a/bbootimg/src/main/kotlin/packable/VBMetaParser.kt +++ b/bbootimg/src/main/kotlin/packable/VBMetaParser.kt @@ -60,8 +60,8 @@ class VBMetaParser : IPackable { super.`@verify`(fileName) } - override fun pull(fileName: String, deviceName: String) { - super.pull(fileName, deviceName) + fun pull(fileName: String) { + super.pull(fileName, File(fileName).nameWithoutExtension) } fun clear(fileName: String) { diff --git a/bbootimg/src/main/kotlin/packable/VendorBootParser.kt b/bbootimg/src/main/kotlin/packable/VendorBootParser.kt index 2aeb85b..6b70601 100644 --- a/bbootimg/src/main/kotlin/packable/VendorBootParser.kt +++ b/bbootimg/src/main/kotlin/packable/VendorBootParser.kt @@ -15,6 +15,7 @@ package cfig.packable import cfig.bootimg.v3.VendorBoot +import cfig.helper.Helper import com.fasterxml.jackson.databind.ObjectMapper import org.slf4j.LoggerFactory import java.io.File @@ -38,6 +39,18 @@ class VendorBootParser : IPackable { log.debug(vb.toString()) } + fun unpackInternal(targetFile: String, fileName: String, unpackDir: String) { + log.info("unpackInternal(fileName: $fileName, unpackDir: $unpackDir)") + Helper.setProp("workDir", unpackDir) + clear() + val vb = VendorBoot + .parse(fileName) + .extractImages() + .extractVBMeta() + .printUnpackSummary() + log.debug(vb.toString()) + } + override fun pack(fileName: String) { val cfgFile = "$outDir/${fileName.removeSuffix(".img")}.json" log.info("Loading config from $cfgFile") @@ -52,8 +65,8 @@ class VendorBootParser : IPackable { super.`@verify`(fileName) } - override fun pull(fileName: String, deviceName: String) { - super.pull(fileName, deviceName) + fun pull(fileName: String) { + super.pull(fileName, File(fileName).nameWithoutExtension) super.pull("vbmeta.img", "vbmeta") } @@ -65,7 +78,7 @@ class VendorBootParser : IPackable { VBMetaParser().clear("vbmeta.img") } - override fun flash(fileName: String, deviceName: String) { + fun flash(fileName: String) { val stem = fileName.substring(0, fileName.indexOf(".")) super.flash("$fileName.signed", stem) diff --git a/lazybox/tools/lazybox b/lazybox/tools/lazybox index 8c2ac9a017308e85d14a562649bb6b6332d23152..bd8b9946b792b4b4a3275a48f0ce901e42d9a9a1 100755 GIT binary patch delta 27511 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 delta 25399 zcmb__cUV(N)c3t12_c{~X#x^DhzNG<*dky76%;#mY%6wMOJZ-RtfPV*6%`aIg1vy9 zwJp|F*MdETa&>V*)a3ik1r+mse|+Ebyw_)P<~R3DJ2P|UOyQb!N|>G|Ot6<)c4V2B z48wR>{NXlQVbPIcs1qWDVOadD#unhBF8Kn(J5inY`Cl0(|Eqv^PIy6`xX$|`q*8f`0K>)N#FAiWtG7R;JEM933w+%iKwFqP@ewpW{s_r0H1kq0}{sewT$#+ zm|B;Qbn;0W+tcE1c=`2rRSk-5IiFYS$LCpX62vG*AfejF3Z7ZD0F>ed26%}9E;hjb z8ek6;xb~sxHTe}QnDM^`FvSK~M#WI`&;%k4@N5IT(g0tpgDnyNaUE>MC>TcdO8~{@L2S?)jYI7OX^?+4LDgRfZ{R(+*48$8-%_;QU}uv&KlsGbugcv0UluTBRvJ5;QpTh zJU(oIvkmYG1ANv1=NsU11Ke0zTL8$P7txP^>Kb-6z##^BVIAy-w00QaQ*|(vzy$+* zy%y8Ww$R`3AUYgIezDCTwGXiOsL? zuN&a6z_t1F1!!aYYlN8w__P83&j1J5{ThF&0X}Si-`f4mpD%!${jUl5)WLL=bghG_ zFhUJ*Q)p7*Hv!{;cdm>LlY*%-Ae7~2OE<=x`5nD}_8%-i;wUb&Lj6}`diAM^u-lqp zvVenY@LS+{z_csS1oNO;zlX4l6EIC+1TyeP27(&=A8-p`s_^Lh|Ij3kSu8WK1{b3M z!;i2`940yXK2m`UBI*>NJ0e`oU>UO-hIr72a+bMOlYkf*I3NSs)HDGzh#@MQW!ly7 zAHs{0OqOX{^S%e#csdI3wgywHg8rlC4J|gYGPNb~(w5|c^q6G?#3=(Ktu1{yiYzg; z_8(Fs7|{X23TOZXuk4d@=olWSAW#lj}9h z$*6bAnCvjKCNs>fawgd1n2+faF`&6EW6Ny*YP$3qD_mN@S}eT*dW&ta^bTktYqs4csUdDuwQ# zSy?qSRcT*?Jt$3Ol_5M%RSv5OpGWCYD}{2b7t5F~H&r@$(}XOP3w>Fp90N$wlrjjE zl>wkxsY+QOXu64VZ1d{yx0E8hlE-4DQ%f2yR3^7#nS8`=(i%9!NEy_on$IGL(k!J1 zrI}{RxV984(v?@>*@*~O1|q<8xl%HSzBsIm1WiDA`3PD-R_QYm;V2MCDQccO7Bt;d z*&UWzR=St*YO=p$mlxBJRMJf1mSJNhA zl?9-*#-)@Zy$)+YGa04*S{k0A3|q%C3L21#(Ug^GrF7Z?deldGC6Qu#<>qaax+x#; zptON<;cif5sN-pdQkqP|g~}NzlrqYO2SAT7%2R38SaTFKD_t3nfk@M@JPwKirktQu zs*FFwDo`_H<*;)!puRHU0%c^B=@%)rP>#J)jfGc1QIm6&rkW_7u2X8NG%Kj?v~jnq z=~#4TTa5TvN}+qEPzp0Nj#7-nS(IXM&Z86>W1(IF53D*R4S;f5PAQC{)s({Yh^G`L zLIR~`46~V1%=k%^VkX~7sX5j^lw$CwP>T60l~SmnbV{l2q!cPAmr}I-DN3RB&nc(} ziXxv<2XsP8p+yTQb!M1bls00RLP}j2<^iQLSnHI!GR!kdF$EM+3ibY$Qcu`TlzK5t zF{R#ED^Ut}F-D9nw4;#H01Q7$1JO$ER~K-*#%QreDT0x50JU|k8?fnkCu?TC4<1NC%bFtvbo zW|;1j1~W_urCk`NH>F)M8&KK}>l{kEGfXt4Js4&frE-Rep|mH%jHNULeSp$X^Z`o4 z&<7~(MHh0Qy{RGw?Spx4A@%e{AD}cGeSp#k^Z`oyp$|~nAANw*0q6siMxqZ;8ihVU z=|J=WN(Z42P#TRsK0GBRkTRn*K;6UMcpDabm^88v10xK255gZi<8sWWr> zwreHyDNe<>+zPiE?jFXbznTl*pJkk2m7ZS~!ORMo*B#=Hbt6YQIV#>(%H)h|ILDZn za!rfbK!&@Zl%$4p0#maLt4uafoG=FbBK}vHV3B%TZL!Uib1OFGe2R^?1+U}o%-A-vm3}j<8Nh@UYKbZ?mxeS$39w=Xn!g5;SHmMuK ziNA^DLGlg=$(kS z(4umkURL`0_Bcx%o538R-QAG zWC$|NwLaNCa#zS{ zyKCCrt%m2d=5igLAwSZ|1W#fOPoY9{mS+<335EP% z3jHROuc%?VpvkF|P-|^;c2=0MrqDjx>cVxY63V9*3H*cpk;O8uesU&3C_5BJD`2aQ ztQ4BF9cx4P^Py&_>|TgoL2GQQWqdl9ug}~a8YrKSDD{C83wPEaG0?ukZ8eAiI$D@m zgDN$Q&xJx-7{=3-TdT=GTkBtrH+}BbqJ==Cf1o))bE}a8(S8FA=HivL%;R~ST#Y?U zxe+|hRn|{h{iCx8@?>)JEDqgewZ@bis1eG=v2=J$aTB`VRx=Tjqtilt_{v1^@27@Z z^Id#Wl@BUBUgH&W_=73ePNS%eIQ2)wF*OleB4Rtus8Dx4VqZRD7$R;##6~|d{Ow1) zK{fI05wDRZDzqsduQ?yDDdH&+Pw*q&wCZ>Yl(bh(#BXZK5E>fDN3`W5S|Q?OM0~HV zE$H+g8FsFTSA=-))g40}_;^)cXbt~Ud&LYwyc<8_&G-?oMNPabh^M%rZWijrM|{CY ze2R$O5HUk7k{k0Pm1NAUjv5>&_eKMla;b=zq4o@Q;^STVLi^AKbwEtO2PSVUM(i-S zhOoQ(f;I(>|Dw}}V(8z78W;>U@B}0K4*b_Nxo1#I{iny?|+`yhRPbWRx>_f zcWhoT`~jJnHuxD<8g%#G(cL4~Ts(9cG}r(tG;qKFfUfY z^l+8B1x5*=&EnK7cdAk--&HB$HMDgktJGiaLcm5oAKUbdB$6Jo^(HRblL(VLkSJptX9W zYIK%m-oMl7-@Mo9L*TZ5)ah4~y}e!Ce^)U+p?6tX`=aWZY6kF#U&I+k-u3ow)#-o8 zPRd;>t1G))mA)ePYhB5;BwhMAD8{3BEq@f>|3~pXYl`2LfA1D*#TP%6FMf9wN-uka zirX8=H?UT|aywqU7Km+IBVH-@xU5#Zo|P8W;w4Y|n6|os@M^)@@`APE1v{0Oj+2VX zJ9wI99=%2Xgj|w9HDx-z1##%>$+je&`?hj+Q#Hgy!^TEKv>qxp_Qph+YeG-4oX6yk zzTU?6Dk^CwlGoRvUTPVW*W?t-6rW_7&E#F*X?6|En#*b5W8);SFBtT`wsI-An@kS( zVkG`d5 z>C8uaks!fUF5DvJ#AU*dW~^DDlw-B{6_5|cfig(m1vSekr81I2MnZIKiUTpdO1T@LQm&A!>DSDAajA^wUHXGp zESKT!(o!D`5J(49%B7H3{j81mm0Ca&*T~m?-s~~r-rv`GF-p{cAEU-7-@%ffmYI}G zCKLO+x3aBCzo9|;4QtYG&8Oe)mzvEY7yCP#k1aXS)mL7ASCC}1S;~zdCH);l2_@8L zI>0eJn)*s4p?2u6`ihy~X(@jz@rwES{ub7!`#7CmiC&ZfZPoCVPTv?|(l@Y(K&x_~ zCZV|^(Yu_$HyU(2nLWVY@@a`ERdCoBJw(u5h&-Q?oB^J#3QMx8lw5ZcT2qE&u_$uN zqqThoJG53mNx27gtWqg=ht!L-vlNstd5_TU?NN#iMLNBlw2Jg}*iby&M{s`)TB^K= zk-<`B>L)}{iIbU;-ZpcJX%DRzk?drK{@D-quav7InUN0l;)MC@Sz1OWPK%2&NtJTnP!@Z>RU{~<2apGkOo1AasZpKTQgSrPot;GP zMme%CNJ*4ky&J_5wBB=tiBc|?SPt|P9W0h|S4fwE)?wR=8JWd43-oBKSgY8zus$t$ z>k~523XtDxtr>n_XvO$_29werbzX-$FMO@je**0W>hwaV|CUL1541(L#|Qeck>u6D zP_`-Y8|18zX~mghelR}OG9S%^#uxy!6F$(2F))lj+OxEIZvlCj8h`X)qk*nz>ENgx z8ufvG4h;#=&nh!OKgCg{am;MS4~G;Km@0r|g_f1;D_ZI5vc1>rs+__n?+mFGX&f_L zp}VBqT12AbVkIBP@s~Kaeu;BUkOT8VH%V z^5yKWZHwZ)|6aFvNxx*3pm|z}Ez8&l`Rbk)G7B#$2L%(oo(&}4gI!n|={eY&H6zmo z+bI}LTc|)OcTPiPOqI+j`0QE8nUQkG;P-&v1O9aQ1K|&Z{~-Jw;O_u`GW;R%hrqub zrHJ8$)DS{?t=?4`$s;?UXFwr5Y5?>A2(6{4(PVc3e>T@Opr6f^5A?ISPN^Ah$8_=0 zj}Ej$jMh*a93x-j3z2;KR+lpc@qP+&r`oJdWWbxdr#}kJd;QY{qfN?f(hP@jAeDR+ z3e!HaCQzNGQmi}K1h1mQ=`520^QbFKpW5}Pl$)eB#-K2YpwopQfm#f7IF_pV$&D*T zS^A1&D8Nq@FqXU;V#fxPFGE}!Mri23h*uZEq@qJ09WDee{2ggNv{Pt`dP23P#u_&i zNv5c4HMNLu{1kN%EF&qG4~kK!j*FFYR+^!qLOBc)UgNd=LgipVP7ihTo}sQzWsX5A zbJWznLcKwy+*a~+sIzxO4R53YZ)6Q`9M3z8bROp1tf|_EFJ1E=ykab5rCf8QLB~K} zP$}16?TxxHC}9R!Kg`olptc5PVFXG!p+QVxO-vad(~CSG=FlQZWsft1LhLpsK}TeO z+5-OpeaRihy##3O$FKz&;9cj(unF*f7V#ZEk_{qjhIznF;rT z_>J&YyjC%uJ~`ArGvU(9d~!^2j(6PoI5*(G+ACvdX&gx#%jc>br*8AQxRl zzTQV}!ksJgiV^ZTns6)2e9oG1Ys-vwiDQNGSSQQEAYPsk*+z$rWQ;q8A`DWW`f^hU z6qaid6>KhfHNru(6`71BdK7a6?{gjLsMw$~Mg|RQOf6l-1ih3u!E_a)`K(8jU4emc z;Dag^J^zVLANCL%29I?5<)C|>>GTPp*}%?t7x_S^pAFpYzD{2Xzd6D?Kh^1T55bs$ z!wyonWmyUGdeA8*oTRKxY#}*2(qV98-oB>gZG!UBE*z+eb!ru3TWHQ#Eg{=T)>Tfc z)&Qk7k~N2aHMr`lV6;Qmx081R@=~Fs2}X3PS;pjL9K_BQ@sF{C>Cq#m4J#*$VkY{B zpt0WHJqWEOLkXm1mPL-C!B~t^5noX=Q3qlqMGiF~$B6YPU$!;rILgj-QYn+iAjKPp z1WYd6BW!v> zY+%bm*3*RhR3elQEt1VU5Swo-$!i534MLb$6Rs)wKFZGIX$@*boJZT4+^9kINypK4 z_GfC4uGA~kNFIxlH%9z9rDV!zH#VMZ9PMj;s+3yIrU*V$DkusBy+Ce`c63ZGxq}`1 za1^!z1@}hNtwQtM*v~R62|LD}y+J(3^kSXJ^f8VmePM}o#hW6sWlSscImInQBjhqS znL8C!9CD!QG_9_y|sC}#4G?PHlg@1n~f&j)*P zZwR(=LS;G6`JnO}W5UfU-dw4w!7xm@DZmeE@H61Czy&q95O^4HY7Nc;js%`pgO$L& zfyYv;$SeBIgp&hC^RHzO1d}}3glh~`J;4-BGQlpR zY%#5z41T9#*#hd1nP|e<7R%;Qe==ImqF5%kIBygp3>AjW>ps7``R|a__Om;x^!lWI z0%ij_FfNL{K)#OiWOIq@ct@;II*xa2m8vbtW;~-SJuPJN=5lnvxrbs*xb7vc^O9r# zMCXWcqS|AaHYWRLRvXCr@y_gGa%6l!n}e{Ypj}`??Zl~!HS}G`KRSIhhTiU7ILF$< z54kSrT(Z?PbtXARg8tBwSWa+tZ>%+zr#dZHU1X^B-yGpt8b)?1N+!nuT0)1%3=%b= zv(uSkk*vXHrip!?Q09=ZtMV}~v>>$fHx0>}P-xy82IJ2_bi!C?wi7uT+sb(owuicK z=F6W~#wM^HtutBf`PtT~;pNMxLv0d$>^inSSvRp4t0I3-?9zT7?5^s@ZGyz})z8&U zCy(f1ch~Nft*ihY49X3{I0pqD%so-o_Tir7tY@!?dcORy34W4v(Cb_d#02^V=sr=NRMr(bjp ziwg|TsJmpu6fbrYSuurHENzN6JB8fEZ&1#cDJNO;CNN%3@eL7}B;jU}yx+R{x5FmD zn?goL>&JNARySn=6M|9a`s%JuuBd63>Y75E)3OCj^Jaa>plL0H67Ih;vSC_lTq5y~kfV{kn^otFM!L)7^|O zmC~&Dk$@R?#A=2un@W6Vv|u-o;rN|J{+Q8>9YQY82w=OCe`joDt;n*O8`*utdX^uG z)p?e)>EhDhY&s!JxKuJ>mM1%&te@q_E2f>ilzbtjIC6bf57vv+n;l@?>r0{gxQ1VF?i;m!}1d)QsDhUl!9(w zF|LCWjARmSAfIn9)F_(R&23>PE@6B^3Z1t}RtJ|W<0MM^q^4;SPDn=0^*3$6^KwTe zoITk#*I8tNGTM@}b6v1O@y}dWHiLY}?=9jo&&K@*_C;~dv$b*N7dIn!K?2Q_g>AbX z8#xm0l19Q6kU{hOu}WJpubW~X#stItxkSSKt}%vr!k2KXcSb4V(o>PSe5_fB^}A+v zjkGsb%|fWV+xLpKRZY`a?r%MgZ@8rz@0gTVNtKN3@h@X=QkWISpae%Zg*i=A8{?QK zyj@m3>FQN@s+^KJZ^@?}t<41pSIBJpKN^v=}tWeAcF6{ZDe0vzHlc0MLz;aUc~++{K}$Y4qtjnP>oDjK z99&0WFW?Nc+(z*1J+0HPMN1Z-?`#HtJ>dV)a;@<0Ho}chAs$+G7h3dx)>S15GvzDm zLChBrcPs1|S2slgtkj=PagMK$8H#E}t}bwKXs8w>v0kzmeZ}Ro)g81*m6Suf;r9hD zq8BO&_m;RW^fODTA{XO^8cDWUk{x+9*P3)%Br%o%nFjL${< zb}simY|Ql~ehL?nyv&&EO~Mt9*s7Qe>;>F}Y*g5|Tb0$7Wbmi>aGUVypL$ZKFT_BjwP!qyxiF;D1?lu9 z{>z+2a-@S6SmuDaY2q?hYGN#N73hjd#}@`eT}|wG)t%7ioS3L{(s?r27iBKo0Ew?0=_7?9`H8>-Gcrzo(x~^kNIldau;mV z9$D^6n`61JNi^)jxbw!Cq4mqxcv-+ws@?xE<|III%=1c%WRsotN2w**D9M=9X-UQk z8MeFrTH!}6#uaTa(Y09VYdxprw%UGt!>x3=bChp`?qu4^R&8cz>wQ$3D6#TJPb)SH zbOrT6((#Pd&gYf(Su|l!B>Wr9DFJ$WT=v?TO=g ztla7@}V7XY~mpTC2pV zGMo-#Ge1kb)(l~VWXYNZm>a*Zadn-gF->wx`%}%F{j*Y%Wz0>{m?hb#8FR6kdRQ$P zV{O`b?Gbcd?b^1O={?tZvRg^7b?r@0X}X8Xu+~9qkw4bCSbkGErOKfBZ>weF-L@KY z#pL2T*S2Rgf!WVXWTtLOwh6aO8km|D`GrciH%O)N7Gme=XXWpxsN`!UevLTB`??%c z&HP}$%X&{ZXJ*nPyJ3>UmSD%MkNVEG&wWs`ePm3$dqAN|%*`kkbLqwMB`l-C6|Z^d z13OSz8}yAY&^cMhm*PZRA~!>v(d2l%I~zfs#BXDzWaj!-Cc!wgh()YRIoa#y3fQb1 z-vk#ytE>`nk|`Rr`lw!z7a}+2w@by`>k=^+qK=k}x!q-AE(Pw4n#tQR51Z3u(Iy92 z6p5Q!SS~IT;pj`o*GHNprcJx43)Z{Nq!lcs0VJFiko_c}o2FQj6qGI9W|CmiFdH?i z_gu^s6=Re4N8Z9bGn(@fG1mY&e^T9<$ueh9!xaa0`ddeJ`YFU_b4R;P{06tIc{ z&Y}%0=2|6+xg;`ivtQ@_u&Wp@K`G`o7mF}i34rXD@B`ID%q_*+k%diT!^>MknPBZM zZ;*b6Z&@+79CBSt?r(N?NGNU^)3I7fAkGjz#d;{yFk-&NQ8W;IP-#Ujv@c7<`Adt#T4W1xM*|_4kTCm75M`cZ-e zSXIH?N+s)Q{v&K9AC``=y7|w*Q2g0mFzmPXY9-g2Q3ZL0_1IOjF111l+G*{Q!hf_6 zJzBS~X`$b=Vy*+}m*^~N312%hGqHt9kk&iq-Fq=zc_ccBBnYohZYR3CG|&dbu%6>S zIHzJUo}trU+@;eWPJwmi(2pEyzMck2PFz=qpR`$gV#26=P$P z@w9Yn6(vjmtESh)L-{3`;O>!IC|c#4mLzX;gEew_n>SRBc3XIhgKCpfu!gd?d-}z~6sc7gVvZUnwW;>R_aA|0TzS}T~qD9{(p*0dQ+wH-j z=}ydU62`|qPbwEQmfodS7OdvxOoEU6B^H9{U+PqTD-$=mB&a4VIEM3BD&_{lJQVR3 zHof;0Oni4)i~2%KMv^YO94+f(Ur&(KPyV%H2(C|on@rv1AQW>d6|ID1;PQq^BJ8h{ zh@B0v2QYGvgUdp!`kmR;T^khofl8okL#vnF~=S8ZG!VM%SbfSd+#v*nG1KMcfH8 zJlUo3rmZ^tfGs+G2MnKnaQSGoGT@fGb^3F_e{F&Zg5hMni5yIp!Q4ZJ#wV9j@eHGR zwhvSN-=zbYmQ`0JhA&2GsdJK329^2nnu2s7o%gypdti&NR)31PMnExqr>8mCk_CHR zSTWhLH^92IB!t7+2lQb3C8FI_Q;Ny+z0KH##C)IMm=h&9Ly@e4Zn;zXQVn&t|$qkjT+i80Q)U<}^f2+I;-4rs#S9V9HJvE}yS29@?^ z)Fg?lv@oN^UyWZOYUMLVq}k23In|7m-?KcyW9 z`SgZ->O)rJr?QO4XaN%zgQIlN_oD{ir5}TZ$bKod#4OweIEx>yXG#!r8F-R*d z9ygJcom77Wfhox7G3j{7H9Va!4n2($aT(g$Q#N{zMKL|c5^*;` zMO>klt#d_^PR)X>xbq^eJ9cC1qhJEK8|3JrF7;A0^Rjb87*{IJ-Q?>b7q)4RW9l20 zg+5E`Xnq1yNUb%1Oh~W8j-nzp^-VtPEK22l>kqs8=i(mM0klyPHs_N^;4b`Tojw+| zh(v9SS7RRm^zXG$2nZLD=ZBrymE`MT2T!Tmn3wQk?fVa7hYOhgaK8^_nLtomI7)ky zwnx0_a^Oe{wu)>y;_v(kHnIgj#>E)p#VY^odLi{g>E5;o%d3}1935@dpN3&xK}sE< zo)X|63)cnmokeWY2eeJ#FCQ6W>J|T(dPSTSra)87;o|gm{M0Mr%rpXi>aD&FCgK*7 zz3C2Eww+CPckQh%%w}K_N%)cosXjxw?0F;siX{4Uy9ujRtjC)V^sGq4&ER)sS7+)g zjP+(AW})?d^hF_8UMA&vVl{Ii$45A32fr$42+P=`e7*C;`O@kJQ36is0U@4IgNBv>r+hll)u0^vvhM!0bz9b^bY~|ZfOV7oYWC`V?Wg>2#TKQGTj&)<)sjd{_g0WEU zEn9;QH;IhNqz5#anbX-T#5K#)E~_-Rs|;6O3Mz#$A##>K`NF6q!?WlC!2Ro9J`NQ6Nmh3?xyxYNp?ZdIAs2GkQ_b?k<^a`r@3A&m!8|$UYdyMz@xZwrY-?c*Zcc9&a+iorP75}R zgyw9)w(`pySIcshkZX$7PYTldM~MqE#4@*yZx$4!kTWZzJ)D+722{Vy2ftQjbmje9 zf82S5>q@5QwrQs1xu2Dq)Zu=C3q?ZiHLe| zU1Z0pWjI@MIqiq7++L^Gu+7QC(-Un{V39IKjJK(_7lX?P+I&WcJ3#}^tg#%gwyT+U z24UV2(tA^9+FIW^WrW*OM%-I$UkI@X5n`LX?b-X-kEnNUIJP+^pF56RT+a`Jtu+69 z8ok|hVG%a!_g)x)S?BYG(`+%x%= z2!-^#Jl8>v4AZefuHOsiB3-e*?hY*ux0)Qk+($xB2wV%@9*~GD_QdT*H%jm7TQD~o7ZuD&sO5B<9d(d(0O*P6RrccCu?uaVY?Id<{E)cL*j3q zz=lk>TP@6!>S!V(I$_^BV7^!-;NEKU+p|n?Tby~5QOn(p1D+(u8euGrx!n;){NCFx z>|=8A_5_=(GBIrwFOjwf8bz$dpQ2#x-to>LEMT_W@waC31YCkvfIHwaxe+%-ZG;24 zhj(VPjdFVZ^})!x;GBSqRtvZnsyMlTYgs11BCyB(erzR4yzhy&IDg;MIu1Mxcvh-> z!1JtBfPVA&egJ!kcs}TiYK(i(jh-$&=z)P9$5gP$VE{?ma8lyA+I7J)NQZ4t(TXvop4Dq*W90s; zaO+J_2ZN!Cv8-u9|DuD1nr!uYkma2c7WaplynIiV$&J$KUyxm|TbMiHCS@R>QGJ>% zdHK4TUvG3@Gd@g&upD^OxFt!iWyr>(0XST0se3RR6A`)fV;YZ5GXqL@z5 zKbs62Pahmy=4tt37gurSAU84H>ahrt*N1Tr$!S?Gj6{8K_l(fGe_+sav0`B|2kP{a z2yEJe_KSuQ6ONmh{dD@)WY>ol>}GQJ!$k9g*b4et_5>2Dau zIT?w?a$lW(Ea+gA^hzI{-VG(~M7F5iv4lOX_OyJ4bM;-7LcXUMp{G0}uQUVNANx-4 zr`H-(EO%IKoMiIL#*T!abXo3&nxQ-6dB>bsravUXkVP7Is#`SymSYXl#uYNn7~ked zOY(nBYb??dm)vl~HXce_pG?(G?eRz@!h*&)hISh<7BuuvjcB)tRx#eJTV|B_X!Xq} zmg}#3=Z};md>>7UuIh~9tL7OFzBt;W!)T3 zTwpl4mf>z`q9Fk{HFk@*@ntMF9;cN}g!Xw-w%2lNY27ZzU}Uf3npqnm=4K7UHPpxu z^EcFC7Ws>dqFdY_2MfNH66ME6P?>u^wrAgye?EG%_lVJ_Hki8FfAXZq?w_1deZ?nF z=NZ_a#ARQ;>7GE9F{WnNp`p#kaG%Jg?{|@hc z2Ue*m#CKKA7^la0XVXjJ?NEvcOdU@uB^J%)XFf9KMNvL-NglSh@TX$(QeGo%WVl#N zMzmW#sCjalmJ3+R`U3p@k}Ua^09W{g7Rj%MkS?F?%%hDMtu#D7?!ul^UvKZ?-}ql;`yAw_c!=9gD;Xq{nyhf$AAwDsEq$? z>wO2)DY))nd`#|wakBwqQ8nWWFl~dY>%0Fp)y9O7>_|2i>x>J z+iXqnr^h7ko1J&^u>4Pq*|+X7J%c~Z`r*f)<}$(}|98y$jjt^<8(yc7@8291@n6op zqf%q8A@oN4Yo!66Wq@N1@Gt`$VSu|E;Gkcz;&qc>176Dva03G@F~Hv{f2{y#fZrP6 z$G>1j{Oeo41jN72H^8|DIMo2}G{6Z4c)0Q0K2DrNc4ywkAABv}m0fWo{H!#2w1N`mt zubq@Lz;6xkV;(DhYQ9?r4EY8)*8ry);GG6I!2mBe!1E{`R!8+tF<^)>z>x+x!~l0N zz=4S-My$J_$B4wHMr=dHwh)%t0k;?KJX|fl3xDlX8%DpuLqCHmx$;?KY>Ia z`XwUjqaPZgbaoA0QbRY?&}}tzR1Mu&zx*+p#W*31U{PSk#_j z*1*w+esYR_^@)CJihf?o@X7j&z3%^AhY!&F?b(AKi#6$A#I!0PnyxBR5hu+ z(PvolY*@x;+ zQcPAvq8+Tz?z?94nXp#VZTh)i$n$+Td$DuXp|-&$m%695IsfwEz^t3f z4R^1vH6Pi|`?m=xS)0C0cev2d=ZNw?os@V8BRCG6jZz_jsG4cycM9BbYNOW51(OA%9p9rM!ivH#5KLVU~B4) z@Xw`B7VWw^?VCV0!_BJ0>TU<)+4fqm$$K{E8-Mk!Iv&*R#emlSSsFVA_GR_~t!Ggp7g@O-v( zRLs>W`XeP%`kAblb$Zz7oCX)4FZuhgHl6mYT(rl@*lfyrhYKYO?gjcyc@UMP@4{#*IKXRmMFbg4Aq$#@I(zWuuweK4KW>sw~f zmg!4#=1pulviXBN*PbiitlRl|p`vQG?T+0^|0H|d|6K8YT+6#{CoVYYMYMaXynfY_kCA?ey^9U7!|w6dhD#CzbpQ&3R!abX3B&3!}{m>_56Q(y}sS}6B_5v z>j&-nIIBhR!WL=MOGbS<^fbZ7=wEf^wk7SRb(|EtWyYcapVpBxbywcyw=#9Pv*vlv zkiCj$+?;z?;zzuh(&l@s`r%s_ej4J{XRpnO(;HHCf3ALRHs$mAB~8@*luwUzIsS*N zpI=sNw5DpU3EyUh=)7hQGwqHw)pma2E-!FLXF{d|S_#~vkB z+IyLPxR-PK$y1Mn7B5fi*xuz#zh`R>UCR|a-i)01*1659BWup@tXOY!eQ56$f!z

-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 diff --git a/tools/factory_image_parser.py b/tools/factory_image_parser.py index 3cf63f1..acd8f28 100755 --- a/tools/factory_image_parser.py +++ b/tools/factory_image_parser.py @@ -32,7 +32,6 @@ known_list = [ "system_ext.img", "system.img", "system_other.img", - "userdata.img", "vbmeta.img", "vbmeta_system.img", "vbmeta_vendor.img", @@ -43,20 +42,21 @@ known_list = [ ] unknown_list = [ - "cmnlib.img", #Pixel3 "abl.img", #Pixel3 "aop.img", #Pixel3 "cmnlib64.img", #Pixel3 + "cmnlib.img", #Pixel3 "devcfg.img", #Pixel3 "hyp.img", #Pixel3 "keymaster.img", #Pixel3 "modem.img", #Pixel3 + "pvmfw.img", #Pixel7 "qupfw.img", #Pixel3 + "super_empty.img", "tz.img", #Pixel3 - "xbl.img", #Pixel3 + "userdata.img", "xbl_config.img", #Pixel3 - "pvmfw.img", #Pixel7 - "super_empty.img" + "xbl.img", #Pixel3 ] tmp2 = "tmp2"