1*333d2b36SAndroid Build Coastguard Worker// Copyright (C) 2021 The Android Open Source Project 2*333d2b36SAndroid Build Coastguard Worker// 3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License"); 4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License. 5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at 6*333d2b36SAndroid Build Coastguard Worker// 7*333d2b36SAndroid Build Coastguard Worker// http://www.apache.org/licenses/LICENSE-2.0 8*333d2b36SAndroid Build Coastguard Worker// 9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software 10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS, 11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and 13*333d2b36SAndroid Build Coastguard Worker// limitations under the License. 14*333d2b36SAndroid Build Coastguard Worker 15*333d2b36SAndroid Build Coastguard Workerpackage filesystem 16*333d2b36SAndroid Build Coastguard Worker 17*333d2b36SAndroid Build Coastguard Workerimport ( 18*333d2b36SAndroid Build Coastguard Worker "fmt" 19*333d2b36SAndroid Build Coastguard Worker "strconv" 20*333d2b36SAndroid Build Coastguard Worker "strings" 21*333d2b36SAndroid Build Coastguard Worker 22*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint" 23*333d2b36SAndroid Build Coastguard Worker "github.com/google/blueprint/proptools" 24*333d2b36SAndroid Build Coastguard Worker 25*333d2b36SAndroid Build Coastguard Worker "android/soong/android" 26*333d2b36SAndroid Build Coastguard Worker) 27*333d2b36SAndroid Build Coastguard Worker 28*333d2b36SAndroid Build Coastguard Workerfunc init() { 29*333d2b36SAndroid Build Coastguard Worker android.RegisterModuleType("bootimg", BootimgFactory) 30*333d2b36SAndroid Build Coastguard Worker} 31*333d2b36SAndroid Build Coastguard Worker 32*333d2b36SAndroid Build Coastguard Workertype bootimg struct { 33*333d2b36SAndroid Build Coastguard Worker android.ModuleBase 34*333d2b36SAndroid Build Coastguard Worker 35*333d2b36SAndroid Build Coastguard Worker properties BootimgProperties 36*333d2b36SAndroid Build Coastguard Worker 37*333d2b36SAndroid Build Coastguard Worker output android.Path 38*333d2b36SAndroid Build Coastguard Worker installDir android.InstallPath 39*333d2b36SAndroid Build Coastguard Worker 40*333d2b36SAndroid Build Coastguard Worker bootImageType bootImageType 41*333d2b36SAndroid Build Coastguard Worker} 42*333d2b36SAndroid Build Coastguard Worker 43*333d2b36SAndroid Build Coastguard Workertype BootimgProperties struct { 44*333d2b36SAndroid Build Coastguard Worker // Set the name of the output. Defaults to <module_name>.img. 45*333d2b36SAndroid Build Coastguard Worker Stem *string 46*333d2b36SAndroid Build Coastguard Worker 47*333d2b36SAndroid Build Coastguard Worker // Path to the linux kernel prebuilt file 48*333d2b36SAndroid Build Coastguard Worker Kernel_prebuilt *string `android:"arch_variant,path"` 49*333d2b36SAndroid Build Coastguard Worker 50*333d2b36SAndroid Build Coastguard Worker // Filesystem module that is used as ramdisk 51*333d2b36SAndroid Build Coastguard Worker Ramdisk_module *string 52*333d2b36SAndroid Build Coastguard Worker 53*333d2b36SAndroid Build Coastguard Worker // Path to the device tree blob (DTB) prebuilt file to add to this boot image 54*333d2b36SAndroid Build Coastguard Worker Dtb_prebuilt *string `android:"arch_variant,path"` 55*333d2b36SAndroid Build Coastguard Worker 56*333d2b36SAndroid Build Coastguard Worker // Header version number. Must be set to one of the version numbers that are currently 57*333d2b36SAndroid Build Coastguard Worker // supported. Refer to 58*333d2b36SAndroid Build Coastguard Worker // https://source.android.com/devices/bootloader/boot-image-header 59*333d2b36SAndroid Build Coastguard Worker Header_version *string 60*333d2b36SAndroid Build Coastguard Worker 61*333d2b36SAndroid Build Coastguard Worker // Determines the specific type of boot image this module is building. Can be boot, 62*333d2b36SAndroid Build Coastguard Worker // vendor_boot or init_boot. Defaults to boot. 63*333d2b36SAndroid Build Coastguard Worker // Refer to https://source.android.com/devices/bootloader/partitions/vendor-boot-partitions 64*333d2b36SAndroid Build Coastguard Worker // for vendor_boot. 65*333d2b36SAndroid Build Coastguard Worker // Refer to https://source.android.com/docs/core/architecture/partitions/generic-boot for 66*333d2b36SAndroid Build Coastguard Worker // init_boot. 67*333d2b36SAndroid Build Coastguard Worker Boot_image_type *string 68*333d2b36SAndroid Build Coastguard Worker 69*333d2b36SAndroid Build Coastguard Worker // Optional kernel commandline arguments 70*333d2b36SAndroid Build Coastguard Worker Cmdline []string `android:"arch_variant"` 71*333d2b36SAndroid Build Coastguard Worker 72*333d2b36SAndroid Build Coastguard Worker // File that contains bootconfig parameters. This can be set only when `vendor_boot` is true 73*333d2b36SAndroid Build Coastguard Worker // and `header_version` is greater than or equal to 4. 74*333d2b36SAndroid Build Coastguard Worker Bootconfig *string `android:"arch_variant,path"` 75*333d2b36SAndroid Build Coastguard Worker 76*333d2b36SAndroid Build Coastguard Worker // The size of the partition on the device. It will be a build error if this built partition 77*333d2b36SAndroid Build Coastguard Worker // image exceeds this size. 78*333d2b36SAndroid Build Coastguard Worker Partition_size *int64 79*333d2b36SAndroid Build Coastguard Worker 80*333d2b36SAndroid Build Coastguard Worker // When set to true, sign the image with avbtool. Default is false. 81*333d2b36SAndroid Build Coastguard Worker Use_avb *bool 82*333d2b36SAndroid Build Coastguard Worker 83*333d2b36SAndroid Build Coastguard Worker // This can either be "default", or "make_legacy". "make_legacy" will sign the boot image 84*333d2b36SAndroid Build Coastguard Worker // like how build/make/core/Makefile does, to get bit-for-bit backwards compatibility. But 85*333d2b36SAndroid Build Coastguard Worker // we may want to reconsider if it's necessary to have two modes in the future. The default 86*333d2b36SAndroid Build Coastguard Worker // is "default" 87*333d2b36SAndroid Build Coastguard Worker Avb_mode *string 88*333d2b36SAndroid Build Coastguard Worker 89*333d2b36SAndroid Build Coastguard Worker // Name of the partition stored in vbmeta desc. Defaults to the name of this module. 90*333d2b36SAndroid Build Coastguard Worker Partition_name *string 91*333d2b36SAndroid Build Coastguard Worker 92*333d2b36SAndroid Build Coastguard Worker // Path to the private key that avbtool will use to sign this filesystem image. 93*333d2b36SAndroid Build Coastguard Worker // TODO(jiyong): allow apex_key to be specified here 94*333d2b36SAndroid Build Coastguard Worker Avb_private_key *string `android:"path_device_first"` 95*333d2b36SAndroid Build Coastguard Worker 96*333d2b36SAndroid Build Coastguard Worker // Hash and signing algorithm for avbtool. Default is SHA256_RSA4096. 97*333d2b36SAndroid Build Coastguard Worker Avb_algorithm *string 98*333d2b36SAndroid Build Coastguard Worker 99*333d2b36SAndroid Build Coastguard Worker // The index used to prevent rollback of the image on device. 100*333d2b36SAndroid Build Coastguard Worker Avb_rollback_index *int64 101*333d2b36SAndroid Build Coastguard Worker 102*333d2b36SAndroid Build Coastguard Worker // The security patch passed to as the com.android.build.<type>.security_patch avb property. 103*333d2b36SAndroid Build Coastguard Worker // Replacement for the make variables BOOT_SECURITY_PATCH / INIT_BOOT_SECURITY_PATCH. 104*333d2b36SAndroid Build Coastguard Worker Security_patch *string 105*333d2b36SAndroid Build Coastguard Worker} 106*333d2b36SAndroid Build Coastguard Worker 107*333d2b36SAndroid Build Coastguard Workertype bootImageType int 108*333d2b36SAndroid Build Coastguard Worker 109*333d2b36SAndroid Build Coastguard Workerconst ( 110*333d2b36SAndroid Build Coastguard Worker unsupported bootImageType = iota 111*333d2b36SAndroid Build Coastguard Worker boot 112*333d2b36SAndroid Build Coastguard Worker vendorBoot 113*333d2b36SAndroid Build Coastguard Worker initBoot 114*333d2b36SAndroid Build Coastguard Worker) 115*333d2b36SAndroid Build Coastguard Worker 116*333d2b36SAndroid Build Coastguard Workerfunc toBootImageType(ctx android.ModuleContext, bootImageType string) bootImageType { 117*333d2b36SAndroid Build Coastguard Worker switch bootImageType { 118*333d2b36SAndroid Build Coastguard Worker case "boot": 119*333d2b36SAndroid Build Coastguard Worker return boot 120*333d2b36SAndroid Build Coastguard Worker case "vendor_boot": 121*333d2b36SAndroid Build Coastguard Worker return vendorBoot 122*333d2b36SAndroid Build Coastguard Worker case "init_boot": 123*333d2b36SAndroid Build Coastguard Worker return initBoot 124*333d2b36SAndroid Build Coastguard Worker default: 125*333d2b36SAndroid Build Coastguard Worker ctx.ModuleErrorf("Unknown boot_image_type %s. Must be one of \"boot\", \"vendor_boot\", or \"init_boot\"", bootImageType) 126*333d2b36SAndroid Build Coastguard Worker } 127*333d2b36SAndroid Build Coastguard Worker return unsupported 128*333d2b36SAndroid Build Coastguard Worker} 129*333d2b36SAndroid Build Coastguard Worker 130*333d2b36SAndroid Build Coastguard Workerfunc (b bootImageType) String() string { 131*333d2b36SAndroid Build Coastguard Worker switch b { 132*333d2b36SAndroid Build Coastguard Worker case boot: 133*333d2b36SAndroid Build Coastguard Worker return "boot" 134*333d2b36SAndroid Build Coastguard Worker case vendorBoot: 135*333d2b36SAndroid Build Coastguard Worker return "vendor_boot" 136*333d2b36SAndroid Build Coastguard Worker case initBoot: 137*333d2b36SAndroid Build Coastguard Worker return "init_boot" 138*333d2b36SAndroid Build Coastguard Worker default: 139*333d2b36SAndroid Build Coastguard Worker panic("unknown boot image type") 140*333d2b36SAndroid Build Coastguard Worker } 141*333d2b36SAndroid Build Coastguard Worker} 142*333d2b36SAndroid Build Coastguard Worker 143*333d2b36SAndroid Build Coastguard Workerfunc (b bootImageType) isBoot() bool { 144*333d2b36SAndroid Build Coastguard Worker return b == boot 145*333d2b36SAndroid Build Coastguard Worker} 146*333d2b36SAndroid Build Coastguard Worker 147*333d2b36SAndroid Build Coastguard Workerfunc (b bootImageType) isVendorBoot() bool { 148*333d2b36SAndroid Build Coastguard Worker return b == vendorBoot 149*333d2b36SAndroid Build Coastguard Worker} 150*333d2b36SAndroid Build Coastguard Worker 151*333d2b36SAndroid Build Coastguard Workerfunc (b bootImageType) isInitBoot() bool { 152*333d2b36SAndroid Build Coastguard Worker return b == initBoot 153*333d2b36SAndroid Build Coastguard Worker} 154*333d2b36SAndroid Build Coastguard Worker 155*333d2b36SAndroid Build Coastguard Worker// bootimg is the image for the boot partition. It consists of header, kernel, ramdisk, and dtb. 156*333d2b36SAndroid Build Coastguard Workerfunc BootimgFactory() android.Module { 157*333d2b36SAndroid Build Coastguard Worker module := &bootimg{} 158*333d2b36SAndroid Build Coastguard Worker module.AddProperties(&module.properties) 159*333d2b36SAndroid Build Coastguard Worker android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) 160*333d2b36SAndroid Build Coastguard Worker return module 161*333d2b36SAndroid Build Coastguard Worker} 162*333d2b36SAndroid Build Coastguard Worker 163*333d2b36SAndroid Build Coastguard Workertype bootimgDep struct { 164*333d2b36SAndroid Build Coastguard Worker blueprint.BaseDependencyTag 165*333d2b36SAndroid Build Coastguard Worker kind string 166*333d2b36SAndroid Build Coastguard Worker} 167*333d2b36SAndroid Build Coastguard Worker 168*333d2b36SAndroid Build Coastguard Workervar bootimgRamdiskDep = bootimgDep{kind: "ramdisk"} 169*333d2b36SAndroid Build Coastguard Worker 170*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) DepsMutator(ctx android.BottomUpMutatorContext) { 171*333d2b36SAndroid Build Coastguard Worker ramdisk := proptools.String(b.properties.Ramdisk_module) 172*333d2b36SAndroid Build Coastguard Worker if ramdisk != "" { 173*333d2b36SAndroid Build Coastguard Worker ctx.AddDependency(ctx.Module(), bootimgRamdiskDep, ramdisk) 174*333d2b36SAndroid Build Coastguard Worker } 175*333d2b36SAndroid Build Coastguard Worker} 176*333d2b36SAndroid Build Coastguard Worker 177*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) installFileName() string { 178*333d2b36SAndroid Build Coastguard Worker return proptools.StringDefault(b.properties.Stem, b.BaseModuleName()+".img") 179*333d2b36SAndroid Build Coastguard Worker} 180*333d2b36SAndroid Build Coastguard Worker 181*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) partitionName() string { 182*333d2b36SAndroid Build Coastguard Worker return proptools.StringDefault(b.properties.Partition_name, b.BaseModuleName()) 183*333d2b36SAndroid Build Coastguard Worker} 184*333d2b36SAndroid Build Coastguard Worker 185*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) GenerateAndroidBuildActions(ctx android.ModuleContext) { 186*333d2b36SAndroid Build Coastguard Worker b.bootImageType = toBootImageType(ctx, proptools.StringDefault(b.properties.Boot_image_type, "boot")) 187*333d2b36SAndroid Build Coastguard Worker if b.bootImageType == unsupported { 188*333d2b36SAndroid Build Coastguard Worker return 189*333d2b36SAndroid Build Coastguard Worker } 190*333d2b36SAndroid Build Coastguard Worker 191*333d2b36SAndroid Build Coastguard Worker kernelProp := proptools.String(b.properties.Kernel_prebuilt) 192*333d2b36SAndroid Build Coastguard Worker if b.bootImageType.isVendorBoot() && kernelProp != "" { 193*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("kernel_prebuilt", "vendor_boot partition can't have kernel") 194*333d2b36SAndroid Build Coastguard Worker return 195*333d2b36SAndroid Build Coastguard Worker } 196*333d2b36SAndroid Build Coastguard Worker if b.bootImageType.isBoot() && kernelProp == "" { 197*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("kernel_prebuilt", "boot partition must have kernel") 198*333d2b36SAndroid Build Coastguard Worker return 199*333d2b36SAndroid Build Coastguard Worker } 200*333d2b36SAndroid Build Coastguard Worker var kernel android.Path 201*333d2b36SAndroid Build Coastguard Worker if kernelProp != "" { 202*333d2b36SAndroid Build Coastguard Worker kernel = android.PathForModuleSrc(ctx, kernelProp) 203*333d2b36SAndroid Build Coastguard Worker } 204*333d2b36SAndroid Build Coastguard Worker 205*333d2b36SAndroid Build Coastguard Worker unsignedOutput := b.buildBootImage(ctx, kernel) 206*333d2b36SAndroid Build Coastguard Worker 207*333d2b36SAndroid Build Coastguard Worker output := unsignedOutput 208*333d2b36SAndroid Build Coastguard Worker if proptools.Bool(b.properties.Use_avb) { 209*333d2b36SAndroid Build Coastguard Worker // This bootimg module supports 2 modes of avb signing. It is not clear to this author 210*333d2b36SAndroid Build Coastguard Worker // why there are differences, but one of them is to match the behavior of make-built boot 211*333d2b36SAndroid Build Coastguard Worker // images. 212*333d2b36SAndroid Build Coastguard Worker switch proptools.StringDefault(b.properties.Avb_mode, "default") { 213*333d2b36SAndroid Build Coastguard Worker case "default": 214*333d2b36SAndroid Build Coastguard Worker output = b.signImage(ctx, unsignedOutput) 215*333d2b36SAndroid Build Coastguard Worker case "make_legacy": 216*333d2b36SAndroid Build Coastguard Worker output = b.addAvbFooter(ctx, unsignedOutput, kernel) 217*333d2b36SAndroid Build Coastguard Worker default: 218*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("avb_mode", `Unknown value for avb_mode, expected "default" or "make_legacy", got: %q`, *b.properties.Avb_mode) 219*333d2b36SAndroid Build Coastguard Worker } 220*333d2b36SAndroid Build Coastguard Worker } 221*333d2b36SAndroid Build Coastguard Worker 222*333d2b36SAndroid Build Coastguard Worker b.installDir = android.PathForModuleInstall(ctx, "etc") 223*333d2b36SAndroid Build Coastguard Worker ctx.InstallFile(b.installDir, b.installFileName(), output) 224*333d2b36SAndroid Build Coastguard Worker 225*333d2b36SAndroid Build Coastguard Worker ctx.SetOutputFiles([]android.Path{output}, "") 226*333d2b36SAndroid Build Coastguard Worker b.output = output 227*333d2b36SAndroid Build Coastguard Worker} 228*333d2b36SAndroid Build Coastguard Worker 229*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) buildBootImage(ctx android.ModuleContext, kernel android.Path) android.Path { 230*333d2b36SAndroid Build Coastguard Worker output := android.PathForModuleOut(ctx, "unsigned", b.installFileName()) 231*333d2b36SAndroid Build Coastguard Worker 232*333d2b36SAndroid Build Coastguard Worker builder := android.NewRuleBuilder(pctx, ctx) 233*333d2b36SAndroid Build Coastguard Worker cmd := builder.Command().BuiltTool("mkbootimg") 234*333d2b36SAndroid Build Coastguard Worker 235*333d2b36SAndroid Build Coastguard Worker if kernel != nil { 236*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithInput("--kernel ", kernel) 237*333d2b36SAndroid Build Coastguard Worker } 238*333d2b36SAndroid Build Coastguard Worker 239*333d2b36SAndroid Build Coastguard Worker // These arguments are passed for boot.img and init_boot.img generation 240*333d2b36SAndroid Build Coastguard Worker if b.bootImageType.isBoot() || b.bootImageType.isInitBoot() { 241*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithArg("--os_version ", ctx.Config().PlatformVersionLastStable()) 242*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithArg("--os_patch_level ", ctx.Config().PlatformSecurityPatch()) 243*333d2b36SAndroid Build Coastguard Worker } 244*333d2b36SAndroid Build Coastguard Worker 245*333d2b36SAndroid Build Coastguard Worker dtbName := proptools.String(b.properties.Dtb_prebuilt) 246*333d2b36SAndroid Build Coastguard Worker if dtbName != "" { 247*333d2b36SAndroid Build Coastguard Worker dtb := android.PathForModuleSrc(ctx, dtbName) 248*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithInput("--dtb ", dtb) 249*333d2b36SAndroid Build Coastguard Worker } 250*333d2b36SAndroid Build Coastguard Worker 251*333d2b36SAndroid Build Coastguard Worker cmdline := strings.Join(b.properties.Cmdline, " ") 252*333d2b36SAndroid Build Coastguard Worker if cmdline != "" { 253*333d2b36SAndroid Build Coastguard Worker flag := "--cmdline " 254*333d2b36SAndroid Build Coastguard Worker if b.bootImageType.isVendorBoot() { 255*333d2b36SAndroid Build Coastguard Worker flag = "--vendor_cmdline " 256*333d2b36SAndroid Build Coastguard Worker } 257*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithArg(flag, proptools.ShellEscapeIncludingSpaces(cmdline)) 258*333d2b36SAndroid Build Coastguard Worker } 259*333d2b36SAndroid Build Coastguard Worker 260*333d2b36SAndroid Build Coastguard Worker headerVersion := proptools.String(b.properties.Header_version) 261*333d2b36SAndroid Build Coastguard Worker if headerVersion == "" { 262*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("header_version", "must be set") 263*333d2b36SAndroid Build Coastguard Worker return output 264*333d2b36SAndroid Build Coastguard Worker } 265*333d2b36SAndroid Build Coastguard Worker verNum, err := strconv.Atoi(headerVersion) 266*333d2b36SAndroid Build Coastguard Worker if err != nil { 267*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("header_version", "%q is not a number", headerVersion) 268*333d2b36SAndroid Build Coastguard Worker return output 269*333d2b36SAndroid Build Coastguard Worker } 270*333d2b36SAndroid Build Coastguard Worker if verNum < 3 { 271*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("header_version", "must be 3 or higher for vendor_boot") 272*333d2b36SAndroid Build Coastguard Worker return output 273*333d2b36SAndroid Build Coastguard Worker } 274*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithArg("--header_version ", headerVersion) 275*333d2b36SAndroid Build Coastguard Worker 276*333d2b36SAndroid Build Coastguard Worker ramdiskName := proptools.String(b.properties.Ramdisk_module) 277*333d2b36SAndroid Build Coastguard Worker if ramdiskName != "" { 278*333d2b36SAndroid Build Coastguard Worker ramdisk := ctx.GetDirectDepWithTag(ramdiskName, bootimgRamdiskDep) 279*333d2b36SAndroid Build Coastguard Worker if filesystem, ok := ramdisk.(*filesystem); ok { 280*333d2b36SAndroid Build Coastguard Worker flag := "--ramdisk " 281*333d2b36SAndroid Build Coastguard Worker if b.bootImageType.isVendorBoot() { 282*333d2b36SAndroid Build Coastguard Worker flag = "--vendor_ramdisk " 283*333d2b36SAndroid Build Coastguard Worker } 284*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithInput(flag, filesystem.OutputPath()) 285*333d2b36SAndroid Build Coastguard Worker } else { 286*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("ramdisk", "%q is not android_filesystem module", ramdisk.Name()) 287*333d2b36SAndroid Build Coastguard Worker return output 288*333d2b36SAndroid Build Coastguard Worker } 289*333d2b36SAndroid Build Coastguard Worker } 290*333d2b36SAndroid Build Coastguard Worker 291*333d2b36SAndroid Build Coastguard Worker bootconfig := proptools.String(b.properties.Bootconfig) 292*333d2b36SAndroid Build Coastguard Worker if bootconfig != "" { 293*333d2b36SAndroid Build Coastguard Worker if !b.bootImageType.isVendorBoot() { 294*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("bootconfig", "requires vendor_boot: true") 295*333d2b36SAndroid Build Coastguard Worker return output 296*333d2b36SAndroid Build Coastguard Worker } 297*333d2b36SAndroid Build Coastguard Worker if verNum < 4 { 298*333d2b36SAndroid Build Coastguard Worker ctx.PropertyErrorf("bootconfig", "requires header_version: 4 or later") 299*333d2b36SAndroid Build Coastguard Worker return output 300*333d2b36SAndroid Build Coastguard Worker } 301*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithInput("--vendor_bootconfig ", android.PathForModuleSrc(ctx, bootconfig)) 302*333d2b36SAndroid Build Coastguard Worker } 303*333d2b36SAndroid Build Coastguard Worker 304*333d2b36SAndroid Build Coastguard Worker // Output flag for boot.img and init_boot.img 305*333d2b36SAndroid Build Coastguard Worker flag := "--output " 306*333d2b36SAndroid Build Coastguard Worker if b.bootImageType.isVendorBoot() { 307*333d2b36SAndroid Build Coastguard Worker flag = "--vendor_boot " 308*333d2b36SAndroid Build Coastguard Worker } 309*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithOutput(flag, output) 310*333d2b36SAndroid Build Coastguard Worker 311*333d2b36SAndroid Build Coastguard Worker if b.properties.Partition_size != nil { 312*333d2b36SAndroid Build Coastguard Worker assertMaxImageSize(builder, output, *b.properties.Partition_size, proptools.Bool(b.properties.Use_avb)) 313*333d2b36SAndroid Build Coastguard Worker } 314*333d2b36SAndroid Build Coastguard Worker 315*333d2b36SAndroid Build Coastguard Worker builder.Build("build_bootimg", fmt.Sprintf("Creating %s", b.BaseModuleName())) 316*333d2b36SAndroid Build Coastguard Worker return output 317*333d2b36SAndroid Build Coastguard Worker} 318*333d2b36SAndroid Build Coastguard Worker 319*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) addAvbFooter(ctx android.ModuleContext, unsignedImage android.Path, kernel android.Path) android.Path { 320*333d2b36SAndroid Build Coastguard Worker output := android.PathForModuleOut(ctx, b.installFileName()) 321*333d2b36SAndroid Build Coastguard Worker builder := android.NewRuleBuilder(pctx, ctx) 322*333d2b36SAndroid Build Coastguard Worker builder.Command().Text("cp").Input(unsignedImage).Output(output) 323*333d2b36SAndroid Build Coastguard Worker cmd := builder.Command().BuiltTool("avbtool"). 324*333d2b36SAndroid Build Coastguard Worker Text("add_hash_footer"). 325*333d2b36SAndroid Build Coastguard Worker FlagWithInput("--image ", output) 326*333d2b36SAndroid Build Coastguard Worker 327*333d2b36SAndroid Build Coastguard Worker if b.properties.Partition_size != nil { 328*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithArg("--partition_size ", strconv.FormatInt(*b.properties.Partition_size, 10)) 329*333d2b36SAndroid Build Coastguard Worker } else { 330*333d2b36SAndroid Build Coastguard Worker cmd.Flag("--dynamic_partition_size") 331*333d2b36SAndroid Build Coastguard Worker } 332*333d2b36SAndroid Build Coastguard Worker 333*333d2b36SAndroid Build Coastguard Worker // If you don't provide a salt, avbtool will use random bytes for the salt. 334*333d2b36SAndroid Build Coastguard Worker // This is bad for determinism (cached builds and diff tests are affected), so instead, 335*333d2b36SAndroid Build Coastguard Worker // we try to provide a salt. The requirements for a salt are not very clear, one aspect of it 336*333d2b36SAndroid Build Coastguard Worker // is that if it's unpredictable, attackers trying to change the contents of a partition need 337*333d2b36SAndroid Build Coastguard Worker // to find a new hash collision every release, because the salt changed. 338*333d2b36SAndroid Build Coastguard Worker if kernel != nil { 339*333d2b36SAndroid Build Coastguard Worker cmd.Textf(`--salt $(sha256sum "%s" | cut -d " " -f 1)`, kernel.String()) 340*333d2b36SAndroid Build Coastguard Worker cmd.Implicit(kernel) 341*333d2b36SAndroid Build Coastguard Worker } else { 342*333d2b36SAndroid Build Coastguard Worker cmd.Textf(`--salt $(sha256sum "%s" "%s" | cut -d " " -f 1 | tr -d '\n')`, ctx.Config().BuildNumberFile(ctx), ctx.Config().Getenv("BUILD_DATETIME_FILE")) 343*333d2b36SAndroid Build Coastguard Worker cmd.OrderOnly(ctx.Config().BuildNumberFile(ctx)) 344*333d2b36SAndroid Build Coastguard Worker } 345*333d2b36SAndroid Build Coastguard Worker 346*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithArg("--partition_name ", b.bootImageType.String()) 347*333d2b36SAndroid Build Coastguard Worker 348*333d2b36SAndroid Build Coastguard Worker if b.properties.Avb_algorithm != nil { 349*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithArg("--algorithm ", proptools.NinjaAndShellEscape(*b.properties.Avb_algorithm)) 350*333d2b36SAndroid Build Coastguard Worker } 351*333d2b36SAndroid Build Coastguard Worker 352*333d2b36SAndroid Build Coastguard Worker if b.properties.Avb_private_key != nil { 353*333d2b36SAndroid Build Coastguard Worker key := android.PathForModuleSrc(ctx, proptools.String(b.properties.Avb_private_key)) 354*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithInput("--key ", key) 355*333d2b36SAndroid Build Coastguard Worker } 356*333d2b36SAndroid Build Coastguard Worker 357*333d2b36SAndroid Build Coastguard Worker if !b.bootImageType.isVendorBoot() { 358*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithArg("--prop ", proptools.NinjaAndShellEscape(fmt.Sprintf( 359*333d2b36SAndroid Build Coastguard Worker "com.android.build.%s.os_version:%s", b.bootImageType.String(), ctx.Config().PlatformVersionLastStable()))) 360*333d2b36SAndroid Build Coastguard Worker } 361*333d2b36SAndroid Build Coastguard Worker 362*333d2b36SAndroid Build Coastguard Worker fingerprintFile := ctx.Config().BuildFingerprintFile(ctx) 363*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithArg("--prop ", fmt.Sprintf("com.android.build.%s.fingerprint:$(cat %s)", b.bootImageType.String(), fingerprintFile.String())) 364*333d2b36SAndroid Build Coastguard Worker cmd.OrderOnly(fingerprintFile) 365*333d2b36SAndroid Build Coastguard Worker 366*333d2b36SAndroid Build Coastguard Worker if b.properties.Security_patch != nil { 367*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithArg("--prop ", proptools.NinjaAndShellEscape(fmt.Sprintf( 368*333d2b36SAndroid Build Coastguard Worker "com.android.build.%s.security_patch:%s", b.bootImageType.String(), *b.properties.Security_patch))) 369*333d2b36SAndroid Build Coastguard Worker } 370*333d2b36SAndroid Build Coastguard Worker 371*333d2b36SAndroid Build Coastguard Worker if b.properties.Avb_rollback_index != nil { 372*333d2b36SAndroid Build Coastguard Worker cmd.FlagWithArg("--rollback_index ", strconv.FormatInt(*b.properties.Avb_rollback_index, 10)) 373*333d2b36SAndroid Build Coastguard Worker } 374*333d2b36SAndroid Build Coastguard Worker 375*333d2b36SAndroid Build Coastguard Worker builder.Build("add_avb_footer", fmt.Sprintf("Adding avb footer to %s", b.BaseModuleName())) 376*333d2b36SAndroid Build Coastguard Worker return output 377*333d2b36SAndroid Build Coastguard Worker} 378*333d2b36SAndroid Build Coastguard Worker 379*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) signImage(ctx android.ModuleContext, unsignedImage android.Path) android.Path { 380*333d2b36SAndroid Build Coastguard Worker propFile, toolDeps := b.buildPropFile(ctx) 381*333d2b36SAndroid Build Coastguard Worker 382*333d2b36SAndroid Build Coastguard Worker output := android.PathForModuleOut(ctx, b.installFileName()) 383*333d2b36SAndroid Build Coastguard Worker builder := android.NewRuleBuilder(pctx, ctx) 384*333d2b36SAndroid Build Coastguard Worker builder.Command().Text("cp").Input(unsignedImage).Output(output) 385*333d2b36SAndroid Build Coastguard Worker builder.Command().BuiltTool("verity_utils"). 386*333d2b36SAndroid Build Coastguard Worker Input(propFile). 387*333d2b36SAndroid Build Coastguard Worker Implicits(toolDeps). 388*333d2b36SAndroid Build Coastguard Worker Output(output) 389*333d2b36SAndroid Build Coastguard Worker 390*333d2b36SAndroid Build Coastguard Worker builder.Build("sign_bootimg", fmt.Sprintf("Signing %s", b.BaseModuleName())) 391*333d2b36SAndroid Build Coastguard Worker return output 392*333d2b36SAndroid Build Coastguard Worker} 393*333d2b36SAndroid Build Coastguard Worker 394*333d2b36SAndroid Build Coastguard Worker// Calculates avb_salt from some input for deterministic output. 395*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) salt() string { 396*333d2b36SAndroid Build Coastguard Worker var input []string 397*333d2b36SAndroid Build Coastguard Worker input = append(input, b.properties.Cmdline...) 398*333d2b36SAndroid Build Coastguard Worker input = append(input, proptools.StringDefault(b.properties.Partition_name, b.Name())) 399*333d2b36SAndroid Build Coastguard Worker input = append(input, proptools.String(b.properties.Header_version)) 400*333d2b36SAndroid Build Coastguard Worker return sha1sum(input) 401*333d2b36SAndroid Build Coastguard Worker} 402*333d2b36SAndroid Build Coastguard Worker 403*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) buildPropFile(ctx android.ModuleContext) (android.Path, android.Paths) { 404*333d2b36SAndroid Build Coastguard Worker var sb strings.Builder 405*333d2b36SAndroid Build Coastguard Worker var deps android.Paths 406*333d2b36SAndroid Build Coastguard Worker addStr := func(name string, value string) { 407*333d2b36SAndroid Build Coastguard Worker fmt.Fprintf(&sb, "%s=%s\n", name, value) 408*333d2b36SAndroid Build Coastguard Worker } 409*333d2b36SAndroid Build Coastguard Worker addPath := func(name string, path android.Path) { 410*333d2b36SAndroid Build Coastguard Worker addStr(name, path.String()) 411*333d2b36SAndroid Build Coastguard Worker deps = append(deps, path) 412*333d2b36SAndroid Build Coastguard Worker } 413*333d2b36SAndroid Build Coastguard Worker 414*333d2b36SAndroid Build Coastguard Worker addStr("avb_hash_enable", "true") 415*333d2b36SAndroid Build Coastguard Worker addPath("avb_avbtool", ctx.Config().HostToolPath(ctx, "avbtool")) 416*333d2b36SAndroid Build Coastguard Worker algorithm := proptools.StringDefault(b.properties.Avb_algorithm, "SHA256_RSA4096") 417*333d2b36SAndroid Build Coastguard Worker addStr("avb_algorithm", algorithm) 418*333d2b36SAndroid Build Coastguard Worker key := android.PathForModuleSrc(ctx, proptools.String(b.properties.Avb_private_key)) 419*333d2b36SAndroid Build Coastguard Worker addPath("avb_key_path", key) 420*333d2b36SAndroid Build Coastguard Worker addStr("avb_add_hash_footer_args", "") // TODO(jiyong): add --rollback_index 421*333d2b36SAndroid Build Coastguard Worker partitionName := proptools.StringDefault(b.properties.Partition_name, b.Name()) 422*333d2b36SAndroid Build Coastguard Worker addStr("partition_name", partitionName) 423*333d2b36SAndroid Build Coastguard Worker addStr("avb_salt", b.salt()) 424*333d2b36SAndroid Build Coastguard Worker 425*333d2b36SAndroid Build Coastguard Worker propFile := android.PathForModuleOut(ctx, "prop") 426*333d2b36SAndroid Build Coastguard Worker android.WriteFileRule(ctx, propFile, sb.String()) 427*333d2b36SAndroid Build Coastguard Worker return propFile, deps 428*333d2b36SAndroid Build Coastguard Worker} 429*333d2b36SAndroid Build Coastguard Worker 430*333d2b36SAndroid Build Coastguard Workervar _ android.AndroidMkEntriesProvider = (*bootimg)(nil) 431*333d2b36SAndroid Build Coastguard Worker 432*333d2b36SAndroid Build Coastguard Worker// Implements android.AndroidMkEntriesProvider 433*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) AndroidMkEntries() []android.AndroidMkEntries { 434*333d2b36SAndroid Build Coastguard Worker return []android.AndroidMkEntries{android.AndroidMkEntries{ 435*333d2b36SAndroid Build Coastguard Worker Class: "ETC", 436*333d2b36SAndroid Build Coastguard Worker OutputFile: android.OptionalPathForPath(b.output), 437*333d2b36SAndroid Build Coastguard Worker ExtraEntries: []android.AndroidMkExtraEntriesFunc{ 438*333d2b36SAndroid Build Coastguard Worker func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { 439*333d2b36SAndroid Build Coastguard Worker entries.SetString("LOCAL_MODULE_PATH", b.installDir.String()) 440*333d2b36SAndroid Build Coastguard Worker entries.SetString("LOCAL_INSTALLED_MODULE_STEM", b.installFileName()) 441*333d2b36SAndroid Build Coastguard Worker }, 442*333d2b36SAndroid Build Coastguard Worker }, 443*333d2b36SAndroid Build Coastguard Worker }} 444*333d2b36SAndroid Build Coastguard Worker} 445*333d2b36SAndroid Build Coastguard Worker 446*333d2b36SAndroid Build Coastguard Workervar _ Filesystem = (*bootimg)(nil) 447*333d2b36SAndroid Build Coastguard Worker 448*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) OutputPath() android.Path { 449*333d2b36SAndroid Build Coastguard Worker return b.output 450*333d2b36SAndroid Build Coastguard Worker} 451*333d2b36SAndroid Build Coastguard Worker 452*333d2b36SAndroid Build Coastguard Workerfunc (b *bootimg) SignedOutputPath() android.Path { 453*333d2b36SAndroid Build Coastguard Worker if proptools.Bool(b.properties.Use_avb) { 454*333d2b36SAndroid Build Coastguard Worker return b.OutputPath() 455*333d2b36SAndroid Build Coastguard Worker } 456*333d2b36SAndroid Build Coastguard Worker return nil 457*333d2b36SAndroid Build Coastguard Worker} 458