| Jiyong Park | 6446b62 | 2021-02-01 20:08:28 +0900 | [diff] [blame] | 1 | // 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 |  | 
 | 15 | package kernel | 
 | 16 |  | 
 | 17 | import ( | 
 | 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 |  | 
 | 29 | func init() { | 
| Jiyong Park | 6446b62 | 2021-02-01 20:08:28 +0900 | [diff] [blame] | 30 | 	pctx.Import("android/soong/cc/config") | 
| Paul Duffin | e5ac250 | 2021-03-29 01:24:49 +0100 | [diff] [blame] | 31 | 	registerKernelBuildComponents(android.InitRegistrationContext) | 
 | 32 | } | 
 | 33 |  | 
 | 34 | func registerKernelBuildComponents(ctx android.RegistrationContext) { | 
 | 35 | 	ctx.RegisterModuleType("prebuilt_kernel_modules", prebuiltKernelModulesFactory) | 
| Jiyong Park | 6446b62 | 2021-02-01 20:08:28 +0900 | [diff] [blame] | 36 | } | 
 | 37 |  | 
 | 38 | type prebuiltKernelModules struct { | 
 | 39 | 	android.ModuleBase | 
 | 40 |  | 
 | 41 | 	properties prebuiltKernelModulesProperties | 
 | 42 |  | 
 | 43 | 	installDir android.InstallPath | 
 | 44 | } | 
 | 45 |  | 
 | 46 | type prebuiltKernelModulesProperties struct { | 
 | 47 | 	// List or filegroup of prebuilt kernel module files. Should have .ko suffix. | 
 | 48 | 	Srcs []string `android:"path,arch_variant"` | 
 | 49 |  | 
 | 50 | 	// Kernel version that these modules are for. Kernel modules are installed to | 
 | 51 | 	// /lib/modules/<kernel_version> directory in the corresponding partition. Default is "". | 
 | 52 | 	Kernel_version *string | 
| Inseob Kim | 6a463f8 | 2023-11-06 18:07:13 +0900 | [diff] [blame] | 53 |  | 
 | 54 | 	// Whether this module is directly installable to one of the partitions. Default is true | 
 | 55 | 	Installable *bool | 
| Jiyong Park | 6446b62 | 2021-02-01 20:08:28 +0900 | [diff] [blame] | 56 | } | 
 | 57 |  | 
 | 58 | // prebuilt_kernel_modules installs a set of prebuilt kernel module files to the correct directory. | 
 | 59 | // In addition, this module builds modules.load, modules.dep, modules.softdep and modules.alias | 
 | 60 | // using depmod and installs them as well. | 
 | 61 | func prebuiltKernelModulesFactory() android.Module { | 
 | 62 | 	module := &prebuiltKernelModules{} | 
 | 63 | 	module.AddProperties(&module.properties) | 
 | 64 | 	android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) | 
 | 65 | 	return module | 
 | 66 | } | 
 | 67 |  | 
| Inseob Kim | 6a463f8 | 2023-11-06 18:07:13 +0900 | [diff] [blame] | 68 | func (pkm *prebuiltKernelModules) installable() bool { | 
 | 69 | 	return proptools.BoolDefault(pkm.properties.Installable, true) | 
 | 70 | } | 
 | 71 |  | 
