Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  bootimg.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// Copyright (C) 2021 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package filesystem

import (
 "fmt"
 "strconv"
 "strings"

 "github.com/google/blueprint"
 "github.com/google/blueprint/proptools"

 "android/soong/android"
)

//go:generate go run ../../blueprint/gobtools/codegen

type bootimg struct {
 android.ModuleBase

 properties       BootimgProperties
 commonProperties CommonBootimgProperties

 output     android.Path
 installDir android.InstallPath

 bootImageType bootImageType
}

type BootimgProperties struct {
 // Set the name of the output. Defaults to <module_name>.img.
 Stem *string

 // Path to the linux kernel prebuilt file
 Kernel_prebuilt proptools.Configurable[string] `android:"replace_instead_of_append,arch_variant,path"`

 // Filesystem module that is used as ramdisk
 Ramdisk_module *string

 // Filesystem module that is used as --vendor_ramdisk_fragment for mkbootimg
 // Only supported for vendor_boot partition type.
 Ramdisk_fragment_modules []string

 // Path to the device tree blob (DTB) prebuilt file to add to this boot image
 Dtb_prebuilt *string `android:"arch_variant,path"`

 // Optional kernel commandline arguments
 Cmdline []string `android:"arch_variant"`

 // File that contains bootconfig parameters. This can be set only when `vendor_boot` is true
 // and `header_version` is greater than or equal to 4.
 Bootconfig *string `android:"arch_variant,path"`
}

// properties common between bootimg and prebuilt_bootimg module types.
type CommonBootimgProperties struct {
 // Header version number. Must be set to one of the version numbers that are currently
 // supported. Refer to
 // https://source.android.com/devices/bootloader/boot-image-header
 Header_version *string

 // Determines the specific type of boot image this module is building. Can be boot,
 // vendor_boot, vendor_kernel_boot or init_boot. Defaults to boot.
 // Refer to https://source.android.com/devices/bootloader/partitions/vendor-boot-partitions
 // for vendor_boot.
 // Refer to https://source.android.com/docs/core/architecture/partitions/generic-boot for
 // init_boot.
 Boot_image_type *string

 // The size of the partition on the device. It will be a build error if this built partition
 // image exceeds this size.
 Partition_size proptools.Configurable[int64] `android:"replace_instead_of_append"`

 // When set to true, sign the image with avbtool. Default is false.
 Use_avb *bool

 // This can either be "default", or "make_legacy". "make_legacy" will sign the boot image
 // like how build/make/core/Makefile does, to get bit-for-bit backwards compatibility. But
 // we may want to reconsider if it's necessary to have two modes in the future. The default
 // is "default"
 Avb_mode *string

 // Name of the partition stored in vbmeta desc. Defaults to the name of this module.
 Partition_name *string

 // Path to the private key that avbtool will use to sign this filesystem image.
 // TODO(jiyong): allow apex_key to be specified here
 Avb_private_key *string `android:"path_device_first"`

 // Hash and signing algorithm for avbtool. Default is SHA256_RSA4096.
 Avb_algorithm *string

 // The index used to prevent rollback of the image on device.
 Avb_rollback_index *int64

 // Rollback index location of this image. Must be 012, etc.
 Avb_rollback_index_location *int64

 // The security patch passed to as the com.android.build.<type>.security_patch avb property.
 // Replacement for the make variables BOOT_SECURITY_PATCH / INIT_BOOT_SECURITY_PATCH.
 Security_patch *string
}

type bootImageType int

const (
 unsupported bootImageType = iota
 boot
 vendorBoot
 initBoot
 vendorKernelBoot
)

func toBootImageType(ctx android.ModuleContext, bootImageType string) bootImageType {
 switch bootImageType {
 case "boot":
  return boot
 case "vendor_boot":
  return vendorBoot
 case "init_boot":
  return initBoot
 case "vendor_kernel_boot":
  return vendorKernelBoot
 default:
  ctx.ModuleErrorf("Unknown boot_image_type %s. Must be one of \"boot\", \"vendor_boot\", \"vendor_kernel_boot\", or \"init_boot\"", bootImageType)
 }
 return unsupported
}

func (b bootImageType) String() string {
 switch b {
 case boot:
  return "boot"
 case vendorBoot:
  return "vendor_boot"
 case initBoot:
  return "init_boot"
 case vendorKernelBoot:
  return "vendor_kernel_boot"
 default:
  panic("unknown boot image type")
 }
}

func (b bootImageType) isBoot() bool {
 return b == boot
}

func (b bootImageType) isVendorBoot() bool {
 return b == vendorBoot
}

