diff options
Diffstat (limited to 'kernel/prebuilt_kernel_modules.go')
-rw-r--r-- | kernel/prebuilt_kernel_modules.go | 170 |
1 files changed, 170 insertions, 0 deletions
diff --git a/kernel/prebuilt_kernel_modules.go b/kernel/prebuilt_kernel_modules.go new file mode 100644 index 000000000..5bcca047e --- /dev/null +++ b/kernel/prebuilt_kernel_modules.go @@ -0,0 +1,170 @@ +// 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 kernel + +import ( + "fmt" + "path/filepath" + "strings" + + "android/soong/android" + _ "android/soong/cc/config" + + "github.com/google/blueprint" + "github.com/google/blueprint/proptools" +) + +func init() { + pctx.Import("android/soong/cc/config") + registerKernelBuildComponents(android.InitRegistrationContext) +} + +func registerKernelBuildComponents(ctx android.RegistrationContext) { + ctx.RegisterModuleType("prebuilt_kernel_modules", prebuiltKernelModulesFactory) +} + +type prebuiltKernelModules struct { + android.ModuleBase + + properties prebuiltKernelModulesProperties + + installDir android.InstallPath +} + +type prebuiltKernelModulesProperties struct { + // List or filegroup of prebuilt kernel module files. Should have .ko suffix. + Srcs []string `android:"path,arch_variant"` + + // Kernel version that these modules are for. Kernel modules are installed to + // /lib/modules/<kernel_version> directory in the corresponding partition. Default is "". + Kernel_version *string +} + +// prebuilt_kernel_modules installs a set of prebuilt kernel module files to the correct directory. +// In addition, this module builds modules.load, modules.dep, modules.softdep and modules.alias +// using depmod and installs them as well. +func prebuiltKernelModulesFactory() android.Module { + module := &prebuiltKernelModules{} + module.AddProperties(&module.properties) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) + return module +} + +func (pkm *prebuiltKernelModules) KernelVersion() string { + return proptools.StringDefault(pkm.properties.Kernel_version, "") +} + +func (pkm *prebuiltKernelModules) DepsMutator(ctx android.BottomUpMutatorContext) { + // do nothing +} + +func (pkm *prebuiltKernelModules) GenerateAndroidBuildActions(ctx android.ModuleContext) { + modules := android.PathsForModuleSrc(ctx, pkm.properties.Srcs) + + depmodOut := runDepmod(ctx, modules) + strippedModules := stripDebugSymbols(ctx, modules) + + installDir := android.PathForModuleInstall(ctx, "lib", "modules") + if pkm.KernelVersion() != "" { + installDir = installDir.Join(ctx, pkm.KernelVersion()) + } + + for _, m := range strippedModules { + ctx.InstallFile(installDir, filepath.Base(m.String()), m) + } + ctx.InstallFile(installDir, "modules.load", depmodOut.modulesLoad) + ctx.InstallFile(installDir, "modules.dep", depmodOut.modulesDep) + ctx.InstallFile(installDir, "modules.softdep", depmodOut.modulesSoftdep) + ctx.InstallFile(installDir, "modules.alias", depmodOut.modulesAlias) +} + +var ( + pctx = android.NewPackageContext("android/soong/kernel") + + stripRule = pctx.AndroidStaticRule("strip", + blueprint.RuleParams{ + Command: "$stripCmd -o $out --strip-debug $in", + CommandDeps: []string{"$stripCmd"}, + }, "stripCmd") +) + +func stripDebugSymbols(ctx android.ModuleContext, modules android.Paths) android.OutputPaths { + dir := android.PathForModuleOut(ctx, "stripped").OutputPath + var outputs android.OutputPaths + + for _, m := range modules { + stripped := dir.Join(ctx, filepath.Base(m.String())) + ctx.Build(pctx, android.BuildParams{ + Rule: stripRule, + Input: m, + Output: stripped, + Args: map[string]string{ + "stripCmd": "${config.ClangBin}/llvm-strip", + }, + }) + outputs = append(outputs, stripped) + } + + return outputs +} + +type depmodOutputs struct { + modulesLoad android.OutputPath + modulesDep android.OutputPath + modulesSoftdep android.OutputPath + modulesAlias android.OutputPath +} + +func runDepmod(ctx android.ModuleContext, modules android.Paths) depmodOutputs { + baseDir := android.PathForModuleOut(ctx, "depmod").OutputPath + fakeVer := "0.0" // depmod demands this anyway + modulesDir := baseDir.Join(ctx, "lib", "modules", fakeVer) + + builder := android.NewRuleBuilder(pctx, ctx) + + // Copy the module files to a temporary dir + builder.Command().Text("rm").Flag("-rf").Text(modulesDir.String()) + builder.Command().Text("mkdir").Flag("-p").Text(modulesDir.String()) + for _, m := range modules { + builder.Command().Text("cp").Input(m).Text(modulesDir.String()) + } + + // Enumerate modules to load + modulesLoad := modulesDir.Join(ctx, "modules.load") + var basenames []string + for _, m := range modules { + basenames = append(basenames, filepath.Base(m.String())) + } + builder.Command(). + Text("echo").Flag("\"" + strings.Join(basenames, " ") + "\""). + Text("|").Text("tr").Flag("\" \"").Flag("\"\\n\""). + Text(">").Output(modulesLoad) + + // Run depmod to build modules.dep/softdep/alias files + modulesDep := modulesDir.Join(ctx, "modules.dep") + modulesSoftdep := modulesDir.Join(ctx, "modules.softdep") + modulesAlias := modulesDir.Join(ctx, "modules.alias") + builder.Command(). + BuiltTool("depmod"). + FlagWithArg("-b ", baseDir.String()). + Text(fakeVer). + ImplicitOutput(modulesDep). + ImplicitOutput(modulesSoftdep). + ImplicitOutput(modulesAlias) + + builder.Build("depmod", fmt.Sprintf("depmod %s", ctx.ModuleName())) + + return depmodOutputs{modulesLoad, modulesDep, modulesSoftdep, modulesAlias} +} |