blob: 4f9dc7b23bdca7fe99771afe0bb5b37c26c7b5f3 [file] [log] [blame]
Jihoon Kangf2c53982024-10-09 17:32:52 +00001// Copyright (C) 2024 The Android Open Source Project
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package filesystem
16
17import (
Spandan Das258c08f2025-01-08 23:30:45 +000018 "strings"
19
Jihoon Kangf2c53982024-10-09 17:32:52 +000020 "android/soong/android"
21
22 "github.com/google/blueprint"
23 "github.com/google/blueprint/proptools"
24)
25
26type PartitionNameProperties struct {
Jihoon Kange7e3ec82025-01-02 21:29:14 +000027 // Name of the boot partition filesystem module
Jihoon Kangf2c53982024-10-09 17:32:52 +000028 Boot_partition_name *string
Jihoon Kange7e3ec82025-01-02 21:29:14 +000029 // Name of the vendor boot partition filesystem module
30 Vendor_boot_partition_name *string
31 // Name of the init boot partition filesystem module
32 Init_boot_partition_name *string
33 // Name of the system partition filesystem module
Jihoon Kangf2c53982024-10-09 17:32:52 +000034 System_partition_name *string
Jihoon Kange7e3ec82025-01-02 21:29:14 +000035 // Name of the system_ext partition filesystem module
Jihoon Kangf2c53982024-10-09 17:32:52 +000036 System_ext_partition_name *string
Jihoon Kange7e3ec82025-01-02 21:29:14 +000037 // Name of the product partition filesystem module
Jihoon Kangf2c53982024-10-09 17:32:52 +000038 Product_partition_name *string
Jihoon Kange7e3ec82025-01-02 21:29:14 +000039 // Name of the vendor partition filesystem module
Jihoon Kangf2c53982024-10-09 17:32:52 +000040 Vendor_partition_name *string
Jihoon Kange7e3ec82025-01-02 21:29:14 +000041 // Name of the odm partition filesystem module
Spandan Dasc5717162024-11-01 18:33:57 +000042 Odm_partition_name *string
Jihoon Kange7e3ec82025-01-02 21:29:14 +000043 // Name of the recovery partition filesystem module
44 Recovery_partition_name *string
Cole Faust3552eb62024-11-06 18:07:26 -080045 // The vbmeta partition and its "chained" partitions
46 Vbmeta_partitions []string
Jihoon Kange7e3ec82025-01-02 21:29:14 +000047 // Name of the userdata partition filesystem module
mrziwang23ba8762024-11-07 16:21:53 -080048 Userdata_partition_name *string
Spandan Dasa0394002025-01-07 18:38:34 +000049 // Name of the system_dlkm partition filesystem module
50 System_dlkm_partition_name *string
51 // Name of the vendor_dlkm partition filesystem module
52 Vendor_dlkm_partition_name *string
53 // Name of the odm_dlkm partition filesystem module
54 Odm_dlkm_partition_name *string
Jihoon Kangf2c53982024-10-09 17:32:52 +000055}
56
Jihoon Kang3be17162025-01-09 20:51:54 +000057type DeviceProperties struct {
58 // Path to the prebuilt bootloader that would be copied to PRODUCT_OUT
59 Bootloader *string `android:"path"`
60}
61
Jihoon Kangf2c53982024-10-09 17:32:52 +000062type androidDevice struct {
63 android.ModuleBase
64
65 partitionProps PartitionNameProperties
Jihoon Kang3be17162025-01-09 20:51:54 +000066
67 deviceProps DeviceProperties
68
69 // copyToProductOutTimestamp for copying necessary files to PRODUCT_OUT
70 copyToProductOutTimestamp android.WritablePath
Jihoon Kangf2c53982024-10-09 17:32:52 +000071}
72
73func AndroidDeviceFactory() android.Module {
74 module := &androidDevice{}
Jihoon Kang3be17162025-01-09 20:51:54 +000075 module.AddProperties(&module.partitionProps, &module.deviceProps)
Cole Faust341d5f12025-01-07 15:32:38 -080076 android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibFirst)
Jihoon Kangf2c53982024-10-09 17:32:52 +000077 return module
78}
79
80type partitionDepTagType struct {
81 blueprint.BaseDependencyTag
82}
83
84var filesystemDepTag partitionDepTagType
85
86func (a *androidDevice) DepsMutator(ctx android.BottomUpMutatorContext) {
87 addDependencyIfDefined := func(dep *string) {
88 if dep != nil {
Cole Faust341d5f12025-01-07 15:32:38 -080089 ctx.AddDependency(ctx.Module(), filesystemDepTag, proptools.String(dep))
Jihoon Kangf2c53982024-10-09 17:32:52 +000090 }
91 }
92
93 addDependencyIfDefined(a.partitionProps.Boot_partition_name)
Jihoon Kang9e087002025-01-08 19:12:23 +000094 addDependencyIfDefined(a.partitionProps.Init_boot_partition_name)
Spandan Dasef200ac2025-01-08 01:42:45 +000095 addDependencyIfDefined(a.partitionProps.Vendor_boot_partition_name)
Jihoon Kangf2c53982024-10-09 17:32:52 +000096 addDependencyIfDefined(a.partitionProps.System_partition_name)
97 addDependencyIfDefined(a.partitionProps.System_ext_partition_name)
98 addDependencyIfDefined(a.partitionProps.Product_partition_name)
99 addDependencyIfDefined(a.partitionProps.Vendor_partition_name)
Spandan Dasc5717162024-11-01 18:33:57 +0000100 addDependencyIfDefined(a.partitionProps.Odm_partition_name)
mrziwang23ba8762024-11-07 16:21:53 -0800101 addDependencyIfDefined(a.partitionProps.Userdata_partition_name)
Spandan Dasa0394002025-01-07 18:38:34 +0000102 addDependencyIfDefined(a.partitionProps.System_dlkm_partition_name)
103 addDependencyIfDefined(a.partitionProps.Vendor_dlkm_partition_name)
104 addDependencyIfDefined(a.partitionProps.Odm_dlkm_partition_name)
Spandan Dasef200ac2025-01-08 01:42:45 +0000105 addDependencyIfDefined(a.partitionProps.Recovery_partition_name)
Cole Faust3552eb62024-11-06 18:07:26 -0800106 for _, vbmetaPartition := range a.partitionProps.Vbmeta_partitions {
107 ctx.AddDependency(ctx.Module(), filesystemDepTag, vbmetaPartition)
108 }
Jihoon Kangf2c53982024-10-09 17:32:52 +0000109}
110
Jihoon Kang3be17162025-01-09 20:51:54 +0000111func (a *androidDevice) copyToProductOut(ctx android.ModuleContext, builder *android.RuleBuilder, src android.Path, dest string) {
112 destPath := android.PathForModuleInPartitionInstall(ctx, "").Join(ctx, dest)
113 builder.Command().Text("rsync").Flag("-a").Flag("--checksum").Input(src).Text(destPath.String())
114}
115
116func (a *androidDevice) copyFilesToProductOut(ctx android.ModuleContext) {
117 a.copyToProductOutTimestamp = android.PathForModuleOut(ctx, "timestamp")
118 builder := android.NewRuleBuilder(pctx, ctx)
119 builder.Command().Text("touch").Output(a.copyToProductOutTimestamp)
120
121 // List all individual files to be copied to PRODUCT_OUT here
122 if a.deviceProps.Bootloader != nil {
123 a.copyToProductOut(ctx, builder, android.PathForModuleSrc(ctx, proptools.String(a.deviceProps.Bootloader)), "bootloader")
124 }
125
126 builder.Build("copy_to_product_out", "Copy files to PRODUCT_OUT")
127}
128
Jihoon Kangf2c53982024-10-09 17:32:52 +0000129func (a *androidDevice) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Cole Faust44080412024-12-20 14:17:07 -0800130 a.buildTargetFilesZip(ctx)
mrziwang2fd33a72025-01-08 12:22:08 -0800131 var deps []android.Path
132 ctx.VisitDirectDepsWithTag(filesystemDepTag, func(m android.Module) {
133 imageOutput, ok := android.OtherModuleProvider(ctx, m, android.OutputFilesProvider)
134 if !ok {
135 ctx.ModuleErrorf("Partition module %s doesn't set OutputfilesProvider", m.Name())
136 }
137 if len(imageOutput.DefaultOutputFiles) != 1 {
138 ctx.ModuleErrorf("Partition module %s should provide exact 1 output file", m.Name())
139 }
140 deps = append(deps, imageOutput.DefaultOutputFiles[0])
141 })
Jihoon Kang3be17162025-01-09 20:51:54 +0000142
143 a.copyFilesToProductOut(ctx)
144
mrziwang2fd33a72025-01-08 12:22:08 -0800145 out := android.PathForModuleOut(ctx, "out")
146 ctx.Build(pctx, android.BuildParams{
Jihoon Kang3be17162025-01-09 20:51:54 +0000147 Rule: android.Touch,
148 Output: out,
149 Implicits: deps,
150 Validation: a.copyToProductOutTimestamp,
mrziwang2fd33a72025-01-08 12:22:08 -0800151 })
152 ctx.SetOutputFiles(android.Paths{out}, "")
153 ctx.CheckbuildFile(out)
Cole Faust44080412024-12-20 14:17:07 -0800154}
Jihoon Kangf2c53982024-10-09 17:32:52 +0000155
Spandan Dasef200ac2025-01-08 01:42:45 +0000156type targetFilesZipCopy struct {
157 srcModule *string
158 destSubdir string
159}
160
Cole Faust44080412024-12-20 14:17:07 -0800161func (a *androidDevice) buildTargetFilesZip(ctx android.ModuleContext) {
162 targetFilesDir := android.PathForModuleOut(ctx, "target_files_dir")
163 targetFilesZip := android.PathForModuleOut(ctx, "target_files.zip")
164
165 builder := android.NewRuleBuilder(pctx, ctx)
166 builder.Command().Textf("rm -rf %s", targetFilesDir.String())
167 builder.Command().Textf("mkdir -p %s", targetFilesDir.String())
Spandan Dasef200ac2025-01-08 01:42:45 +0000168 toCopy := []targetFilesZipCopy{
169 targetFilesZipCopy{a.partitionProps.System_partition_name, "SYSTEM"},
170 targetFilesZipCopy{a.partitionProps.System_ext_partition_name, "SYSTEM_EXT"},
171 targetFilesZipCopy{a.partitionProps.Product_partition_name, "PRODUCT"},
172 targetFilesZipCopy{a.partitionProps.Vendor_partition_name, "VENDOR"},
173 targetFilesZipCopy{a.partitionProps.Odm_partition_name, "ODM"},
174 targetFilesZipCopy{a.partitionProps.System_dlkm_partition_name, "SYSTEM_DLKM"},
175 targetFilesZipCopy{a.partitionProps.Vendor_dlkm_partition_name, "VENDOR_DLKM"},
176 targetFilesZipCopy{a.partitionProps.Odm_dlkm_partition_name, "ODM_DLKM"},
177 targetFilesZipCopy{a.partitionProps.Init_boot_partition_name, "BOOT/RAMDISK"},
178 targetFilesZipCopy{a.partitionProps.Init_boot_partition_name, "INIT_BOOT/RAMDISK"},
179 targetFilesZipCopy{a.partitionProps.Vendor_boot_partition_name, "VENDOR_BOOT/RAMDISK"},
Spandan Das25649f52025-01-07 18:09:22 +0000180 }
Spandan Dasef200ac2025-01-08 01:42:45 +0000181 // TODO: Handle cases where recovery files are copied to BOOT/ or RECOVERY/
182 // https://cs.android.com/android/platform/superproject/main/+/main:build/make/core/Makefile;l=6211-6219?q=core%2FMakefile&ss=android%2Fplatform%2Fsuperproject%2Fmain
183 if ctx.DeviceConfig().BoardMoveRecoveryResourcesToVendorBoot() {
184 toCopy = append(toCopy, targetFilesZipCopy{a.partitionProps.Recovery_partition_name, "VENDOR_BOOT/RAMDISK"})
185 }
186
187 for _, zipCopy := range toCopy {
188 if zipCopy.srcModule == nil {
Spandan Das25649f52025-01-07 18:09:22 +0000189 continue
190 }
Spandan Dasef200ac2025-01-08 01:42:45 +0000191 fsInfo := a.getFilesystemInfo(ctx, *zipCopy.srcModule)
192 subdir := zipCopy.destSubdir
193 rootDirString := fsInfo.RootDir.String()
194 if subdir == "SYSTEM" {
195 rootDirString = rootDirString + "/system"
196 }
Spandan Das25649f52025-01-07 18:09:22 +0000197 builder.Command().Textf("mkdir -p %s/%s", targetFilesDir.String(), subdir)
Cole Faust44080412024-12-20 14:17:07 -0800198 builder.Command().
199 BuiltTool("acp").
Spandan Dasef200ac2025-01-08 01:42:45 +0000200 Textf("-rd %s/. %s/%s", rootDirString, targetFilesDir, subdir).
Cole Faust44080412024-12-20 14:17:07 -0800201 Implicit(fsInfo.Output) // so that the staging dir is built
Spandan Dasef200ac2025-01-08 01:42:45 +0000202
Cole Faust44080412024-12-20 14:17:07 -0800203 }
Spandan Das258c08f2025-01-08 23:30:45 +0000204 // Copy cmdline files of boot images
205 if a.partitionProps.Vendor_boot_partition_name != nil {
206 bootImg := ctx.GetDirectDepWithTag(proptools.String(a.partitionProps.Vendor_boot_partition_name), filesystemDepTag)
207 bootImgInfo, _ := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider)
208 builder.Command().Textf("echo %s > %s/%s/cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir, "VENDOR_BOOT")
209 builder.Command().Textf("echo %s > %s/%s/vendor_cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir, "VENDOR_BOOT")
210 }
211 if a.partitionProps.Boot_partition_name != nil {
212 bootImg := ctx.GetDirectDepWithTag(proptools.String(a.partitionProps.Boot_partition_name), filesystemDepTag)
213 bootImgInfo, _ := android.OtherModuleProvider(ctx, bootImg, BootimgInfoProvider)
214 builder.Command().Textf("echo %s > %s/%s/cmdline", proptools.ShellEscape(strings.Join(bootImgInfo.Cmdline, " ")), targetFilesDir, "BOOT")
215 }
216
Cole Faust44080412024-12-20 14:17:07 -0800217 builder.Command().
218 BuiltTool("soong_zip").
219 Text("-d").
220 FlagWithOutput("-o ", targetFilesZip).
221 FlagWithArg("-C ", targetFilesDir.String()).
222 FlagWithArg("-D ", targetFilesDir.String()).
223 Text("-sha256")
224 builder.Build("target_files_"+ctx.ModuleName(), "Build target_files.zip")
225}
226
227func (a *androidDevice) getFilesystemInfo(ctx android.ModuleContext, depName string) FilesystemInfo {
228 fsMod := ctx.GetDirectDepWithTag(depName, filesystemDepTag)
229 fsInfo, ok := android.OtherModuleProvider(ctx, fsMod, FilesystemProvider)
230 if !ok {
231 ctx.ModuleErrorf("Expected dependency %s to be a filesystem", depName)
232 }
233 return fsInfo
Jihoon Kangf2c53982024-10-09 17:32:52 +0000234}