blob: 78a463f75e7cc7d35e33a02216ad804c262271ea [file] [log] [blame]
Jiyong Park6446b622021-02-01 20:08:28 +09001// Copyright (C) 2021 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 kernel
16
17import (
18 "fmt"
19 "path/filepath"
20 "strings"
21
22 "android/soong/android"
23 _ "android/soong/cc/config"
24
25 "github.com/google/blueprint"
26 "github.com/google/blueprint/proptools"
27)
28
29func init() {
Jiyong Park6446b622021-02-01 20:08:28 +090030 pctx.Import("android/soong/cc/config")
Paul Duffine5ac2502021-03-29 01:24:49 +010031 registerKernelBuildComponents(android.InitRegistrationContext)
32}
33
34func registerKernelBuildComponents(ctx android.RegistrationContext) {
Spandan Das5e336422024-11-01 22:31:20 +000035 ctx.RegisterModuleType("prebuilt_kernel_modules", PrebuiltKernelModulesFactory)
Jiyong Park6446b622021-02-01 20:08:28 +090036}
37
38type prebuiltKernelModules struct {
39 android.ModuleBase
40
41 properties prebuiltKernelModulesProperties
42
43 installDir android.InstallPath
44}
45
46type prebuiltKernelModulesProperties struct {
47 // List or filegroup of prebuilt kernel module files. Should have .ko suffix.
48 Srcs []string `android:"path,arch_variant"`
49
Spandan Daseb426b72024-11-08 03:26:45 +000050 // List of system_dlkm kernel modules that the local kernel modules depend on.
51 // The deps will be assembled into intermediates directory for running depmod
52 // but will not be added to the current module's installed files.
53 System_deps []string `android:"path,arch_variant"`
54
Spandan Dasad402922024-11-08 03:26:45 +000055 // If false, then srcs will not be included in modules.load.
56 // This feature is used by system_dlkm
57 Load_by_default *bool
58
Jiyong Park6446b622021-02-01 20:08:28 +090059 // Kernel version that these modules are for. Kernel modules are installed to
60 // /lib/modules/<kernel_version> directory in the corresponding partition. Default is "".
61 Kernel_version *string
Inseob Kim6a463f82023-11-06 18:07:13 +090062
63 // Whether this module is directly installable to one of the partitions. Default is true
64 Installable *bool
Jiyong Park6446b622021-02-01 20:08:28 +090065}
66
67// prebuilt_kernel_modules installs a set of prebuilt kernel module files to the correct directory.
68// In addition, this module builds modules.load, modules.dep, modules.softdep and modules.alias
69// using depmod and installs them as well.
Spandan Das5e336422024-11-01 22:31:20 +000070func PrebuiltKernelModulesFactory() android.Module {
Jiyong Park6446b622021-02-01 20:08:28 +090071 module := &prebuiltKernelModules{}
72 module.AddProperties(&module.properties)
73 android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst)
74 return module
75}
76
Inseob Kim6a463f82023-11-06 18:07:13 +090077func (pkm *prebuiltKernelModules) installable() bool {
78 return proptools.BoolDefault(pkm.properties.Installable, true)
79}
80
Jiyong Park6446b622021-02-01 20:08:28 +090081func (pkm *prebuiltKernelModules) KernelVersion() string {
82 return proptools.StringDefault(pkm.properties.Kernel_version, "")
83}
84
85func (pkm *prebuiltKernelModules) DepsMutator(ctx android.BottomUpMutatorContext) {
86 // do nothing
87}
88
89func (pkm *prebuiltKernelModules) GenerateAndroidBuildActions(ctx android.ModuleContext) {
Inseob Kim6a463f82023-11-06 18:07:13 +090090 if !pkm.installable() {
91 pkm.SkipInstall()
92 }
Spandan Daseb426b72024-11-08 03:26:45 +000093
Jiyong Park6446b622021-02-01 20:08:28 +090094 modules := android.PathsForModuleSrc(ctx, pkm.properties.Srcs)
Spandan Daseb426b72024-11-08 03:26:45 +000095 systemModules := android.PathsForModuleSrc(ctx, pkm.properties.System_deps)
Jiyong Park6446b622021-02-01 20:08:28 +090096
Spandan Dasad402922024-11-08 03:26:45 +000097 depmodOut := pkm.runDepmod(ctx, modules, systemModules)
Jiyong Park6446b622021-02-01 20:08:28 +090098 strippedModules := stripDebugSymbols(ctx, modules)
99
Jiyong Park599992b2021-02-04 19:40:56 +0900100 installDir := android.PathForModuleInstall(ctx, "lib", "modules")
Jiyong Park6446b622021-02-01 20:08:28 +0900101 if pkm.KernelVersion() != "" {
102 installDir = installDir.Join(ctx, pkm.KernelVersion())
103 }
104
105 for _, m := range strippedModules {
106 ctx.InstallFile(installDir, filepath.Base(m.String()), m)
107 }
108 ctx.InstallFile(installDir, "modules.load", depmodOut.modulesLoad)
109 ctx.InstallFile(installDir, "modules.dep", depmodOut.modulesDep)
110 ctx.InstallFile(installDir, "modules.softdep", depmodOut.modulesSoftdep)
111 ctx.InstallFile(installDir, "modules.alias", depmodOut.modulesAlias)
Spandan Daseb426b72024-11-08 03:26:45 +0000112
113 ctx.SetOutputFiles(modules, ".modules")
Jiyong Park6446b622021-02-01 20:08:28 +0900114}
115
116var (
117 pctx = android.NewPackageContext("android/soong/kernel")
118
119 stripRule = pctx.AndroidStaticRule("strip",
120 blueprint.RuleParams{
121 Command: "$stripCmd -o $out --strip-debug $in",
122 CommandDeps: []string{"$stripCmd"},
123 }, "stripCmd")
124)
125
126func stripDebugSymbols(ctx android.ModuleContext, modules android.Paths) android.OutputPaths {
127 dir := android.PathForModuleOut(ctx, "stripped").OutputPath
128 var outputs android.OutputPaths
129
130 for _, m := range modules {
131 stripped := dir.Join(ctx, filepath.Base(m.String()))
132 ctx.Build(pctx, android.BuildParams{
133 Rule: stripRule,
134 Input: m,
135 Output: stripped,
136 Args: map[string]string{
137 "stripCmd": "${config.ClangBin}/llvm-strip",
138 },
139 })
140 outputs = append(outputs, stripped)
141 }
142
143 return outputs
144}
145
146type depmodOutputs struct {
147 modulesLoad android.OutputPath
148 modulesDep android.OutputPath
149 modulesSoftdep android.OutputPath
150 modulesAlias android.OutputPath
151}
152
Spandan Daseb426b72024-11-08 03:26:45 +0000153var (
154 // system/lib/modules/foo.ko: system/lib/modules/bar.ko
155 // will be converted to
156 // /system/lib/modules/foo.ko: /system/lib/modules/bar.ko
157 addLeadingSlashToPaths = pctx.AndroidStaticRule("add_leading_slash",
158 blueprint.RuleParams{
159 Command: `sed -e 's|\([^: ]*lib/modules/[^: ]*\)|/\1|g' $in > $out`,
160 },
161 )
162)
163
164// This is the path in soong intermediates where the .ko files will be copied.
165// The layout should match the layout on device so that depmod can create meaningful modules.* files.
166func modulesDirForAndroidDlkm(ctx android.ModuleContext, modulesDir android.OutputPath, system bool) android.OutputPath {
167 if ctx.InstallInSystemDlkm() || system {
168 // The first component can be either system or system_dlkm
169 // system works because /system/lib/modules is a symlink to /system_dlkm/lib/modules.
170 // system was chosen to match the contents of the kati built modules.dep
171 return modulesDir.Join(ctx, "system", "lib", "modules")
172 } else if ctx.InstallInVendorDlkm() {
173 return modulesDir.Join(ctx, "vendor", "lib", "modules")
174 } else if ctx.InstallInOdmDlkm() {
175 return modulesDir.Join(ctx, "odm", "lib", "modules")
176 } else {
177 // not an android dlkm module.
178 return modulesDir
179 }
180}
181
Spandan Dasad402922024-11-08 03:26:45 +0000182func (pkm *prebuiltKernelModules) runDepmod(ctx android.ModuleContext, modules android.Paths, systemModules android.Paths) depmodOutputs {
Jiyong Park6446b622021-02-01 20:08:28 +0900183 baseDir := android.PathForModuleOut(ctx, "depmod").OutputPath
184 fakeVer := "0.0" // depmod demands this anyway
185 modulesDir := baseDir.Join(ctx, "lib", "modules", fakeVer)
Spandan Daseb426b72024-11-08 03:26:45 +0000186 modulesCpDir := modulesDirForAndroidDlkm(ctx, modulesDir, false)
Jiyong Park6446b622021-02-01 20:08:28 +0900187
188 builder := android.NewRuleBuilder(pctx, ctx)
189
190 // Copy the module files to a temporary dir
Spandan Daseb426b72024-11-08 03:26:45 +0000191 builder.Command().Text("rm").Flag("-rf").Text(modulesCpDir.String())
192 builder.Command().Text("mkdir").Flag("-p").Text(modulesCpDir.String())
Jiyong Park6446b622021-02-01 20:08:28 +0900193 for _, m := range modules {
Spandan Daseb426b72024-11-08 03:26:45 +0000194 builder.Command().Text("cp").Input(m).Text(modulesCpDir.String())
195 }
196
197 modulesDirForSystemDlkm := modulesDirForAndroidDlkm(ctx, modulesDir, true)
198 if len(systemModules) > 0 {
199 builder.Command().Text("mkdir").Flag("-p").Text(modulesDirForSystemDlkm.String())
200 }
201 for _, m := range systemModules {
202 builder.Command().Text("cp").Input(m).Text(modulesDirForSystemDlkm.String())
Jiyong Park6446b622021-02-01 20:08:28 +0900203 }
204
205 // Enumerate modules to load
206 modulesLoad := modulesDir.Join(ctx, "modules.load")
Spandan Dasad402922024-11-08 03:26:45 +0000207 // If Load_by_default is set to false explicitly, create an empty modules.load
208 if pkm.properties.Load_by_default != nil && !*pkm.properties.Load_by_default {
209 builder.Command().Text("rm").Flag("-rf").Text(modulesLoad.String())
210 builder.Command().Text("touch").Output(modulesLoad)
211 } else {
212 var basenames []string
213 for _, m := range modules {
214 basenames = append(basenames, filepath.Base(m.String()))
215 }
216 builder.Command().
217 Text("echo").Flag("\"" + strings.Join(basenames, " ") + "\"").
218 Text("|").Text("tr").Flag("\" \"").Flag("\"\\n\"").
219 Text(">").Output(modulesLoad)
Jiyong Park6446b622021-02-01 20:08:28 +0900220 }
Jiyong Park6446b622021-02-01 20:08:28 +0900221
222 // Run depmod to build modules.dep/softdep/alias files
223 modulesDep := modulesDir.Join(ctx, "modules.dep")
224 modulesSoftdep := modulesDir.Join(ctx, "modules.softdep")
225 modulesAlias := modulesDir.Join(ctx, "modules.alias")
Spandan Daseb426b72024-11-08 03:26:45 +0000226 builder.Command().Text("mkdir").Flag("-p").Text(modulesDir.String())
Jiyong Park6446b622021-02-01 20:08:28 +0900227 builder.Command().
228 BuiltTool("depmod").
229 FlagWithArg("-b ", baseDir.String()).
230 Text(fakeVer).
231 ImplicitOutput(modulesDep).
232 ImplicitOutput(modulesSoftdep).
233 ImplicitOutput(modulesAlias)
234
235 builder.Build("depmod", fmt.Sprintf("depmod %s", ctx.ModuleName()))
236
Spandan Daseb426b72024-11-08 03:26:45 +0000237 finalModulesDep := modulesDep
238 // Add a leading slash to paths in modules.dep of android dlkm
239 if ctx.InstallInSystemDlkm() || ctx.InstallInVendorDlkm() || ctx.InstallInOdmDlkm() {
240 finalModulesDep := modulesDep.ReplaceExtension(ctx, "intermediates")
241 ctx.Build(pctx, android.BuildParams{
242 Rule: addLeadingSlashToPaths,
243 Input: modulesDep,
244 Output: finalModulesDep,
245 })
246 }
247
248 return depmodOutputs{modulesLoad, finalModulesDep, modulesSoftdep, modulesAlias}
Jiyong Park6446b622021-02-01 20:08:28 +0900249}