Skip to content

Commit be6bf94

Browse files
Add custom kernel config overrides to build flow
1 parent eda5f7e commit be6bf94

13 files changed

Lines changed: 160 additions & 2 deletions

File tree

.github/workflows/build.yml

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ on:
8585
required: false
8686
type: string
8787
default: "off"
88+
custom_kernel_config:
89+
required: false
90+
type: string
91+
default: ""
8892

8993
# ==================== ZRAM 扩展选项 ====================
9094
zram_full_algo:
@@ -141,6 +145,8 @@ jobs:
141145

142146
steps:
143147
- name: 构建信息摘要
148+
env:
149+
CUSTOM_KERNEL_CONFIG_INPUT: ${{ inputs.custom_kernel_config || '' }}
144150
shell: bash
145151
run: |
146152
set -euo pipefail
@@ -171,6 +177,19 @@ jobs:
171177
fi
172178
fi
173179
180+
custom_kernel_config_count="$(python3 - <<'PY'
181+
import os
182+
raw = os.environ.get("CUSTOM_KERNEL_CONFIG_INPUT", "")
183+
normalized = raw.replace("\r\n", "\n").replace("\r", "\n").replace("|", "\n")
184+
count = sum(1 for line in normalized.splitlines() if line.strip())
185+
print(count)
186+
PY
187+
)"
188+
custom_kernel_config_label="无"
189+
if [ "$custom_kernel_config_count" -gt 0 ]; then
190+
custom_kernel_config_label="${custom_kernel_config_count} 项"
191+
fi
192+
174193
{
175194
echo "EFFECTIVE_USE_ZRAM=$effective_use_zram"
176195
echo "EFFECTIVE_ZRAM_FULL_ALGO=$effective_zram_full_algo"
@@ -210,6 +229,7 @@ jobs:
210229
echo "KPM 密码 : ${{ inputs.kpm_password && '已自定义' || '默认' }}"
211230
echo "Re-Kernel : ${{ inputs.use_rekernel }}"
212231
echo "虚拟化支持 : ${{ inputs.virtualization_support }}"
232+
echo "自定义内核选项: $custom_kernel_config_label"
213233
echo "自定义注入 : ${{ inputs.use_custom_external_modules }}"
214234
echo "Stock Config : 自动检测 config/stock_defconfig"
215235
echo "========================================"
@@ -2455,7 +2475,6 @@ jobs:
24552475
enable_required_config CONFIG_IPC_NS
24562476
enable_required_config CONFIG_PID_NS
24572477
enable_required_config CONFIG_DEVTMPFS
2458-
enable_required_config CONFIG_USER_NS
24592478
24602479
# 可选: 网络相关配置 (Docker/NAT 模式)
24612480
enable_config_if_defined CONFIG_NETFILTER_XT_MATCH_ADDRTYPE
@@ -5159,6 +5178,53 @@ jobs:
51595178
51605179
echo "ABK Control 管理器桥接校验通过。"
51615180
5181+
- name: 应用自定义内核选项
5182+
if: inputs.custom_kernel_config != ''
5183+
working-directory: ${{ env.KERNEL_ROOT }}
5184+
env:
5185+
CUSTOM_KERNEL_CONFIG_INPUT: ${{ inputs.custom_kernel_config }}
5186+
run: |
5187+
set -euo pipefail
5188+
python3 - <<'PY'
5189+
from pathlib import Path
5190+
import os
5191+
import re
5192+
5193+
defconfig = Path(os.environ["DEFCONFIG"])
5194+
raw = os.environ.get("CUSTOM_KERNEL_CONFIG_INPUT", "")
5195+
normalized = raw.replace("\r\n", "\n").replace("\r", "\n").replace("|", "\n")
5196+
entries = []
5197+
5198+
for raw_line in normalized.splitlines():
5199+
line = raw_line.strip()
5200+
if not line:
5201+
continue
5202+
if re.fullmatch(r"# CONFIG_[A-Za-z0-9_]+ is not set", line):
5203+
key = line[len("# "):].split(" ", 1)[0]
5204+
elif re.fullmatch(r"CONFIG_[A-Za-z0-9_]+=.+", line):
5205+
key = line.split("=", 1)[0]
5206+
else:
5207+
raise SystemExit(f"::error::非法自定义内核选项: {line}(仅支持 CONFIG_FOO=... 或 # CONFIG_BAR is not set)")
5208+
entries.append((key, line))
5209+
5210+
if not entries:
5211+
print("未解析到有效的自定义内核选项,跳过。")
5212+
raise SystemExit(0)
5213+
5214+
lines = defconfig.read_text().splitlines()
5215+
for key, line in entries:
5216+
lines = [
5217+
current for current in lines
5218+
if current != f"# {key} is not set" and not current.startswith(f"{key}=")
5219+
]
5220+
lines.append(line)
5221+
5222+
defconfig.write_text("\n".join(lines) + "\n")
5223+
print(f"已应用 {len(entries)} 项自定义内核选项到 {defconfig}")
5224+
for _, line in entries:
5225+
print(f" {line}")
5226+
PY
5227+
51625228
- name: 编译内核
51635229
uses: nick-fields/retry@v4
51645230
with:

.github/workflows/kernel-custom.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,11 @@ on:
9595
- "123"
9696
- "345"
9797
default: "off"
98+
custom_kernel_config:
99+
description: "自定义内核选项(支持多行或 | 分隔,仅支持 CONFIG_FOO=... 与 # CONFIG_BAR is not set)"
100+
required: false
101+
type: string
102+
default: ""
98103

99104
# ==================== 功能开关 ====================
100105
use_zram:
@@ -200,6 +205,7 @@ jobs:
200205
supp_op: ${{ inputs.supp_op || false }}
201206
enable_susfs: ${{ !inputs.cancel_susfs }}
202207
virtualization_support: ${{ inputs.virtualization_support || 'off' }}
208+
custom_kernel_config: ${{ inputs.custom_kernel_config || '' }}
203209
zram_full_algo: ${{ inputs.zram_full_algo || false }}
204210
zram_extra_algos: ${{ inputs.zram_extra_algos || '' }}
205211
kpm_password: ${{ inputs.kpm_password || '' }}

app/src/main/java/com/abk/kernel/data/model/KernelSupport.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,7 @@ object KernelSupport {
312312
},
313313
kpmPassword = if (isOnePlus || ksuVariant == KSU_VARIANT_NONE || !gkiKpmSupported) "" else config.kpmPassword,
314314
virtualizationSupport = if (isOnePlus) "off" else normalizeVirtualizationSupport(line.kernelVersion, config.virtualizationSupport),
315+
customKernelConfig = if (isOnePlus) "" else normalizeCustomKernelConfig(config.customKernelConfig),
315316
useCustomExternalModules = if (isOnePlus) false else config.useCustomExternalModules,
316317
customExternalModules = if (isOnePlus) {
317318
emptyList()
@@ -425,6 +426,9 @@ object KernelSupport {
425426
}
426427
}
427428

429+
private fun normalizeCustomKernelConfig(value: String): String =
430+
value.replace("\r\n", "\n").replace('\r', '\n').trim()
431+
428432
fun subLevelOptions(androidVersion: String, kernelVersion: String): List<String> =
429433
subLevels(lineFor(androidVersion, kernelVersion)) + "X"
430434

app/src/main/java/com/abk/kernel/data/model/Models.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ data class BuildParameterSummary(
129129
val kpmPassword: String = "",
130130
val reKernelEnabled: String = "",
131131
val virtualizationSupport: String = "",
132+
val customKernelConfig: String = "",
132133
val customInjection: String = "",
133134
val stockConfig: String = "",
134135
val source: String = "workflow_log",
@@ -597,6 +598,7 @@ data class KernelBuildConfig(
597598
val zramExtraAlgos: String = "",
598599
val kpmPassword: String = "",
599600
val virtualizationSupport: String = "off",
601+
val customKernelConfig: String = "",
600602
val useCustomExternalModules: Boolean = false,
601603
val customExternalModules: List<CustomExternalModule> = emptyList(),
602604
val onePlusCpu: String = "sm8650",

app/src/main/java/com/abk/kernel/ui/screens/BuildScreen.kt

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,9 @@ fun BuildScreen(
141141
val buildTimePreview = remember(context, config.buildTime) {
142142
buildTimePreview(context, config.buildTime)
143143
}
144+
val customKernelConfigEntryCount = remember(config.customKernelConfig) {
145+
countCustomKernelConfigEntries(config.customKernelConfig)
146+
}
144147
var showConfirmDialog by remember { mutableStateOf(false) }
145148
var showBuildSubmittedDialog by rememberSaveable { mutableStateOf(false) }
146149
var showSavePlanDialog by remember { mutableStateOf(false) }
@@ -1332,6 +1335,11 @@ fun BuildScreen(
13321335
options = virtualizationSupportOptions,
13331336
onSelect = { vm.updateBuildConfig(config.copy(virtualizationSupport = it)) }
13341337
)
1338+
Text(
1339+
text = stringResource(R.string.build_virtualization_userns_hint),
1340+
style = MaterialTheme.typography.bodySmall,
1341+
color = MaterialTheme.colorScheme.onSurfaceVariant
1342+
)
13351343
SwitchRow(stringResource(R.string.build_enable_oneplus_8e), config.suppOp) {
13361344
vm.updateBuildConfig(config.copy(suppOp = it))
13371345
}
@@ -1607,6 +1615,24 @@ fun BuildScreen(
16071615
singleLine = true
16081616
)
16091617
ConfigPreviewText(buildTimePreview)
1618+
OutlinedTextField(
1619+
value = config.customKernelConfig,
1620+
onValueChange = { vm.updateBuildConfig(config.copy(customKernelConfig = it)) },
1621+
label = { Text(stringResource(R.string.build_custom_kernel_config)) },
1622+
placeholder = { Text(stringResource(R.string.build_custom_kernel_config_placeholder)) },
1623+
modifier = Modifier.fillMaxWidth(),
1624+
minLines = 4,
1625+
maxLines = 8
1626+
)
1627+
Text(
1628+
text = if (customKernelConfigEntryCount > 0) {
1629+
stringResource(R.string.build_custom_kernel_config_count, customKernelConfigEntryCount)
1630+
} else {
1631+
stringResource(R.string.build_custom_kernel_config_hint)
1632+
},
1633+
style = MaterialTheme.typography.bodySmall,
1634+
color = MaterialTheme.colorScheme.onSurfaceVariant
1635+
)
16101636
}
16111637
}
16121638

@@ -2438,6 +2464,10 @@ private fun buildPlanSummary(config: KernelBuildConfig): String {
24382464
if (config.virtualizationSupport != "off") {
24392465
enabled += stringResource(R.string.build_feature_virtualization, virtualizationSupportLabel(config.virtualizationSupport))
24402466
}
2467+
val customKernelConfigEntryCount = countCustomKernelConfigEntries(config.customKernelConfig)
2468+
if (customKernelConfigEntryCount > 0) {
2469+
enabled += stringResource(R.string.build_feature_custom_kernel_config, customKernelConfigEntryCount)
2470+
}
24412471
val featureSummary = enabled.ifEmpty { listOf(stringResource(R.string.build_base_config)) }.joinToString("")
24422472
val externalModuleCount = if (config.useCustomExternalModules) config.customExternalModules.size else 0
24432473
val ksuSummary = when {
@@ -2564,6 +2594,15 @@ private fun virtualizationSupportLabel(value: String): String = when (value) {
25642594
else -> value
25652595
}
25662596

2597+
private fun countCustomKernelConfigEntries(value: String): Int =
2598+
value
2599+
.replace("\r\n", "\n")
2600+
.replace('\r', '\n')
2601+
.replace('|', '\n')
2602+
.lineSequence()
2603+
.map { it.trim() }
2604+
.count { it.isNotEmpty() }
2605+
25672606
private fun buildVersionPreview(context: Context, config: KernelBuildConfig): String {
25682607
val compact = config.version.filterNot { it.isWhitespace() }
25692608
if (compact.isBlank()) {

app/src/main/java/com/abk/kernel/ui/screens/flash/FlashDialogs.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -366,6 +366,7 @@ internal fun ParameterSummarySections(summary: BuildParameterSummary) {
366366
ParameterRow(stringResource(R.string.flash_kpm_password), summary.kpmPassword)
367367
ParameterRow("Re-Kernel", summary.reKernelEnabled)
368368
ParameterRow(stringResource(R.string.runtime_virtualization), summary.virtualizationSupport)
369+
ParameterRow(stringResource(R.string.build_custom_kernel_config), summary.customKernelConfig)
369370
ParameterRow(stringResource(R.string.flash_custom_injection), summary.customInjection)
370371
ParameterRow("Stock Config", summary.stockConfig)
371372
}
@@ -487,6 +488,7 @@ internal fun parsePrebuiltGkiParameterSummary(release: PrebuiltGkiRelease): Buil
487488
kpmPassword = values["kpmPassword"].orEmpty(),
488489
reKernelEnabled = values["reKernelEnabled"].orEmpty(),
489490
virtualizationSupport = values["virtualizationSupport"].orEmpty(),
491+
customKernelConfig = values["customKernelConfig"].orEmpty(),
490492
customInjection = values["customInjection"].orEmpty(),
491493
stockConfig = values["stockConfig"].orEmpty(),
492494
source = "release_body",
@@ -552,6 +554,7 @@ internal fun normalizeReleaseParameterLabel(label: String): String? {
552554
compact.contains("kpm密码") -> "kpmPassword"
553555
compact.contains("re-kernel") || compact.contains("rekernel") -> "reKernelEnabled"
554556
compact.contains("虚拟化支持") -> "virtualizationSupport"
557+
compact.contains("自定义内核选项") -> "customKernelConfig"
555558
compact == "自定义注入" -> "customInjection"
556559
compact.contains("stockconfig") -> "stockConfig"
557560
else -> null

app/src/main/java/com/abk/kernel/viewmodel/MainViewModel.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4703,6 +4703,7 @@ internal fun encodeBuildPlanPayload(
47034703
writer.writeString(config.zramExtraAlgos)
47044704
writer.writeString(config.kpmPassword)
47054705
writer.writeString(config.customRef)
4706+
writer.writeString(config.customKernelConfig)
47064707
val modules = if (config.useCustomExternalModules) {
47074708
config.customExternalModules
47084709
.mapNotNull { module ->
@@ -4805,6 +4806,11 @@ internal fun decodeBuildPlanPayload(
48054806
} else {
48064807
""
48074808
}
4809+
val customKernelConfig = if (version >= BUILD_PLAN_CUSTOM_KERNEL_CONFIG_VERSION) {
4810+
reader.readString()
4811+
} else {
4812+
""
4813+
}
48084814
val moduleCount = reader.readVarInt()
48094815
require(moduleCount in 0..BUILD_PLAN_MAX_MODULES) { messages.tooManyModules }
48104816
val modules = List(moduleCount) {
@@ -4852,6 +4858,7 @@ internal fun decodeBuildPlanPayload(
48524858
zramExtraAlgos = zramExtraAlgos,
48534859
kpmPassword = kpmPassword,
48544860
customRef = customRef,
4861+
customKernelConfig = customKernelConfig,
48554862
virtualizationSupport = virtualizationSupport,
48564863
useCustomExternalModules = featureMask.hasBuildPlanFlag(10),
48574864
customExternalModules = modules,
@@ -4984,12 +4991,13 @@ private const val LATE_FAILED_ARTIFACT_POLL_INTERVAL_MS = 5_000L
49844991

49854992
private const val BUILD_PLAN_CODE_PREFIX = "ABKP2:"
49864993
private const val BUILD_PLAN_LEGACY_CODE_PREFIX = "ABKP1:"
4987-
private const val BUILD_PLAN_CODE_VERSION = 6
4994+
private const val BUILD_PLAN_CODE_VERSION = 7
49884995
private const val BUILD_PLAN_MIN_SUPPORTED_VERSION = 2
49894996
private const val BUILD_PLAN_CUSTOM_REF_VERSION = 3
49904997
private const val BUILD_PLAN_ONEPLUS_FIELDS_VERSION = 4
49914998
private const val BUILD_PLAN_KSU_BRANCH_V5_VERSION = 5
49924999
private const val BUILD_PLAN_MODULE_METADATA_VERSION = 6
5000+
private const val BUILD_PLAN_CUSTOM_KERNEL_CONFIG_VERSION = 7
49935001
private const val BUILD_PLAN_NAME_LIMIT = 80
49945002
private const val BUILD_PLAN_MAX_STRING_BYTES = 4096
49955003
private const val BUILD_PLAN_MAX_MODULES = 32
@@ -5025,6 +5033,7 @@ private const val SUMMARY_LABEL_NETWORKING_TYPO = "networing\u589e\u5f3a"
50255033
private const val SUMMARY_LABEL_KPM = "kpm\u529f\u80fd"
50265034
private const val SUMMARY_LABEL_KPM_PASSWORD = "kpm\u5bc6\u7801"
50275035
private const val SUMMARY_LABEL_VIRTUALIZATION = "\u865a\u62df\u5316\u652f\u6301"
5036+
private const val SUMMARY_LABEL_CUSTOM_KERNEL_CONFIG = "\u81ea\u5b9a\u4e49\u5185\u6838\u9009\u9879"
50285037
private const val SUMMARY_LABEL_CUSTOM_INJECTION = "\u81ea\u5b9a\u4e49\u6ce8\u5165"
50295038
private const val SUMMARY_VALUE_DEFAULT_ZH = "\u9ed8\u8ba4"
50305039
private const val SUMMARY_VALUE_NONE_ZH = "\u65e0"
@@ -5095,6 +5104,7 @@ internal fun parseBuildParameterSummary(
50955104
kpmPassword = values["kpmPassword"].orEmpty(),
50965105
reKernelEnabled = values["reKernelEnabled"].orEmpty(),
50975106
virtualizationSupport = values["virtualizationSupport"].orEmpty(),
5107+
customKernelConfig = values["customKernelConfig"].orEmpty(),
50985108
customInjection = values["customInjection"].orEmpty(),
50995109
stockConfig = values["stockConfig"].orEmpty(),
51005110
extraRows = extraRows
@@ -5130,6 +5140,7 @@ private fun normalizeBuildSummaryLabel(label: String): String? {
51305140
compact.contains(SUMMARY_LABEL_KPM_PASSWORD) -> "kpmPassword"
51315141
compact.contains("re-kernel") || compact.contains("rekernel") -> "reKernelEnabled"
51325142
compact.contains(SUMMARY_LABEL_VIRTUALIZATION) -> "virtualizationSupport"
5143+
compact.contains(SUMMARY_LABEL_CUSTOM_KERNEL_CONFIG) -> "customKernelConfig"
51335144
compact.contains(SUMMARY_LABEL_CUSTOM_INJECTION) -> "customInjection"
51345145
compact.contains("stockconfig") -> "stockConfig"
51355146
else -> null
@@ -5330,6 +5341,7 @@ internal fun KernelBuildConfig.toInputMap(): Map<String, String> {
53305341
"zram_extra_algos" to config.zramExtraAlgos,
53315342
"kpm_password" to config.kpmPassword,
53325343
"virtualization_support" to config.virtualizationSupport,
5344+
"custom_kernel_config" to config.customKernelConfig,
53335345
"use_custom_external_modules" to config.useCustomExternalModules.toString(),
53345346
"custom_ref" to if (config.kernelsuBranch == KSU_BRANCH_CUSTOM) {
53355347
config.customRef.trim()

app/src/main/res/values-en/strings.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@
190190
<string name="build_enable_kpm">Enable KPM</string>
191191
<string name="build_enable_rekernel">Enable Re-Kernel driver (test)</string>
192192
<string name="build_virtualization_support">Virtualization support</string>
193+
<string name="build_virtualization_userns_hint">Virtualization no longer enables USER_NS automatically. If DroidSpaces/Wayland needs it, add CONFIG_USER_NS=y in custom kernel options below.</string>
193194
<string name="build_enable_oneplus_8e">Enable OnePlus 8E support</string>
194195
<string name="build_oneplus_lz4kd">Enable lz4kd</string>
195196
<string name="build_oneplus_bbr">Enable BBR</string>
@@ -252,6 +253,10 @@
252253
<string name="build_custom_version_optional">Custom version name (optional)</string>
253254
<string name="build_custom_time_optional">Custom build time (optional)</string>
254255
<string name="build_time_placeholder">Empty/N = current UTC time</string>
256+
<string name="build_custom_kernel_config">Custom kernel options</string>
257+
<string name="build_custom_kernel_config_placeholder">One entry per line, for example CONFIG_USER_NS=y or # CONFIG_IPV6 is not set</string>
258+
<string name="build_custom_kernel_config_hint">Only CONFIG_FOO=... and # CONFIG_BAR is not set are supported. These lines override the final defconfig right before compilation.</string>
259+
<string name="build_custom_kernel_config_count">%1$d custom kernel options configured</string>
255260
<string name="build_add_queue">Add to queue</string>
256261
<string name="build_queue_title">Build queue</string>
257262
<string name="build_plan_library">Plan library</string>
@@ -307,6 +312,7 @@
307312
<string name="build_config_preview">Config preview</string>
308313
<string name="build_feature_networking">Networking</string>
309314
<string name="build_feature_virtualization">Virtualization %1$s</string>
315+
<string name="build_feature_custom_kernel_config">%1$d custom config</string>
310316
<string name="build_base_config">Base config</string>
311317
<string name="build_summary_external_modules">External modules %1$d</string>
312318
<string name="build_hero_desc">Triggers GitHub Actions and automatically organizes img, AK3, manager, and SUSFS modules.</string>

0 commit comments

Comments
 (0)