func (b bootImageType) isVendorKernelBoot() bool {
 return b == vendorKernelBoot
}

func (b bootImageType) isInitBoot() bool {
 return b == initBoot
}

// bootimg is the image for the boot partition. It consists of header, kernel, ramdisk, and dtb.
func BootimgFactory() android.Module {
 module := &bootimg{}
 module.AddProperties(&module.properties, &module.commonProperties)
 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
 return module
}

type bootimgDep struct {
 blueprint.BaseDependencyTag
 kind string
}

var bootimgRamdiskDep = bootimgDep{kind: "ramdisk"}
var bootimgRamdiskFragmentDep = bootimgDep{kind: "ramdisk_fragment"}

func (b *bootimg) DepsMutator(ctx android.BottomUpMutatorContext) {
 ramdisk := proptools.String(b.properties.Ramdisk_module)
 if ramdisk != "" {
  ctx.AddDependency(ctx.Module(), bootimgRamdiskDep, ramdisk)
 }
 for _, fragment := range b.properties.Ramdisk_fragment_modules {
  ctx.AddDependency(ctx.Module(), bootimgRamdiskFragmentDep, fragment)
 }
}

func (b *bootimg) installFileName() string {
 return proptools.StringDefault(b.properties.Stem, b.BaseModuleName()+".img")
}

func (b *bootimg) partitionName() string {
 return proptools.StringDefault(b.commonProperties.Partition_name, b.BaseModuleName())
}

func (b *bootimg) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 b.bootImageType = toBootImageType(ctx, proptools.StringDefault(b.commonProperties.Boot_image_type, "boot"))
 if b.bootImageType == unsupported {
  return
 }
 if !b.bootImageType.isVendorBoot() && len(b.properties.Ramdisk_fragment_modules) > 0 {
  ctx.PropertyErrorf("ramdisk_fragment_modules", "Ramdisk_fragment_modules is only supported for vendor_boot partition type.")
 }

 kernelProp := b.properties.Kernel_prebuilt.GetOrDefault(ctx, "")
 if b.bootImageType.isVendorBoot() && kernelProp != "" {
  ctx.PropertyErrorf("kernel_prebuilt", "vendor_boot partition can't have kernel")
  return
 }
 if b.bootImageType.isBoot() && kernelProp == "" {
  ctx.PropertyErrorf("kernel_prebuilt", "boot partition must have kernel")
  return
 }

 kernelPath := b.getKernelPath(ctx)
 unsignedOutput := b.buildBootImage(ctx, kernelPath)

 output := unsignedOutput
 if proptools.Bool(b.commonProperties.Use_avb) {
  // This bootimg module supports 2 modes of avb signing. It is not clear to this author
  // why there are differences, but one of them is to match the behavior of make-built boot
  // images.
  switch proptools.StringDefault(b.commonProperties.Avb_mode, "default") {
  case "default":
   output = b.signImage(ctx, unsignedOutput)
  case "make_legacy":
   output = b.addAvbFooter(ctx, unsignedOutput, kernelPath)
  default:
   ctx.PropertyErrorf("avb_mode", `Unknown value for avb_mode, expected "default" or "make_legacy", got: %q`, *b.commonProperties.Avb_mode)
  }
 }

 b.installDir = android.PathForModuleInstall(ctx, "etc")
 ctx.InstallFile(b.installDir, b.installFileName(), output)

 ctx.SetOutputFiles([]android.Path{output}, "")
 b.output = output

 // Set the Filesystem info of the ramdisk dependency.
 // `android_device` will use this info to package `target_files.zip`
 // TODO: Move this under BootimgInfo, as is, it's easy to confuse the bootImg module for
 // the underlying ramdisk module.
 if ramdisk := proptools.String(b.properties.Ramdisk_module); ramdisk != "" {
  ramdiskModule := ctx.GetDirectDepProxyWithTag(ramdisk, bootimgRamdiskDep)
  fsInfo, _ := android.OtherModuleProvider(ctx, ramdiskModule, FilesystemProvider)
  android.SetProvider(ctx, FilesystemProvider, fsInfo)
 } else {
  setCommonFilesystemInfo(ctx, b)
 }

 // Set BootimgInfo for building target_files.zip
 dtbPath := b.getDtbPath(ctx)
 android.SetProvider(ctx, BootimgInfoProvider, BootimgInfo{
  Type:                b.bootImageType,
  Cmdline:             b.properties.Cmdline,
  Kernel:              kernelPath,
  Dtb:                 dtbPath,
  Bootconfig:          b.getBootconfigPath(ctx),
  Output:              output,
  SignedOutput:        b.SignedOutputPath(),
  PropFileForMiscInfo: b.buildPropFileForMiscInfo(ctx),
  HeaderVersion:       proptools.String(b.commonProperties.Header_version),
 })

 extractedPublicKey := android.PathForModuleOut(ctx, b.partitionName()+".avbpubkey")
 if b.commonProperties.Avb_private_key != nil {
  key := android.PathForModuleSrc(ctx, proptools.String(b.commonProperties.Avb_private_key))
  ctx.Build(pctx, android.BuildParams{
   Rule:   extractPublicKeyRule,
   Input:  key,
   Output: extractedPublicKey,
  })
 }
 var ril int
 if b.commonProperties.Avb_rollback_index_location != nil {
  ril = proptools.Int(b.commonProperties.Avb_rollback_index_location)
 }

 android.SetProvider(ctx, vbmetaPartitionProvider, vbmetaPartitionInfo{
  Name:                  b.partitionName(),
  RollbackIndexLocation: ril,
  PublicKey:             extractedPublicKey,
  Output:                output,
 })

 // Dump compliance metadata
 complianceMetadataInfo := ctx.ComplianceMetadataInfo()
 prebuiltFilesCopied := make([]string, 0)
 if kernelPath != nil {
  prebuiltFilesCopied = append(prebuiltFilesCopied, kernelPath.String()+":kernel")
 }
 if dtbPath != nil {
  prebuiltFilesCopied = append(prebuiltFilesCopied, dtbPath.String()+":dtb.img")
 }
 complianceMetadataInfo.SetPrebuiltFilesCopied(prebuiltFilesCopied)

 if ramdisk := proptools.String(b.properties.Ramdisk_module); ramdisk != "" {
  buildComplianceMetadata(ctx, bootimgRamdiskDep)
 }
}