| Jiyong Park | 6446b62 | 2021-02-01 20:08:28 +0900 | [diff] [blame] | 72 | func (pkm *prebuiltKernelModules) KernelVersion() string { | 
 | 73 | 	return proptools.StringDefault(pkm.properties.Kernel_version, "") | 
 | 74 | } | 
 | 75 |  | 
 | 76 | func (pkm *prebuiltKernelModules) DepsMutator(ctx android.BottomUpMutatorContext) { | 
 | 77 | 	// do nothing | 
 | 78 | } | 
 | 79 |  | 
 | 80 | func (pkm *prebuiltKernelModules) GenerateAndroidBuildActions(ctx android.ModuleContext) { | 
| Inseob Kim | 6a463f8 | 2023-11-06 18:07:13 +0900 | [diff] [blame] | 81 | 	if !pkm.installable() { | 
 | 82 | 		pkm.SkipInstall() | 
 | 83 | 	} | 
| Jiyong Park | 6446b62 | 2021-02-01 20:08:28 +0900 | [diff] [blame] | 84 | 	modules := android.PathsForModuleSrc(ctx, pkm.properties.Srcs) | 
 | 85 |  | 
 | 86 | 	depmodOut := runDepmod(ctx, modules) | 
 | 87 | 	strippedModules := stripDebugSymbols(ctx, modules) | 
 | 88 |  | 
| Jiyong Park | 599992b | 2021-02-04 19:40:56 +0900 | [diff] [blame] | 89 | 	installDir := android.PathForModuleInstall(ctx, "lib", "modules") | 
| Jiyong Park | 6446b62 | 2021-02-01 20:08:28 +0900 | [diff] [blame] | 90 | 	if pkm.KernelVersion() != "" { | 
 | 91 | 		installDir = installDir.Join(ctx, pkm.KernelVersion()) | 
 | 92 | 	} | 
 | 93 |  | 
 | 94 | 	for _, m := range strippedModules { | 
 | 95 | 		ctx.InstallFile(installDir, filepath.Base(m.String()), m) | 
 | 96 | 	} | 
 | 97 | 	ctx.InstallFile(installDir, "modules.load", depmodOut.modulesLoad) | 
 | 98 | 	ctx.InstallFile(installDir, "modules.dep", depmodOut.modulesDep) | 
 | 99 | 	ctx.InstallFile(installDir, "modules.softdep", depmodOut.modulesSoftdep) | 
 | 100 | 	ctx.InstallFile(installDir, "modules.alias", depmodOut.modulesAlias) | 
 | 101 | } | 
 | 102 |  | 
 | 103 | var ( | 
 | 104 | 	pctx = android.NewPackageContext("android/soong/kernel") | 
 | 105 |  | 
 | 106 | 	stripRule = pctx.AndroidStaticRule("strip", | 
 | 107 | 		blueprint.RuleParams{ | 
 | 108 | 			Command:     "$stripCmd -o $out --strip-debug $in", | 
 | 109 | 			CommandDeps: []string{"$stripCmd"}, | 
 | 110 | 		}, "stripCmd") | 
 | 111 | ) | 
 | 112 |  | 
 | 113 | func stripDebugSymbols(ctx android.ModuleContext, modules android.Paths) android.OutputPaths { | 
 | 114 | 	dir := android.PathForModuleOut(ctx, "stripped").OutputPath | 
 | 115 | 	var outputs android.OutputPaths | 
 | 116 |  | 
 | 117 | 	for _, m := range modules { | 
 | 118 | 		stripped := dir.Join(ctx, filepath.Base(m.String())) | 
 | 119 | 		ctx.Build(pctx, android.BuildParams{ | 
 | 120 | 			Rule:   stripRule, | 
 | 121 | 			Input:  m, | 
 | 122 | 			Output: stripped, | 
 | 123 | 			Args: map[string]string{ | 
 | 124 | 				"stripCmd": "${config.ClangBin}/llvm-strip", | 
 | 125 | 			}, | 
 | 126 | 		}) | 
 | 127 | 		outputs = append(outputs, stripped) | 
 | 128 | 	} | 
 | 129 |  | 
 | 130 | 	return outputs | 
 | 131 | } | 
 | 132 |  | 
 | 133 | type depmodOutputs struct { | 
 | 134 | 	modulesLoad    android.OutputPath | 
 | 135 | 	modulesDep     android.OutputPath | 
 | 136 | 	modulesSoftdep android.OutputPath | 
 | 137 | 	modulesAlias   android.OutputPath | 
 | 138 | } | 
 | 139 |  | 
 | 140 | func runDepmod(ctx android.ModuleContext, modules android.Paths) depmodOutputs { | 
 | 141 | 	baseDir := android.PathForModuleOut(ctx, "depmod").OutputPath | 
 | 142 | 	fakeVer := "0.0" // depmod demands this anyway | 
 | 143 | 	modulesDir := baseDir.Join(ctx, "lib", "modules", fakeVer) | 
 | 144 |  | 
 | 145 | 	builder := android.NewRuleBuilder(pctx, ctx) | 
 | 146 |  | 
 | 147 | 	// Copy the module files to a temporary dir | 
 | 148 | 	builder.Command().Text("rm").Flag("-rf").Text(modulesDir.String()) | 
 | 149 | 	builder.Command().Text("mkdir").Flag("-p").Text(modulesDir.String()) | 
 | 150 | 	for _, m := range modules { | 
 | 151 | 		builder.Command().Text("cp").Input(m).Text(modulesDir.String()) | 
 | 152 | 	} | 
 | 153 |  | 
 | 154 | 	// Enumerate modules to load | 
 | 155 | 	modulesLoad := modulesDir.Join(ctx, "modules.load") | 
 | 156 | 	var basenames []string | 
 | 157 | 	for _, m := range modules { | 
 | 158 | 		basenames = append(basenames, filepath.Base(m.String())) | 
 | 159 | 	} | 
 | 160 | 	builder.Command(). | 
 | 161 | 		Text("echo").Flag("\"" + strings.Join(basenames, " ") + "\""). | 
 | 162 | 		Text("|").Text("tr").Flag("\" \"").Flag("\"\\n\""). | 
 | 163 | 		Text(">").Output(modulesLoad) | 
 | 164 |  | 
 | 165 | 	// Run depmod to build modules.dep/softdep/alias files | 
 | 166 | 	modulesDep := modulesDir.Join(ctx, "modules.dep") | 
 | 167 | 	modulesSoftdep := modulesDir.Join(ctx, "modules.softdep") | 
 | 168 | 	modulesAlias := modulesDir.Join(ctx, "modules.alias") | 
 | 169 | 	builder.Command(). | 
 | 170 | 		BuiltTool("depmod"). | 
 | 171 | 		FlagWithArg("-b ", baseDir.String()). | 
 | 172 | 		Text(fakeVer). | 
 | 173 | 		ImplicitOutput(modulesDep). | 
 | 174 | 		ImplicitOutput(modulesSoftdep). | 
 | 175 | 		ImplicitOutput(modulesAlias) | 
 | 176 |  | 
 | 177 | 	builder.Build("depmod", fmt.Sprintf("depmod %s", ctx.ModuleName())) | 
 | 178 |  | 
 | 179 | 	return depmodOutputs{modulesLoad, modulesDep, modulesSoftdep, modulesAlias} | 
 | 180 | } |