记一次对w527的内核适配
前言
高三的时候整了一块w527的手表 s100这屏幕的确很诱人 以至于到了大学我还是很想用这块屏幕做小板子
https://e.tb.cn/h.8EY5ZKgedemAujA?tk=n0M2TO1KWNA
大概这个样样 多好看 全面屏 480*480
不过他用的ic不一样 是icn3312 一个没有任何驱动的奇怪ic
包括快充芯片也是eta6947这个奇怪东西 现在应该你在github上找到的都是我当时写的
这就很难办了 当时社区里也没有合适的内核 甚至内核驱动有些也是孤品
所以我选择了用别人的0.1成品内核作为底稿
剩下的...那就只能自己写了 oops
那 总结一下配置
soc:w527(ums312)
pmic:sc2730
charge:eta6947
screen:icn3312
audio:asoc
gravity:da217
touchscreen:hynts
kernel:4.14.98
第一 最基本的编译启动
emm 紫光总是很奇怪的 我起初不理解为什么用过那么多紫光4.14全是gcc4.9.x
所以我第一次选择了头铁用clang/Ubuntu自带的gcc
毕竟一开始怎么配置工具链都配置不好 所以用本机gcc自然是很好的选择
当然啦 最大的前提还没说呢 就是紫光真的好好写了代码 而不是一堆雷霆指针配高版本gcc的雷霆优化 把很多的指针写入变成了一坨大便
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y git make bc bison flex libssl-dev build-essential \
gcc-aarch64-linux-gnu clang libyaml-dev
- name: Build kernel
run: |
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
export CC=clang
export LD=aarch64-linux-gnu-ld
# 加载 defconfig
make sprd_sharkl5_s100_defconfig
方便维护和在学校做 所以我选择了ghactions
这一段看起来人畜无害的东西 也编出来了一个看着没什么问题的内核
但是!一刷入问题就来了
[ 35.415455] c0 Internal error: Oops: 96000061 [#1] PREEMPT SMP
[ 35.418097] c3 init: starting service 'bootanim'...
[ 35.421196] c0 dump_die_cb in.
[ 35.429063] c0 dump_die_cb save pregs_die_g ok .
[ 35.433647] c0 dump_die_cb out.
[ 35.436764] c0 Modules linked in: sprd_fm(O) sprdbt_tty(O) pvrsrvkm(O) cyttsp5_i2c_ts(O) flash_ic_aw3642(O) flash_ic_ocp8137(O) flash_ic_sc2703(O) mmdvfs(O) sprd_cpp(O) sprd_flash_drv(O) sprd_sensor(O)
[ 35.454603] c0 CPU: 0 PID: 741 Comm: HwBinder:661_1 Tainted: G S W O 4.14.98-KawaiiSoraNeko #1
[ 35.463938] c0 Hardware name: Unisoc UWS6152 1H10 board (DT)
[ 35.469562] c0 task: ffffffc0d1c28000 task.stack: ffffff8013d08000
[ 35.475714] c0 PC is at dpu_init+0xb0/0x4dc
[ 35.479864] c0 LR is at sprd_crtc_atomic_enable+0x13c/0x160
[ 35.485398] c0 pc : [
<ffffff80084a8618>] lr : [<ffffff800849dbe0>] pstate: 40400045
[ 35.493013] c0 sp : ffffff8013d0b970
[ 35.496569] c0 x29: ffffff8013d0b9c0 x28: ffffffc0f9ebd700
[ 35.506341] c0 x27: ffffffc0d180df10 x26: ffffffc0de9d2800
[ 35.511878] c0 x25: ffffff80089be790 x24: 0000000000000038
[ 35.517416] c0 x23: ffffff80090c3638 x22: ffffff80090c366c
[ 35.522955] c0 x21: ffffffc0f9ebd7e0 x20: ffffffc0f9ebd788
[ 35.528493] c0 x19: 0000000000000000 x18: 0000000000000000
[ 35.534032] c0 x17: 0000007f34ba6bc4 x16: ffffff8008209494
[ 35.539570] c0 x15: 000000000000000a x14: 0000000000f42400
[ 35.545109] c0 x13: ffffffffffffffff x12: ffffff8009067000
[ 35.550648] c0 x11: 0000000000040000 x10: ffffff80091d2012
[ 35.556186] c0 x9 : 000000000000005c x8 : 0000000000000000
[ 35.561723] c0 x7 : 0000000000000001 x6 : ffffff80091d1000
[ 35.567263] c0 x5 : 0000000000000000 x4 : 000000000000000c
[ 35.572800] c0 x3 : 0000000000440000 x2 : 0000ffff00000000
[ 35.578339] c0 x1 : ffffff8009791000 x0 : ffffff8009791800
[ 35.583883] c0
[ 35.583883] c0 PC: 0xffffff80084a8598:
[ 35.589329] c0 8598 394046e4 f9478422 f90027e2 d2800002 f9400001 b9002c3f b9403003 b9404002
[ 35.597723] c0 85b8 b900083f 2a024062 39404ae3 29040822 394052e2 531c6c63 2a023062 39404ee3
[ 35.606118] c0 85d8 2a032083 2a030042 52a00883 2a030042 b9000c22 52880042 72a00022 b9001022
[ 35.606138] c0 85f8 39407c02 34000042 97fff9e4 91200020 b908003f d2dfffe2 9100d2f6 d2800013
[ 35.606158] c0 8618 f803c002 f8044002 12bfffc0 b9080c20 529fffe0 b901e420 f9400295 b902d2b3
[ 35.606177] c0 8638 d28218e0 9411e538 78737ac0 91000673 b902d6a0 f104027f 54ffff21 900028d6
[ 35.606205] c0 8658
[ 35.618762] c0 9105a2d6 9104a2d8 f0003b20 aa1803e1 91003800 97f16356 d0007ca0 912ff013
[ 35.618781] c0 8678 b940a261 36000161 b94bfc02 aa1803e1 b9400663 2a034040 b90026a0 d0003b20
[ 35.666620] c0
[ 35.666620] c0 LR: 0xffffff800849db60:
[ 35.672070] c0 db60 f9442260 b40000a0 f9400401 b4000061 aa1403e0 d63f0020 39407e80 340000e0
[ 35.680467] c0 db80 f9442260 b40000a0 f9400c01 b4000061 aa1403e0 d63f0020 f9441e60 b40000a0
[ 35.688860] c0 dba0 f9400401 b4000061 aa1403e0 d63f0020 f9441e60 b40000a0 f9400c01 b4000061
[ 35.697256] c0 dbc0 aa1403e0 d63f0020 f9441a60 b40000a0 f9400801 b4000061 aa1403e0 d63f0020
[ 35.705648] c0 dbe0 f9441a60 b40000a0 f9402401 b4000061 aa1403e0 d63f0020 52800020 39007a80
[ 35.714043] c0 dc00 17ffffc7 2a0003e1 7100141f 54000129 a9bf7bfd 90003b80 91037c00 910003fd
[ 35.714063] c0 dc20 97f18de9 d2800000 a8c17bfd d65f03c0 f0007ce0 911da000 f861d800 d65f03c0
[ 35.714083] c0 dc40 a9bf7bfd f0007ce0 911da000 910003fd b0006121 91370021 a9007c1f a9017c1f
[ 35.743472] c0
[ 35.743472] c0 SP: 0xffffff8013d0b8f0:
[ 35.748918] c0 b8f0 00000038 00000000 089be790 ffffff80 de9d2800 ffffffc0 d180df10 ffffffc0
[ 35.757312] c0 b910 f9ebd700 ffffffc0 13d0b9c0 ffffff80 0849dbe0 ffffff80 13d0b970 ffffff80
[ 35.765707] c0 b930 084a8618 ffffff80 40400045 00000000 f9f02c00 ffffffc0 00000040 00000000
[ 35.774101] c0 b950 ffffffff 0000007f 0943fd00 ffffff80 13d0b9c0 ffffff80 084a8618 ffffff80
[ 35.782496] c0 b970 f9f0f100 ffffffc0 00000040 00000000 f92bf480 ffffffc0 0943fd00 ffffff80
[ 35.790889] c0 b990 13d0b9c0 ffffff80 0841834c ffffff80 f9f0f100 ffffffc0 00000040 00000000
[ 35.799283] c0 b9b0 13d0b9c0 ffffff80 ddc27f00 bf5c3499 13d0ba20 ffffff80 0849dbe0 ffffff80
[ 35.807677] c0 b9d0 f9ebd018 ffffffc0 f9ebd788 ffffffc0 f9ebd7e0 ffffffc0 08c086ac ffffff80
[ 35.816082] c0
[ 36.803330] c0 Process HwBinder:661_1 (pid: 741, stack limit = 0xffffff8013d08000)
[ 36.803333] c0 Call trace:
[ 36.803339] c0 Exception stack(0xffffff8013d0b830 to 0xffffff8013d0b970)
[ 36.803346] c0 b820: ffffff8009791800 ffffff8009791000
[ 36.803357] c0 b840: 0000ffff00000000 0000000000440000 000000000000000c 0000000000000000
[ 36.850644] c0 b860: ffffff80091d1000 0000000000000001 0000000000000000 000000000000005c
[ 36.858693] c0 b880: ffffff80091d2012 0000000000040000 ffffff8009067000 ffffffffffffffff
[ 36.866741] c0 b8a0: 0000000000f42400 000000000000000a ffffff8008209494 0000007f34ba6bc4
[ 36.874789] c0 b8c0: 0000000000000000 0000000000000000 ffffffc0f9ebd788 ffffffc0f9ebd7e0
[ 36.882838] c0 b8e0: ffffff80090c366c ffffff80090c3638 0000000000000038 ffffff80089be790
[ 36.890885] c0 b900: ffffffc0de9d2800 ffffffc0d180df10 ffffffc0f9ebd700 ffffff8013d0b9c0
[ 36.898933] c0 b920: ffffff800849dbe0 ffffff8013d0b970 ffffff80084a8618 0000000040400045
[ 36.906981] c0 b940: ffffffc0f9f02c00 0000000000000040 0000007fffffffff ffffff800943fd00
[ 36.915027] c0 b960: ffffff8013d0b9c0 ffffff80084a8618
[ 36.915040] c0 [
<ffffff80084a8618>] dpu_init+0xb0/0x4dc
[ 36.915047] c0 [
<ffffff800849dbe0>] sprd_crtc_atomic_enable+0x13c/0x160
[ 36.915056] c0 [
<ffffff800846d86c>] drm_atomic_helper_commit_modeset_enables+0xac/0x18c
[ 36.915065] c0 [
<ffffff800849b0f0>] sprd_atomic_commit_tail+0x2c/0x5c
[ 36.915073] c0 [
<ffffff800849b564>] sprd_commit_tail+0x40/0x7c
[ 36.915080] c0 [
<ffffff800849b8d4>] sprd_atomic_commit+0x31c/0x39c
[ 36.915097] c0 [
<ffffff800848ada4>] drm_atomic_commit+0x50/0x5c
[ 36.968339] c0 [
<ffffff800848b290>] drm_atomic_connector_commit_dpms+0xd0/0xfc
[ 36.975522] c0 [
<ffffff800848fdac>] drm_mode_obj_set_property_ioctl+0xd0/0x250
[ 36.982705] c0 [
<ffffff800848e9f0>] drm_mode_connector_property_set_ioctl+0x34/0x5c
[ 36.990320] c0 [
<ffffff800847b18c>] drm_ioctl_kernel+0x80/0xc4
[ 36.996114] c0 [
<ffffff800847b4e0>] drm_ioctl+0x2ec/0x378
[ 37.001484] c0 [
<ffffff8008208b9c>] vfs_ioctl+0x24/0x40
[ 37.006674] c0 [
<ffffff8008208d58>] do_vfs_ioctl+0xb4/0x7f0
[ 37.012215] c0 [
<ffffff80082094f0>] SyS_ioctl+0x5c/0x8c
[ 37.017402] c0 Exception stack(0xffffff8013d0bec0 to 0xffffff8013d0c000)
[ 37.024069] c0 bec0: 0000000000000006 00000000c01064ab 0000007c9fece288 0000000000000000
[ 37.024076] c0 bee0: 0000000000000000 0000000000000040 0000007f363a4000 00000000000038ce
[ 37.024084] c0 bf00: 000000000000001d 0000007c9fece200 0000007c9fece200 0000007c9fece1d0
[ 37.024093] c0 bf20: ffffff80ffffffd0 000000000000003a 0030a32beb081480 00000f37484e962e
[ 37.060501] c0 bf40: 0000007ca18fcd90 0000007f34ba6bc4 0000007c9fb6a000 0000007c9fecf008
[ 37.068551] c0 bf60: 00000000c01064ab 0000000000000006 0000000000000006 0000007df45ae2f0
[ 37.076597] c0 bf80: 000000000000004f 0000007f349bc038 0000000000000000 00000000000fb000
[ 37.084645] c0 bfa0: 0000007c9fdd7000 0000007c9fece230 0000007f34ba6c64 0000007c9fece150
[ 37.092693] c0 bfc0: 0000007f34beb318 0000000080000000 0000000000000006 000000000000001d
[ 37.100741] c0 bfe0: 0000000000000000 0000000000000000 0000000000000000 0000000000000000
[ 37.108791] c0 [
<ffffff80080832c0>] el0_svc_naked+0x34/0x38
[ 37.114330] c0 Code: b908003f d2dfffe2 9100d2f6 d2800013 (f803c002)
[ 37.120643] c0 ---[ end trace 2a21c748f1c53e95 ]---
[ 37.145152] c0 Kernel panic - not syncing: Fatal exception
[ 37.150546] c0 (sprd_debug_save_context) context saved(CPU:0)
[ 37.156337] c0 SMP: stopping secondary CPUs
哎呀 kernel panic了
如果你是聪明的小猫的话 你就会发现他在PC:dpu_init+0xb0处崩溃了
这时候正好是一个
f803c002 → str x2, [x0], #60
六十四位写
是不是很眼熟
· x0:0xffffff8009781800(上一份 0xffffff8009791800)
· x1:0xffffff8009781000(上一份 0xffffff8009791000)
· x2:0x0000ffff00000000
x2 的来历:dpu_init 中相邻的 MMU 初始化代码:
reg->mmu_min_ppn1 = 0; // 低32位填0
reg->mmu_ppn_range1 = 0xffff; // 高32位填0xffff
编译器把这两个该死的三十二位写合并成了一个六十四位写。
但这里要注意:崩溃时写的地址是 base + 0x800,也就是 mmu_en 的位置,而不是 mmu_min_ppn1(偏移 0x83C)。
指令里的后索引 #60(0x3C)说明编译器打算先写 0x800,然后 x0 += 0x3C 跳到 0x83C 继续写。
但由于第一条写 0x800 就崩了,因为实际映射的寄存器区域可能只有 0x800 长(或者 IOMMU 占了 0x20300800 导致 DPU 映射被截断),总之 0x800 在崩溃时不可写。
我们回顾dpu_lite_r2p0.c里的dpuinit
static int dpu_init(struct dpu_context *ctx)
{
struct dpu_reg *reg = (struct dpu_reg *)ctx->base;
u32 size;
/* set bg color */
reg->bg_color = 0;
/* set dpu output size */
size = (ctx->vm.vactive << 16) | ctx->vm.hactive;
reg->panel_size = size;
reg->blend_size = size;
reg->dpu_cfg0 = 0;
reg->dpu_cfg1 = (qos_cfg.awqos_high << 12) |
(qos_cfg.awqos_low << 8) |
(qos_cfg.arqos_high << 4) |
(qos_cfg.arqos_low) | BIT(18) | BIT(22);
reg->dpu_cfg2 = 0x14002;
if (ctx->is_stopped)
dpu_clean_all(ctx);
reg->mmu_en = 0;
reg->mmu_min_ppn1 = 0;
reg->mmu_ppn_range1 = 0xffff;
reg->mmu_min_ppn2 = 0;
reg->mmu_ppn_range2 = 0xffff;
reg->mmu_vpn_range = 0x1ffff;
reg->dpu_int_clr = 0xffff;
dpu_enhance_reload(ctx);
dpu_write_back_config(ctx);
INIT_WORK(&ctx->dvfs_work, dpu_dvfs_work_func);
return 0;
}
dpu_init 函数(位于 dpu_lite_r2p0.c)的主要流程:
- 通过 ctx->base 获取硬件寄存器基址 reg
- 配置 DPU 基础寄存器(背景色、输出尺寸、QoS 等)
- 调用 dpu_enhance_reload(ctx) 重载增强模块参数
- 调用 dpu_write_back_config(ctx) 配置 Write-Back 功能
- 使用 INIT_WORK 初始化 dvfs_work 工作队列
其实,到最后发现是紫光的驱动没有用 volatile / writel 来访问 MMIO,reg 只是一个普通指针,编译器(高版本 GCC 或 Clang)就放心大胆地合并、重排这些写操作,结果合并出的 64 位写用后索引跳地址时踩到了未映射区域,导致了 kernel panic。
解决问题不算难也不算简单 我选了最简单的办法 也就是降级回gcc4.9.x
如果你头铁 也可以重写drm这坨答辩 当然 重写的成本就可能是重构整个kernel了
题外话
我在编译的时候遇到了一个问题 也挺神秘的
arch/arm64/Makefile:57: Detected assembler with broken .inst; disassembly will be unreliable
CHK include/config/kernel.release
Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: -fstack-protector-strong not supported by compiler
make: *** [Makefile:1206: prepare-compiler-check] Error 1
make: *** Waiting for unfinished jobs....
UPD include/config/kernel.release
arch/arm64/Makefile:49: LSE atomics not supported by binutils
arch/arm64/Makefile:57: Detected assembler with broken .inst; disassembly will be unreliable
CHK include/config/kernel.release
呃 对 栈保护炸了 但我查了很久 gcc4.9.0就引入了栈保护 那这就奇怪了 4.9.x显而易见超过了4.9.0 为什么会炸呢
emm 引入一下
在内核Makefile的prepare-compiler-check 阶段会检测编译器各个功能的可用性
$(CC) -fstack-protector-strong -c empty.c
大概这样检测
问题就出在这个上。gcc 在编译时,如果需要进行汇编,会自动调用 as(汇编器)来生成目标文件。内核的这个探测命令,恰好会触发这个调用。
Android 预编译的 GCC 4.9 工具链,其 gcc 和 as 是分开存放的,并且 gcc 自身可能并不携带“要去哪里找 as”的完整信息。它通常依赖 PATH 环境变量,或者一系列复杂的 wrapper 脚本来定位同目录下的 as。
解释: 在CI 环境中 gcc在尝试汇编时就会找不到 aarch64-linux-android-as 从而退而求其次 去调用宿主机的 /usr/bin/as。当然 我这里只部署了gcc 所以自然就没有工具链as
显而易见 宿主机是x86as 他压根不知道arm指令
booom!
懂了吧 但是gcc4.9是支持的 所以其实根本没啥影响 关掉这个检测就行
prepare-compiler-check: FORCE
# Skip check
# ifdef CONFIG_CC_STACKPROTECTOR_STRONG
# @if ! $(CC) -fstack-protector-strong -x c -c /dev/null -o /dev/null >/dev/null 2>&1; then \
# echo 'Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: -fstack-protector-strong not supported by compiler'; \
# false; \
# fi
# endif
那这样就好了 接下来编译就正常了
所以 第一步 他终于不缺符号的卡在了第一屏
并开启了adb
顺带贴一下我的完整ghactions捏
name: Build Pure Kernel (gcc 4.9)
on:
workflow_dispatch:
permissions:
contents: write
jobs:
build:
runs-on: ubuntu-22.04
steps:
- name: Checkout kernel source
uses: actions/checkout@v4
with:
ref: ${{ github.ref_name }}
submodules: true
- name: Install dependencies
run: |
sudo apt update
sudo apt install -y git make bc bison flex libssl-dev build-essential \
libyaml-dev
- name: Download and setup GCC 4.9 toolchain
run: |
mkdir -p $HOME/toolchains
cd $HOME/toolchains
git clone --depth=1 --branch=W20.13.3 \
--filter=blob:none --no-checkout \
https://github.com/deadman96385/jingpad_android_bsp.git toolchain-tmp
cd toolchain-tmp
git sparse-checkout init --cone
git sparse-checkout set toolchain/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9
git checkout
mv toolchain/prebuilts/gcc/linux-x86/aarch64/aarch64-linux-android-4.9 \
../aarch64-linux-android-4.9
cd ..
rm -rf toolchain-tmp
chmod -R a+x $HOME/toolchains/aarch64-linux-android-4.9/bin
echo "$HOME/toolchains/aarch64-linux-android-4.9/bin" >> $GITHUB_PATH
- name: Verify toolchain
run: |
aarch64-linux-android-gcc --version
aarch64-linux-android-gcc -fstack-protector-strong -c -x c /dev/null -o /dev/null
- name: Test Telegram connection (text message)
run: |
curl -s -X POST "https://api.telegram.org/bot${{ secrets.TELEGRAM_TOKEN }}/sendMessage" \
-d "chat_id=${{ secrets.TELEGRAM_TO }}" \
-d "text= GitHub Actions: Build started at $(date -u '+%Y-%m-%d %H:%M:%S UTC')." | tee /dev/stderr
echo "If the message above shows 'ok:true', your bot can send messages to the chat."
- name: Unshallow KernelSU submodule
run: |
cd KernelSU
git fetch --unshallow
git fetch --tags
- name: Build kernel
run: |
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-android-
# ===== 1. 配置 & 编译内核本体 =====
make sprd_sharkl5_s100_defconfig
scripts/config --disable CONFIG_APPENDED_DTB
scripts/config --disable CONFIG_EFI
scripts/config --disable CONFIG_EFI_STUB
sed -i '/yamltree\.o/d' scripts/dtc/Makefile
sed -i 's/dt_to_yaml(/\/\/ dt_to_yaml(/g' scripts/dtc/dtc.c
sed -i '/ifdef CONFIG_CC_STACKPROTECTOR_STRONG/{n;s/stackp-flag :=.*/stackp-flag := -fstack-protector-strong/}' Makefile
sed -i '/ifdef stackp-name/,/endif/{s/exit 1/true/}' Makefile
sed -i '/ifdef stackp-check/,/endif/{s/exit 1/true/}' Makefile
make olddefconfig
KCFLAGS="-Wno-error=sizeof-pointer-memaccess -Wno-error=array-bounds -Wno-error=missing-braces -Wno-error=format"
make -j$(nproc) KCFLAGS="$KCFLAGS" 2>&1 | tee build.log
# ===== 2. 编译内核内部模块 =====
make modules 2>&1 | tee -a build.log
make modules_install INSTALL_MOD_PATH=./modules_out 2>&1 | tee -a build.log
# ===== 3. 编译外部相机模块(所有需要的子模块) =====
EXTERNAL_MODULES="modules/common/camera/core \
modules/common/camera/sensor \
modules/common/camera/flash/flash_drv \
modules/common/camera/flash/ocp8137 \
modules/common/camera/flash/sc2703s \
modules/common/camera/mmdvfs \
modules/common/camera/fd"
# 所有宏(目录名必须和源码实际目录一致)
EXTRA_ARGS="BSP_BOARD_CAMERA_MODULE_ISP_VERSION=isp2.6"
EXTRA_ARGS="$EXTRA_ARGS BSP_BOARD_CAMERA_MODULE_CSI_VERSION=receiver_r2p1"
EXTRA_ARGS="$EXTRA_ARGS BSP_BOARD_CAMERA_MODULE_ISP_ADAPT_VERSION=sharkl5"
EXTRA_ARGS="$EXTRA_ARGS BSP_BOARD_CAMERA_MODULE_DVFS=sharkl5"
EXTRA_ARGS="$EXTRA_ARGS BSP_BOARD_CAMERA_MODULE_CPP_VERSION=lite_r4p0"
EXTRA_ARGS="$EXTRA_ARGS BSP_BOARD_CAMERA_MODULE_FD_VERSION=fd2.0"
for dir in $EXTERNAL_MODULES; do
if [ -f "$dir/Kbuild" ] || [ -f "$dir/Makefile" ]; then
echo "Building external module: $dir"
make -C . M="$dir" $EXTRA_ARGS modules 2>&1 | tee -a build.log
make -C . M="$dir" modules_install INSTALL_MOD_PATH=./modules_out 2>&1 | tee -a build.log
fi
done
- name: Locate pure kernel image
id: find_kernel
continue-on-error: true
run: |
if [ -f arch/arm64/boot/Image.gz ]; then
echo "kernel_path=arch/arm64/boot/Image.gz" >> $GITHUB_OUTPUT
elif [ -f arch/arm64/boot/Image ]; then
echo "kernel_path=arch/arm64/boot/Image" >> $GITHUB_OUTPUT
else
echo "No kernel image found!"
exit 1
fi
- name: Send build.log if kernel image not found
if: steps.find_kernel.outcome == 'failure'
env:
BOT_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
CHAT_ID: ${{ secrets.TELEGRAM_TO }}
run: |
curl -s -F document=@build.log \
-F "caption= Build failed: kernel image not found. See build.log for details." \
"https://api.telegram.org/bot${BOT_TOKEN}/sendDocument?chat_id=${CHAT_ID}"
exit 1
- name: Package modules
run: |
KERNEL_RELEASE=$(make -s kernelrelease 2>/dev/null | grep -v '^#' | tail -1)
if [ -z "$KERNEL_RELEASE" ]; then
echo "Error: Could not get kernel release"
exit 1
fi
echo "Kernel release: $KERNEL_RELEASE"
echo "KERNEL_RELEASE=$(echo $KERNEL_RELEASE | xargs)" >> $GITHUB_ENV
MODULES_DIR="modules_out/lib/modules/$KERNEL_RELEASE"
if [ ! -d "$MODULES_DIR" ]; then
echo "Error: Modules directory not found at $MODULES_DIR"
exit 1
fi
cd "$MODULES_DIR"
rm -f source build
tar -czf ../../../../modules.tar.gz .
zip -r ../../../../modules.zip .
cd ../../../..
ls -lh modules.tar.gz modules.zip
- name: Prepare AnyKernel3 (flattened modules)
env:
KERNEL_RELEASE: ${{ env.KERNEL_RELEASE }}
run: |
git clone --depth=1 https://github.com/ZeroDreamCat/sprd_ak3.git anykernel
rm -rf anykernel/.git anykernel/{README.md,ramdisk,patch}
rm -rf anykernel/modules/system
cp "${{ steps.find_kernel.outputs.kernel_path }}" anykernel/
MODULES_FLAT="anykernel/modules/vendor/lib/modules"
mkdir -p "${MODULES_FLAT}"
find modules_out/lib/modules/${KERNEL_RELEASE} -name "*.ko" \
-exec cp {} "${MODULES_FLAT}/" \;
cd anykernel
zip -r9 ../AnyKernel3.zip .
cd ..
- name: gzip vmlinux
run: gzip -9 vmlinux
- name: Package all artifacts for Telegram (exclude vmlinux.gz)
run: |
mkdir -p telegram_artifacts
cp ${{ steps.find_kernel.outputs.kernel_path }} telegram_artifacts/
cp modules.tar.gz modules.zip telegram_artifacts/ 2>/dev/null || true
cp System.map Module.symvers build.log telegram_artifacts/ 2>/dev/null || true
cp AnyKernel3.zip telegram_artifacts/
cd telegram_artifacts
zip -9 ../all_artifacts.zip *
cd ..
echo "Created all_artifacts.zip (without vmlinux.gz)"
ls -lh all_artifacts.zip
- name: Create Release and Upload Artifacts
uses: softprops/action-gh-release@v1
with:
tag_name: build-${{ github.run_id }}
name: Build - ${{ github.sha }} (${{ github.ref_name }})
files: |
${{ steps.find_kernel.outputs.kernel_path }}
modules.tar.gz
modules.zip
AnyKernel3.zip
build.log
System.map
Module.symvers
vmlinux.gz
draft: false
prerelease: true
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Send artifacts to Telegram (lightweight + Release link)
env:
BOT_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
CHAT_ID: ${{ secrets.TELEGRAM_TO }}
KERNEL_RELEASE: ${{ env.KERNEL_RELEASE }}
run: |
COMMIT_MSG=$(git log -1 --pretty=%s)
export COMMIT_MSG
python3 -c "
import os, requests
bot_token = os.environ['BOT_TOKEN']
chat_id = os.environ['CHAT_ID']
kernel_release = os.environ.get('KERNEL_RELEASE', 'unknown').strip()
commit_msg = os.environ.get('COMMIT_MSG', 'unknown').strip()
repo = os.environ.get('GITHUB_REPOSITORY', 'unknown')
ref = os.environ.get('GITHUB_REF_NAME', 'unknown')
sha = os.environ.get('GITHUB_SHA', 'unknown')[:7]
run_id = os.environ.get('GITHUB_RUN_ID', 'unknown')
release_url = f'https://github.com/{repo}/releases/tag/build-{run_id}'
zip_file = 'all_artifacts.zip'
if not os.path.exists(zip_file):
print(f' {zip_file} not found')
exit(1)
size = os.path.getsize(zip_file)
print(f' Sending {zip_file} ({size} bytes)...')
caption = (
f' Build completed!\n'
f' Kernel version: {kernel_release}\n'
f' Commit: {commit_msg} ({sha})\n'
f' Branch: {ref}\n'
f' Repo: {repo}\n'
f' Artifacts attached: kernel image, modules, System.map, build.log\n'
f' Full release (including vmlinux.gz):\n{release_url}'
)
with open(zip_file, 'rb') as f:
resp = requests.post(
f'https://api.telegram.org/bot{bot_token}/sendDocument',
data={'chat_id': chat_id, 'caption': caption},
files={'document': f}
)
print(resp.text)
if resp.ok and resp.json().get('ok'):
print(' Telegram notification sent successfully!')
else:
print(' Failed to send Telegram.')
exit(1)
" 
Comments NOTHING