var BootimgInfoProvider = blueprint.NewProvider[BootimgInfo]()

// @auto-generate: gob
type BootimgInfo struct {
 Type                bootImageType
 Cmdline             []string
 Kernel              android.Path
 Dtb                 android.Path
 Bootconfig          android.Path
 Output              android.Path
 SignedOutput        android.Path
 PropFileForMiscInfo android.Path
 HeaderVersion       string
 IsPrebuilt          bool
}

// @auto-generate: gob
type ramdiskFragmentInfo struct {
 // Path to the vendor ramdisk fragment.
 // Will be used as --vendor_ramdisk_fragment
 Output android.Path

 // Name of the ramdisk fragment.
 // Will be used as --ramdisk_name
 Ramdisk_name string

 // The root staging directory of the filesystem.
 RootDir android.Path
}

// @auto-generate: gob
type ramdiskFragmentsInfo []ramdiskFragmentInfo

var ramdiskFragmentInfoProvider = blueprint.NewProvider[ramdiskFragmentInfo]()
var ramdiskFragmentsInfoProvider = blueprint.NewProvider[ramdiskFragmentsInfo]()

func (b *bootimg) getKernelPath(ctx android.ModuleContext) android.Path {
 var kernelPath android.Path
 kernelName := b.properties.Kernel_prebuilt.GetOrDefault(ctx, "")
 if kernelName != "" {
  kernelPath = android.PathForModuleSrc(ctx, kernelName)
 }
 return kernelPath
}

func (b *bootimg) getDtbPath(ctx android.ModuleContext) android.Path {
 var dtbPath android.Path
 dtbName := proptools.String(b.properties.Dtb_prebuilt)
 if dtbName != "" {
  dtbPath = android.PathForModuleSrc(ctx, dtbName)
 }
 return dtbPath
}

func (b *bootimg) getBootconfigPath(ctx android.ModuleContext) android.Path {
 var bootconfigPath android.Path
 bootconfigName := proptools.String(b.properties.Bootconfig)
 if bootconfigName != "" {
  bootconfigPath = android.PathForModuleSrc(ctx, bootconfigName)
 }
 return bootconfigPath
}

