partial support of boot/vendor_boot v4

pull/66/head
cfig 4 years ago
parent e66477ce65
commit e2583777a0
No known key found for this signature in database
GPG Key ID: B104C307F0FDABB7

@ -68,6 +68,7 @@ Please note that the boot.img MUST follows AOSP verified boot flow, either [Boot
| Device Model | Manufacturer | Compatible | Android Version | Note |
|--------------------------------|--------------|----------------------|--------------------------|------|
| Pixel 3 (blueline) | Google | Y | 12 (spp2.210219.008, <Br>2021)| |
| Pixel 3 (blueline) | Google | Y | 11 (RP1A.200720.009, <Br>2020)| [more ...](doc/additional_tricks.md#pixel-3-blueline) |
| Pixel 3 (blueline) | Google | Y | Q preview (qpp2.190228.023, <Br>2019)| [more ...](doc/additional_tricks.md#pixel-3-blueline) |
| Pixel XL (marlin) | HTC | Y | 9.0.0 (PPR2.180905.006, <Br>Sep 2018)| [more ...](doc/additional_tricks.md#pixel-xl-marlin) |
@ -79,31 +80,64 @@ Please note that the boot.img MUST follows AOSP verified boot flow, either [Boot
| X7 (PD1602_A_3.12.8) | VIVO | N | ? | [Issue 35](https://github.com/cfig/Android_boot_image_editor/issues/35) |
## more examples
<details>
<summary>working with recovery.img</summary>
* recovery.img
Please remember to clean the work directory first.
If you are working with recovery.img, the steps are similar:
```bash
rm *.img
cp <your_recovery_image> recovery.img
./gradlew unpack
./gradlew pack
```
cp <your_recovery_image> recovery.img
./gradlew unpack
./gradlew pack
</details>
<details>
<summary>working with vbmeta.img</summary>
* vbmeta.img
```bash
rm *.img
cp <your_vbmeta_image> vbmeta.img
./gradlew unpack
./gradlew pack
```
* boot.img and vbmeta.img
</details>
<details>
<summary>working with boot.img and vbmeta.img</summary>
If your vbmeta.img contains hash of boot.img, you MUST update vbmeta image together.
```bash
rm *.img
cp <your_boot_image> boot.img
cp <your_vbmeta_image> vbmeta.img
./gradlew unpack
./gradlew pack
```
Your boot.img.signed and vbmeta.img.signd will be updated together.
Your boot.img.signed and vbmeta.img.signd will be updated together, then you can flash them to your device.
</details>
<details>
<summary>How to disable AVB verification</summary>
The idea is to set flag=2 in main vbmeta.
```bash
rm *.img
cp <your_vbmeta_image> vbmeta.img
./gradlew unpack
vim -u NONE -N build/unzip_boot/vbmeta.avb.json -c ":19s/0/2/g" -c ":wq"
./gradlew pack
```
Then flash vbmeta.img.signed to your device.
</details>
## boot.img layout
Read [layout](doc/layout.md) of Android boot.img and vendor\_boot.img.

@ -7,22 +7,23 @@ import java.io.InputStream
@OptIn(ExperimentalUnsignedTypes::class)
class BootHeaderV3(
var kernelSize: Int = 0,
var ramdiskSize: Int = 0,
var osVersion: String = "",
var osPatchLevel: String = "",
var headerSize: Int = 0,
var headerVersion: Int = 0,
var cmdline: String = ""
var kernelSize: Int = 0,
var ramdiskSize: Int = 0,
var osVersion: String = "",
var osPatchLevel: String = "",
var headerSize: Int = 0,
var headerVersion: Int = 0,
var cmdline: String = "",
var signatureSize: Int = 0
) {
@Throws(IllegalArgumentException::class)
constructor(iS: InputStream?) : this() {
if (iS == null) {
return
}
log.warn("BootImgHeaderV3 constructor")
log.warn("BootImgHeaderV3/V4 constructor")
val info = Struct3(FORMAT_STRING).unpack(iS)
assert(11 == info.size)
assert(12 == info.size)
if (info[0] != magic) {
throw IllegalArgumentException("stream doesn't look like Android Boot Image V3 Header")
}
@ -39,22 +40,26 @@ class BootHeaderV3(
this.cmdline = info[10] as String
assert(this.headerSize in intArrayOf(BOOT_IMAGE_HEADER_V3_SIZE))
this.signatureSize = (info[11] as UInt).toInt()
assert(this.headerSize in intArrayOf(BOOT_IMAGE_HEADER_V3_SIZE, BOOT_IMAGE_HEADER_V4_SIZE))
}
fun encode(): ByteArray {
return Struct3(FORMAT_STRING).pack(
magic,
kernelSize,
ramdiskSize,
(Common.packOsVersion(osVersion) shl 11) or Common.packOsPatchLevel(osPatchLevel),
headerSize,
0,
0,
0,
0,
headerVersion,
cmdline)
magic,
kernelSize,
ramdiskSize,
(Common.packOsVersion(osVersion) shl 11) or Common.packOsPatchLevel(osPatchLevel),
headerSize,
0,
0,
0,
0,
headerVersion,
cmdline,
signatureSize
)
}
override fun toString(): String {
@ -65,16 +70,18 @@ class BootHeaderV3(
internal val log = LoggerFactory.getLogger(BootHeaderV3::class.java)
const val magic = "ANDROID!"
const val FORMAT_STRING = "8s" + //"ANDROID!"
"4I" + //kernel size, ramdisk size, os_version/patch, header size
"4I" + //reserved
"I" + //header version
"1536s" //cmdline
"4I" + //kernel size, ramdisk size, os_version/patch, header size
"4I" + //reserved
"I" + //header version
"1536s" + //cmdline
"I" //signature size
private const val BOOT_IMAGE_HEADER_V3_SIZE = 1580
private const val BOOT_IMAGE_HEADER_V4_SIZE = 1584
const val pageSize: Int = 4096
init {
assert(BOOT_IMAGE_HEADER_V3_SIZE == Struct3(FORMAT_STRING).calcSize()) {
"internal error: expected size $BOOT_IMAGE_HEADER_V3_SIZE "
assert(BOOT_IMAGE_HEADER_V4_SIZE == Struct3(FORMAT_STRING).calcSize()) {
"internal error: expected size $BOOT_IMAGE_HEADER_V4_SIZE "
}
}
}

@ -41,6 +41,7 @@ data class BootV3(var info: MiscInfo = MiscInfo(),
ret.info.osVersion = header.osVersion
ret.info.osPatchLevel = header.osPatchLevel
ret.info.pageSize = BootHeaderV3.pageSize
ret.info.signatureSize = header.signatureSize
//kernel
ret.kernel.file = workDir + "kernel"
ret.kernel.size = header.kernelSize
@ -65,7 +66,8 @@ data class BootV3(var info: MiscInfo = MiscInfo(),
var cmdline: String = "",
var osVersion: String = "",
var osPatchLevel: String = "",
var imageSize: Long = 0
var imageSize: Long = 0,
var signatureSize: Int = 0
)
data class CommArgs(

@ -6,17 +6,21 @@ import java.io.InputStream
@OptIn(ExperimentalUnsignedTypes::class)
class VendorBootHeader(
var headerVersion: Int = 0,
var pageSize: Int = 0,
var kernelLoadAddr: Long = 0,
var ramdiskLoadAddr: Long = 0,
var vndRamdiskSize: Int = 0,
var cmdline: String = "",
var tagsLoadAddr: Long = 0,
var product: String = "",
var headerSize: Int = 0,
var dtbSize: Int = 0,
var dtbLoadAddr: Long = 0
var headerVersion: Int = 0,
var pageSize: Int = 0,
var kernelLoadAddr: Long = 0,
var ramdiskLoadAddr: Long = 0,
var vndRamdiskSize: Int = 0,
var cmdline: String = "",
var tagsLoadAddr: Long = 0,
var product: String = "",
var headerSize: Int = 0,
var dtbSize: Int = 0,
var dtbLoadAddr: Long = 0,
var vrtSize: Int = 0,
var vrtEntryNum: Int = 0,
var vrtEntrySize: Int = 0,
var bootconfigSize: Int = 0
) {
@Throws(IllegalArgumentException::class)
constructor(iS: InputStream?) : this() {
@ -25,7 +29,7 @@ class VendorBootHeader(
}
log.warn("VendorBootHeader constructor")
val info = Struct3(FORMAT_STRING).unpack(iS)
assert(12 == info.size)
assert(16 == info.size)
if (info[0] != magic) {
throw IllegalArgumentException("stream doesn't look like Android Vendor Boot Image")
}
@ -40,35 +44,45 @@ class VendorBootHeader(
this.headerSize = (info[9] as UInt).toInt()
this.dtbSize = (info[10] as UInt).toInt()
this.dtbLoadAddr = (info[11] as ULong).toLong()
this.vrtSize = (info[12] as UInt).toInt()
this.vrtEntryNum = (info[13] as UInt).toInt()
this.vrtEntrySize = (info[14] as UInt).toInt()
this.bootconfigSize = (info[15] as UInt).toInt()
if (this.headerSize !in arrayOf(VENDOR_BOOT_IMAGE_HEADER_V3_SIZE)) {
if (this.headerSize !in arrayOf(VENDOR_BOOT_IMAGE_HEADER_V3_SIZE, VENDOR_BOOT_IMAGE_HEADER_V4_SIZE)) {
throw IllegalArgumentException("header size " + this.headerSize + " invalid")
}
if (this.headerVersion != 3) {
if (this.headerVersion !in 3..4) {
throw IllegalArgumentException("header version " + this.headerVersion + " invalid")
}
}
fun encode(): ByteArray {
return Struct3(FORMAT_STRING).pack(
magic,
headerVersion,
pageSize,
kernelLoadAddr,
ramdiskLoadAddr,
vndRamdiskSize,
cmdline,
tagsLoadAddr,
product,
headerSize,
dtbSize,
dtbLoadAddr)
magic,
headerVersion,
pageSize,
kernelLoadAddr,
ramdiskLoadAddr,
vndRamdiskSize,
cmdline,
tagsLoadAddr,
product,
headerSize,
dtbSize,
dtbLoadAddr,
vrtSize,
vrtEntryNum,
vrtEntrySize,
bootconfigSize
)
}
companion object {
private val log = LoggerFactory.getLogger(VendorBootHeader::class.java)
const val magic = "VNDRBOOT"
const val VENDOR_BOOT_IMAGE_HEADER_V3_SIZE = 2112
const val VENDOR_BOOT_IMAGE_HEADER_V4_SIZE = 2128
const val FORMAT_STRING = "8s" + //magic
"I" + //header version
"I" + //page size
@ -80,13 +94,20 @@ class VendorBootHeader(
"16s" + //product name
"I" + //header size
"I" + //dtb size
"Q" //dtb physical load addr
"Q" + //dtb physical load addr
"I" + //[v4] vendor ramdisk table size
"I" + //[v4] vendor ramdisk table entry num
"I" + //[v4] vendor ramdisk table entry size
"I" //[v4] bootconfig size
init {
assert(Struct3(FORMAT_STRING).calcSize() == VENDOR_BOOT_IMAGE_HEADER_V3_SIZE)
assert(Struct3(FORMAT_STRING).calcSize() == VENDOR_BOOT_IMAGE_HEADER_V4_SIZE)
}
}
override fun toString(): String {
return "VendorBootHeader(headerVersion=$headerVersion, pageSize=$pageSize, kernelLoadAddr=$kernelLoadAddr, ramdiskLoadAddr=$ramdiskLoadAddr, vndRamdiskSize=$vndRamdiskSize, cmdline='$cmdline', tagsLoadAddr=$tagsLoadAddr, product='$product', headerSize=$headerSize, dtbSize=$dtbSize, dtbLoadAddr=$dtbLoadAddr)"
return "VendorBootHeader(headerVersion=$headerVersion, pageSize=$pageSize, kernelLoadAddr=$kernelLoadAddr, ramdiskLoadAddr=$ramdiskLoadAddr, vndRamdiskSize=$vndRamdiskSize, cmdline='$cmdline', tagsLoadAddr=$tagsLoadAddr, product='$product', headerSize=$headerSize, dtbSize=$dtbSize, dtbLoadAddr=$dtbLoadAddr, vrtSize=$vrtSize, vrtEntryNum=$vrtEntryNum, vrtEntrySize=$vrtEntrySize, bootconfigSize=$bootconfigSize)"
}
}

@ -27,21 +27,20 @@ class BootImgParser() : IPackable {
try {
val hv = probeHeaderVersion(fileName)
log.info("header version $hv")
if (hv == 3) {
val b3 = BootV3
if (hv in 0..2) {
val b2 = BootV2
.parse(fileName)
.extractImages()
.extractVBMeta()
.printSummary()
log.debug(b3.toString())
return
log.debug(b2.toString())
} else {
val b2 = BootV2
val b3 = BootV3
.parse(fileName)
.extractImages()
.extractVBMeta()
.printSummary()
log.debug(b2.toString())
log.debug(b3.toString())
}
} catch (e: IllegalArgumentException) {
log.error(e.message)

@ -1,23 +1,20 @@
# layout of [vendor\_]boot.img
## Image Content Index
[1. boot.img v0-v2](#1-bootimg-v0-v2)
[1 header part](#1-header-part)
- [1.1 boot.img v0-v2](#11-bootimg-header-v0-v2)
- [1.2 boot.img v3](#12-bootimg-header-v3)
- [1.3 vendor\_boot.img v3](#13-vendor_bootimg-header-v3)
[2. boot.img v3-v4](#2-bootimg-v3-v4)
[2 data part](#2-data-part)
[3. vendor_boot.img v3-v4](#3-vendor_bootimg-v3-v4)
[3 signature part](#3-signature-part)
[4. signature part](#4-signature-part)
- [3.1 Boot Image Signature](#31-boot-image-signature-vboot-10)
- [4.1 Boot Image Signature](#41-boot-image-signature-vboot-10)
- [3.2 AVB Footer](#32-avb-footer-vboot-20)
- [4.2 AVB Footer](#42-avb-footer-vboot-20)
## 1. header part
### 1.1 boot.img header v0-v2
value at 0x28 is 0x00,0x01,0x02
## 1. boot.img v0-v2
### header
Value at 0x28 is one of {0x00,0x01,0x02,0x03,0x04}, this filed should be read first to identify header version.
item size in bytes position
+-----------------------------------------------------------+ --> 0
@ -38,7 +35,7 @@ value at 0x28 is 0x00,0x01,0x02
|<tags offset> | 4 |
|--------------------------------+--------------------------| --> 36
|<page size> | 4 |
|--------------------------------+--------------------------| --> 40
|--------------------------------+--------------------------| --> 40 (0x28)
|<header version> | 4 (value in [0,1,2]) |
|--------------------------------+--------------------------| --> 44
|<os version & os patch level> | 4 |
@ -66,7 +63,41 @@ value at 0x28 is 0x00,0x01,0x02
| | - header_size) |
+--------------------------------+--------------------------+ --> pagesize
### 1.2 boot.img header v3
### data
+-----------------------------------------------------------+ --> pagesize
|<kernel> | kernel length |
|--------------------------------+--------------------------|
|<padding> | min(n * page_size - len) |
+-----------------------------------------------------------+
+-----------------------------------------------------------+
|<ramdisk> | ramdisk length |
|--------------------------------+--------------------------|
|<padding> | min(n * page_size - len) |
+-----------------------------------------------------------+
+-----------------------------------------------------------+
|<second bootloader> | second bootloader length |
|--------------------------------+--------------------------|
|<padding> | min(n * page_size - len) |
+-----------------------------------------------------------+
+-----------------------------------------------------------+
|<recovery dtbo> [v1] | recovery dtbo length |
|--------------------------------+--------------------------|
|<padding> [v1] | min(n * page_size - len) |
+-----------------------------------------------------------+
+-----------------------------------------------------------+
|<dtb> [v2] | dtb length |
|--------------------------------+--------------------------|
|<padding> [v2] | min(n * page_size - len) |
+-----------------------------------------------------------+ --> end of data part
## 2. boot.img v3-v4
### header
item size in bytes position
+-----------------------------------------------------------+ --> 0
@ -81,16 +112,37 @@ value at 0x28 is 0x00,0x01,0x02
|<header size> | 4 |
|--------------------------------+--------------------------| --> 24
|<reserved> | 4 * 4 |
|--------------------------------+--------------------------| --> 40
|<header version> | 4 (value=3) |
|--------------------------------+--------------------------| --> 40 (0x28)
|<header version> | 4 (value in [3|4]) |
|--------------------------------+--------------------------| --> 44
|<cmdline> | 1024+512=1536 |
|--------------------------------+--------------------------| --> 1580
|--------------------------------+--------------------------| --> 44
|<signature_size> (v4 only) | 4 |
|--------------------------------+--------------------------| --> 1584
|<padding> | min(n * page_size |
| | - header_size) |
+--------------------------------+--------------------------+ --> pagesize=4096
### 1.3 vendor\_boot.img header v3
### data
```
+-----------------------------------------------------------+ --> pagesize
|<kernel> | kernel length |
+-----------------------------------------------------------+
|<ramdisk> | ramdisk length |
+-----------------------------------------------------------+
|<boot signature> (v4 only) | boot signature length |
+--------------------------------+--------------------------+
padding calculation:
|<padding> | min(n * page_size - len) |
```
## 3. vendor\_boot.img v3-v4
### header
item size in bytes position
+-----------------------------------------------------------+ --> 0
@ -118,45 +170,37 @@ value at 0x28 is 0x00,0x01,0x02
|--------------------------------+--------------------------| --> 2104
|<dtb load addr> | 8 |
|--------------------------------+--------------------------| --> 2112
|<vendor ramdisk table size> | 4 (v4 only) |
|--------------------------------+--------------------------| --> 2116
|<vendor ramdisk table entry num>| 4 (v4 only) |
|--------------------------------+--------------------------| --> 2120
|<vendor ramdisk table entry size| 4 (v4 only) |
|--------------------------------+--------------------------| --> 2124
|<bootconfig size> | 4 (v4 only) |
|--------------------------------+--------------------------| --> 2128
|<padding> | min(n * page_size |
| | - header_size) |
+--------------------------------+--------------------------+ --> pagesize
## 2. data part
### data
```
+-----------------------------------------------------------+ --> pagesize
|<kernel> | kernel length |
|--------------------------------+--------------------------|
|<padding> | min(n * page_size - len) |
+-----------------------------------------------------------+
+-----------------------------------------------------------+
|<ramdisk> | ramdisk length |
|--------------------------------+--------------------------|
|<padding> | min(n * page_size - len) |
+-----------------------------------------------------------+
+-----------------------------------------------------------+
|<second bootloader> | second bootloader length |
|--------------------------------+--------------------------|
|<padding> | min(n * page_size - len) |
|<vendor ramdisk section> | padded len |
+--------------------------------+--------------------------+
|<dtb> | padded len |
+--------------------------------+--------------------------+
|<vendor ramdisk table> | padded len |
+-----------------------------------------------------------+
|<bootconfig> | padded len |
+--------------------------------+--------------------------+
```
+-----------------------------------------------------------+
|<recovery dtbo> [v1] | recovery dtbo length |
|--------------------------------+--------------------------|
|<padding> [v1] | min(n * page_size - len) |
+-----------------------------------------------------------+
+-----------------------------------------------------------+
|<dtb> [v2] | dtb length |
|--------------------------------+--------------------------|
|<padding> [v2] | min(n * page_size - len) |
+-----------------------------------------------------------+ --> end of data part
## 3. signature part
## 4. signature part
### 3.1 Boot Image Signature (VBoot 1.0)
### 4.1 Boot Image Signature (VBoot 1.0)
+--------------------------------+--------------------------+ --> end of data part
|<signature> | signature length |
@ -164,7 +208,7 @@ value at 0x28 is 0x00,0x01,0x02
|<padding> | defined by boot_signer |
+--------------------------------+--------------------------+
### 3.2 AVB Footer (VBoot 2.0)
### 4.2 AVB Footer (VBoot 2.0)
item size in bytes position
+------+--------------------------------+-------------------------+ --> end of data part (say locaton +0)

Loading…
Cancel
Save