func (b *bootimg) buildBootImage(ctx android.ModuleContext, kernel android.Path) android.Path {
 output := android.PathForModuleOut(ctx, "unsigned", b.installFileName())

 builder := android.NewRuleBuilder(pctx, ctx).SandboxDisabled()
 cmd := builder.Command().BuiltTool("mkbootimg")

 if kernel != nil {
  cmd.FlagWithInput("--kernel ", kernel)
 }

 // These arguments are passed for boot.img and init_boot.img generation
 if b.bootImageType.isBoot() || b.bootImageType.isInitBoot() {
  cmd.FlagWithArg("--os_version ", ctx.Config().PlatformVersionLastStable())
  cmd.FlagWithArg("--os_patch_level ", ctx.Config().PlatformSecurityPatch())
 }

 if b.getDtbPath(ctx) != nil {
  cmd.FlagWithInput("--dtb ", b.getDtbPath(ctx))
 }

 cmdline := strings.Join(b.properties.Cmdline, " ")
 if cmdline != "" {
  flag := "--cmdline "
  if b.bootImageType.isVendorBoot() {
   flag = "--vendor_cmdline "
  }
  cmd.FlagWithArg(flag, proptools.ShellEscapeIncludingSpaces(cmdline))
 }

 headerVersion := proptools.String(b.commonProperties.Header_version)
 if headerVersion == "" {
  ctx.PropertyErrorf("header_version", "must be set")
  return output
 }
 verNum, err := strconv.Atoi(headerVersion)
 if err != nil {
  ctx.PropertyErrorf("header_version", "%q is not a number", headerVersion)
  return output
 }
 if b.bootImageType.isVendorBoot() {
  if verNum < 3 {
   ctx.PropertyErrorf("header_version", "must be 3 or higher for vendor_boot")
   return output
  }
 }

 cmd.FlagWithArg("--header_version ", headerVersion)

 ramdiskName := proptools.String(b.properties.Ramdisk_module)
 if ramdiskName != "" {
  ramdisk := ctx.GetDirectDepProxyWithTag(ramdiskName, bootimgRamdiskDep)
  if fsInfo, ok := android.OtherModuleProvider(ctx, ramdisk, FilesystemProvider); ok {
   flag := "--ramdisk "
   if b.bootImageType.isVendorBoot() || b.bootImageType.isVendorKernelBoot() {
    flag = "--vendor_ramdisk "
   }
   cmd.FlagWithInput(flag, fsInfo.Output)
  } else {
   ctx.PropertyErrorf("ramdisk", "%q is not android_filesystem module", ramdisk.Name())
   return output
  }
 }

 bootconfig := proptools.String(b.properties.Bootconfig)
 if bootconfig != "" {
  if !b.bootImageType.isVendorBoot() {
   ctx.PropertyErrorf("bootconfig", "requires vendor_boot: true")
   return output
  }
  if verNum < 4 {
   ctx.PropertyErrorf("bootconfig", "requires header_version: 4 or later")
   return output
  }
  cmd.FlagWithInput("--vendor_bootconfig ", android.PathForModuleSrc(ctx, bootconfig))
 }

 var rfi ramdiskFragmentsInfo
 for _, fragment := range b.properties.Ramdisk_fragment_modules {
  fragmentModule := ctx.GetDirectDepProxyWithTag(fragment, bootimgRamdiskFragmentDep)
  if info, exists := android.OtherModuleProvider(ctx, fragmentModule, ramdiskFragmentInfoProvider); exists {
   cmd.FlagWithArg("--ramdisk_name ", info.Ramdisk_name)
   cmd.FlagWithInput("--vendor_ramdisk_fragment ", info.Output)
   rfi = append(rfi, info)
  } else {
   ctx.ModuleErrorf("%s does not set RamdiskFragmentInfo", fragment)
  }
 }

 // Output flag for boot.img and init_boot.img
 flag := "--output "
 if b.bootImageType.isVendorBoot() || b.bootImageType.isVendorKernelBoot() {
  flag = "--vendor_boot "
 }
 cmd.FlagWithOutput(flag, output)

 if s := b.commonProperties.Partition_size.Get(ctx); s.IsPresent() {
  assertMaxImageSize(builder, output, s.Get(), proptools.Bool(b.commonProperties.Use_avb))
 }

 android.SetProvider(ctx, ramdiskFragmentsInfoProvider, rfi)

 builder.Build("build_bootimg", fmt.Sprintf("Creating %s", b.BaseModuleName()))
 return output
}

func (b *bootimg) addAvbFooter(ctx android.ModuleContext, unsignedImage android.Path, kernel android.Path) android.Path {
 output := android.PathForModuleOut(ctx, b.installFileName())
 builder := android.NewRuleBuilder(pctx, ctx).SandboxDisabled()
 builder.Command().Text("cp").Input(unsignedImage).Output(output)
 cmd := builder.Command().BuiltTool("avbtool").
  Text("add_hash_footer").
  FlagWithInput("--image ", output)

 if s := b.commonProperties.Partition_size.Get(ctx); s.IsPresent() {
  cmd.FlagWithArg("--partition_size ", strconv.FormatInt(s.Get(), 10))
 } else {
  cmd.Flag("--dynamic_partition_size")
 }

 // If you don't provide a salt, avbtool will use random bytes for the salt.
 // This is bad for determinism (cached builds and diff tests are affected), so instead,
 // we try to provide a salt. The requirements for a salt are not very clear, one aspect of it
 // is that if it's unpredictable, attackers trying to change the contents of a partition need
 // to find a new hash collision every release, because the salt changed.
 if kernel != nil {
  cmd.Textf(`--salt $(sha256sum "%s" | cut -d " " -f 1)`, kernel.String())
  cmd.Implicit(kernel)
 } else {
  cmd.Textf(`--salt $(sha256sum "%s" "%s" | cut -d " " -f 1 | tr -d '\n')`, ctx.Config().BuildNumberFile(ctx), ctx.Config().BuildDateFile(ctx))
  cmd.OrderOnly(ctx.Config().BuildNumberFile(ctx))
  cmd.OrderOnly(ctx.Config().BuildDateFile(ctx))
 }

 cmd.FlagWithArg("--partition_name ", b.bootImageType.String())

 if b.commonProperties.Avb_algorithm != nil {
  cmd.FlagWithArg("--algorithm ", proptools.NinjaAndShellEscape(*b.commonProperties.Avb_algorithm))
 }

 if b.commonProperties.Avb_private_key != nil {
  key := android.PathForModuleSrc(ctx, proptools.String(b.commonProperties.Avb_private_key))
  cmd.FlagWithInput("--key ", key)
 }

 if !b.bootImageType.isVendorBoot() && !b.bootImageType.isVendorKernelBoot() {
  cmd.FlagWithArg("--prop ", proptools.NinjaAndShellEscape(fmt.Sprintf(
   "com.android.build.%s.os_version:%s", b.bootImageType.String(), ctx.Config().PlatformVersionLastStable())))
 }

 fingerprintFile := ctx.Config().BuildFingerprintFile(ctx)
 cmd.FlagWithArg("--prop ", fmt.Sprintf("com.android.build.%s.fingerprint:$(cat %s)", b.bootImageType.String(), fingerprintFile.String()))
 cmd.Implicit(fingerprintFile)

 if b.commonProperties.Security_patch != nil {
  cmd.FlagWithArg("--prop ", proptools.NinjaAndShellEscape(fmt.Sprintf(
   "com.android.build.%s.security_patch:%s", b.bootImageType.String(), *b.commonProperties.Security_patch)))
 }

 if b.commonProperties.Avb_rollback_index != nil {
  cmd.FlagWithArg("--rollback_index ", strconv.FormatInt(*b.commonProperties.Avb_rollback_index, 10))
 }

 builder.Build("add_avb_footer", fmt.Sprintf("Adding avb footer to %s", b.BaseModuleName()))
 return output
}

func (b *bootimg) signImage(ctx android.ModuleContext, unsignedImage android.Path) android.Path {
 propFile, toolDeps := b.buildPropFile(ctx)

 output := android.PathForModuleOut(ctx, b.installFileName())
 builder := android.NewRuleBuilder(pctx, ctx).SandboxDisabled()
 builder.Command().Text("cp").Input(unsignedImage).Output(output)
 builder.Command().BuiltTool("verity_utils").
  Input(propFile).
  Implicits(toolDeps).
  Output(output)

 builder.Build("sign_bootimg", fmt.Sprintf("Signing %s", b.BaseModuleName()))
 return output
}

func (b *bootimg) buildPropFile(ctx android.ModuleContext) (android.Path, android.Paths) {
 var sb strings.Builder
 var deps android.Paths
 addStr := func(name string, value string) {
  fmt.Fprintf(&sb, "%s=%s\n", name, value)
 }
 addPath := func(name string, path android.Path) {
  addStr(name, path.String())
  deps = append(deps, path)
 }

 addStr("avb_hash_enable", "true")
 addPath("avb_avbtool", ctx.Config().HostToolPath(ctx, "avbtool"))
 algorithm := proptools.StringDefault(b.commonProperties.Avb_algorithm, "SHA256_RSA4096")
 addStr("avb_algorithm", algorithm)
 key := android.PathForModuleSrc(ctx, proptools.String(b.commonProperties.Avb_private_key))
 addPath("avb_key_path", key)
 addStr("avb_add_hash_footer_args", "") // TODO(jiyong): add --rollback_index
 partitionName := proptools.StringDefault(b.commonProperties.Partition_name, b.Name())
 addStr("partition_name", partitionName)

 propFile := android.PathForModuleOut(ctx, "prop")
 android.WriteFileRule(ctx, propFile, sb.String())
 return propFile, deps
}

func (b *bootimg) getAvbHashFooterArgs(ctx android.ModuleContext) (string, android.Paths) {
 var deps android.Paths
 ret := ""
 if !b.bootImageType.isVendorBoot() && !b.bootImageType.isVendorKernelBoot() {
  ret += "--prop " + fmt.Sprintf("com.android.build.%s.os_version:%s", b.bootImageType.String(), ctx.Config().PlatformVersionLastStable())
 }

 fingerprintFile := ctx.Config().BuildFingerprintFile(ctx)
 ret += " --prop " + fmt.Sprintf("com.android.build.%s.fingerprint:{CONTENTS_OF:%s}", b.bootImageType.String(), fingerprintFile.String())
 deps = append(deps, fingerprintFile)

 if b.commonProperties.Security_patch != nil {
  ret += " --prop " + fmt.Sprintf("com.android.build.%s.security_patch:%s", b.bootImageType.String(), *b.commonProperties.Security_patch)
 }

 if b.commonProperties.Avb_rollback_index != nil {
  ret += " --rollback_index " + strconv.FormatInt(*b.commonProperties.Avb_rollback_index10)
 }
 return strings.TrimSpace(ret), deps
}

func (b *bootimg) buildPropFileForMiscInfo(ctx android.ModuleContext) android.Path {
 var sb strings.Builder
 addStr := func(name string, value string) {
  fmt.Fprintf(&sb, "%s=%s\n", name, value)
 }

 footerArgs, footerArgsDeps := b.getAvbHashFooterArgs(ctx)

 bootImgType := proptools.String(b.commonProperties.Boot_image_type)
 addStr("avb_"+bootImgType+"_add_hash_footer_args", footerArgs)
 if ramdisk := proptools.String(b.properties.Ramdisk_module); ramdisk != "" {
  ramdiskModule := ctx.GetDirectDepProxyWithTag(ramdisk, bootimgRamdiskDep)
  fsInfo, _ := android.OtherModuleProvider(ctx, ramdiskModule, FilesystemProvider)
  if fsInfo.HasOrIsRecovery {
   // Create a dup entry for recovery
   addStr("avb_recovery_add_hash_footer_args", strings.ReplaceAll(footerArgs, bootImgType, "recovery"))
  }
 }
 if b.commonProperties.Avb_private_key != nil {
  addStr("avb_"+bootImgType+"_algorithm", proptools.StringDefault(b.commonProperties.Avb_algorithm, "SHA256_RSA4096"))
  addStr("avb_"+bootImgType+"_key_path", android.PathForModuleSrc(ctx, proptools.String(b.commonProperties.Avb_private_key)).String())
  addStr("avb_"+bootImgType+"_rollback_index_location", strconv.Itoa(proptools.Int(b.commonProperties.Avb_rollback_index_location)))
 }
 if s := b.commonProperties.Partition_size.Get(ctx); s.IsPresent() {
  addStr(bootImgType+"_size", strconv.FormatInt(s.Get(), 10))
 }
 if bootImgType != "boot" {
  addStr(bootImgType, "true")
 }

 propFilePreProcessing := android.PathForModuleOut(ctx, "prop_for_misc_info_pre_processing")
 android.WriteFileRuleVerbatim(ctx, propFilePreProcessing, sb.String())
 propFile := android.PathForModuleOut(ctx, "prop_file_for_misc_info")
 ctx.Build(pctx, android.BuildParams{
  Rule:      textFileProcessorRule,
  Input:     propFilePreProcessing,
  Output:    propFile,
  Implicits: footerArgsDeps,
 })

 return propFile
}

var _ android.AndroidMkEntriesProvider = (*bootimg)(nil)

// Implements android.AndroidMkEntriesProvider
func (b *bootimg) AndroidMkEntries() []android.AndroidMkEntries {
 return []android.AndroidMkEntries{android.AndroidMkEntries{
  Class:      "ETC",
  OutputFile: android.OptionalPathForPath(b.output),
  ExtraEntries: []android.AndroidMkExtraEntriesFunc{
   func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) {
    entries.SetString("LOCAL_MODULE_PATH", b.installDir.String())
    entries.SetString("LOCAL_INSTALLED_MODULE_STEM", b.installFileName())
   },
  },
 }}
}

var _ Filesystem = (*bootimg)(nil)

func (b *bootimg) OutputPath() android.Path {
 return b.output
}

func (b *bootimg) SignedOutputPath() android.Path {
 if proptools.Bool(b.commonProperties.Use_avb) {
  return b.OutputPath()
 }
 return nil
}

type prebuiltBootImg struct {
 android.ModuleBase

 properties       PrebuiltBootImgProperties
 commonProperties CommonBootimgProperties

 bootImageType bootImageType
 output        android.Path
}

type PrebuiltBootImgProperties struct {
 // Path to the prebuilt boot img file
 Src *string `android:"arch_variant,path"`
}

var _ Filesystem = (*prebuiltBootImg)(nil)

func (b *prebuiltBootImg) OutputPath() android.Path {
 return b.output
}

func (b *prebuiltBootImg) SignedOutputPath() android.Path {
 if proptools.Bool(b.commonProperties.Use_avb) {
  return b.OutputPath()
 }
 return nil
}

func PrebuiltBootimgFactory() android.Module {
 module := &prebuiltBootImg{}
 module.AddProperties(&module.properties, &module.commonProperties)
 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
 return module
}

func (b *prebuiltBootImg) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 b.bootImageType = toBootImageType(ctx, proptools.StringDefault(b.commonProperties.Boot_image_type, "boot"))
 if b.bootImageType == unsupported {
  return
 }

 src := android.PathForModuleSrc(ctx, proptools.String(b.properties.Src))
 b.output = src
 var kernelPath android.Path
 if proptools.Bool(b.commonProperties.Use_avb) {
  b.output, kernelPath = b.signWithAvb(ctx, src)
 }
 installDir := android.PathForModuleInstall(ctx, "etc")
 ctx.InstallFile(installDir, src.Base(), b.output)

 ctx.SetOutputFiles([]android.Path{b.output}, "")

 android.SetProvider(ctx, BootimgInfoProvider, BootimgInfo{
  Type:                b.bootImageType,
  Output:              b.output,
  SignedOutput:        b.SignedOutputPath(),
  PropFileForMiscInfo: b.buildPropFileForMiscInfo(ctx),
  HeaderVersion:       proptools.String(b.commonProperties.Header_version),
  Kernel:              kernelPath,
  IsPrebuilt:          true,
 })

 extractedPublicKey := android.PathForModuleOut(ctx, b.bootImageType.String()+".avbpubkey")
 if b.commonProperties.Avb_private_key != nil {
  key := android.PathForModuleSrc(ctx, proptools.String(b.commonProperties.Avb_private_key))
  ctx.Build(pctx, android.BuildParams{
   Rule:   extractPublicKeyRule,
   Input:  key,
   Output: extractedPublicKey,
  })
 }
 var ril int
 if b.commonProperties.Avb_rollback_index_location != nil {
  ril = proptools.Int(b.commonProperties.Avb_rollback_index_location)
 }

 android.SetProvider(ctx, vbmetaPartitionProvider, vbmetaPartitionInfo{
  Name:                  b.bootImageType.String(),
  RollbackIndexLocation: ril,
  PublicKey:             extractedPublicKey,
  Output:                b.output,
 })
}

// Unpacks the kernel from a prebuilt *_boot.img and uses it as salt for add_hash_footer.
// Returns the signed *_boot.img and unpacked kernel.
func (b *prebuiltBootImg) signWithAvb(ctx android.ModuleContext, src android.Path) (android.Path, android.Path) {
 signed := android.PathForModuleOut(ctx, "avb", src.Base())
 unpackDir := android.PathForModuleOut(ctx, "avb", "unpack")
 kernel := unpackDir.Join(ctx, "kernel")

 builder := android.NewRuleBuilder(pctx, ctx).SandboxDisabled()
 builder.Command().Text("cp").Input(src).Output(signed)

 builder.Command().
  BuiltTool("unpack_bootimg").
  FlagWithInput("--boot_img ", src).
  FlagWithArg("--out ", unpackDir.String()).
  ImplicitOutput(kernel)

 cmd := builder.Command()
 cmd.BuiltTool("avbtool").
  Flag("add_hash_footer").
  FlagWithArg("--image ", signed.String()).
  Textf(`--salt $(sha256sum "%s" | cut -d " " -f 1)`, unpackDir.Join(ctx, "kernel")).
  FlagWithArg("--partition_name ", b.bootImageType.String())

 if s := b.commonProperties.Partition_size.Get(ctx); s.IsPresent() {
  cmd.FlagWithArg("--partition_size ", strconv.FormatInt(s.Get(), 10))
 } else {
  cmd.Flag("--dynamic_partition_size")
 }

 if b.commonProperties.Avb_algorithm != nil {
  cmd.FlagWithArg("--algorithm ", proptools.NinjaAndShellEscape(*b.commonProperties.Avb_algorithm))
 }

 if b.commonProperties.Avb_private_key != nil {
  key := android.PathForModuleSrc(ctx, proptools.String(b.commonProperties.Avb_private_key))
  cmd.FlagWithInput("--key ", key)
 }

 if !b.bootImageType.isVendorBoot() && !b.bootImageType.isVendorKernelBoot() {
  cmd.FlagWithArg("--prop ", proptools.NinjaAndShellEscape(fmt.Sprintf(
   "com.android.build.%s.os_version:%s", b.bootImageType.String(), ctx.Config().PlatformVersionLastStable())))
 }

 fingerprintFile := ctx.Config().BuildFingerprintFile(ctx)
 cmd.FlagWithArg("--prop ", fmt.Sprintf("com.android.build.%s.fingerprint:$(cat %s)", b.bootImageType.String(), fingerprintFile.String()))
 cmd.Implicit(fingerprintFile)

 if b.commonProperties.Security_patch != nil {
  cmd.FlagWithArg("--prop ", proptools.NinjaAndShellEscape(fmt.Sprintf(
   "com.android.build.%s.security_patch:%s", b.bootImageType.String(), *b.commonProperties.Security_patch)))
 }

 if b.commonProperties.Avb_rollback_index != nil {
  cmd.FlagWithArg("--rollback_index ", strconv.FormatInt(*b.commonProperties.Avb_rollback_index, 10))
 }

 builder.Build("unpack_and_sign", "unpack_and_sign")

 return signed, kernel
}

func (b *prebuiltBootImg) buildPropFileForMiscInfo(ctx android.ModuleContext) android.Path {
 var sb strings.Builder
 addStr := func(name string, value string) {
  fmt.Fprintf(&sb, "%s=%s\n", name, value)
 }
 footerArgs, footerArgDeps := b.getAvbHashFooterArgs(ctx)
 bootImgType := proptools.String(b.commonProperties.Boot_image_type)
 addStr("avb_"+bootImgType+"_add_hash_footer_args", footerArgs)
 if b.commonProperties.Avb_private_key != nil {
  addStr("avb_"+bootImgType+"_algorithm", proptools.StringDefault(b.commonProperties.Avb_algorithm, "SHA256_RSA4096"))
  addStr("avb_"+bootImgType+"_key_path", android.PathForModuleSrc(ctx, proptools.String(b.commonProperties.Avb_private_key)).String())
  addStr("avb_"+bootImgType+"_rollback_index_location", strconv.Itoa(proptools.Int(b.commonProperties.Avb_rollback_index_location)))
 }
 if s := b.commonProperties.Partition_size.Get(ctx); s.IsPresent() {
  addStr(bootImgType+"_size", strconv.FormatInt(s.Get(), 10))
 }
 addStr("boot_images", bootImgType+".img")

 propFilePreProcessing := android.PathForModuleOut(ctx, "prop_for_misc_info_pre_processing")
 android.WriteFileRuleVerbatim(ctx, propFilePreProcessing, sb.String())
 propFile := android.PathForModuleOut(ctx, "prop_file_for_misc_info")
 ctx.Build(pctx, android.BuildParams{
  Rule:      textFileProcessorRule,
  Input:     propFilePreProcessing,
  Output:    propFile,
  Implicits: footerArgDeps,
 })

 return propFile
}

func (b *prebuiltBootImg) getAvbHashFooterArgs(ctx android.ModuleContext) (string, android.Paths) {
 var deps android.Paths
 ret := ""
 bootImgType := proptools.String(b.commonProperties.Boot_image_type)
 if bootImgType != "vendor_boot" {
  ret += "--prop " + fmt.Sprintf("com.android.build.%s.os_version:%s", bootImgType, ctx.Config().PlatformVersionLastStable())
 }

 fingerprintFile := ctx.Config().BuildFingerprintFile(ctx)
 ret += " --prop " + fmt.Sprintf("com.android.build.%s.fingerprint:{CONTENTS_OF:%s}", bootImgType, fingerprintFile.String())
 deps = append(deps, fingerprintFile)

 if b.commonProperties.Security_patch != nil {
  ret += " --prop " + fmt.Sprintf("com.android.build.%s.security_patch:%s", bootImgType, *b.commonProperties.Security_patch)
 }

 if b.commonProperties.Avb_rollback_index != nil {
  ret += " --rollback_index " + strconv.FormatInt(*b.commonProperties.Avb_rollback_index10)
 }
 return strings.TrimSpace(ret), deps
}

[Dauer der Verarbeitung: 0.27 Sekunden, vorverarbeitet 2026-06-28]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik