1.平台基本信息
#内核, 4.4.197
Linux hs8145x6 4.4.197 #1 SMP Mon Jul 13 10:01:41 UTC 2020 armv7l GNU/Linux
#cpu, armv7
processor : 0
model name : ARMv7 Processor rev 1 (v7l)
BogoMIPS : 1594.16
Features : half thumb fastmult edsp thumbee tls
#硬件, hisi A9
Hardware : Hisilicon A9
Revision : 0000
Serial : 0000000000000000
2.根据 linux 官网提供的 4.4.197 内核,编译一个最简单的内核模块,提示以下错误
[ 196.377553] ------------[ cut here ]------------
[ 196.377602] WARNING: CPU: 1 PID: 3665 at kernel/module.c:1105 module_put+0x78/0x13c()
[ 196.377615] Modules linked in: getshell bridge ...
[ 196.378513] CPU: 1 PID: 3665 Comm: insmod Tainted: P W O 4.4.197 #1
[ 196.378527] Hardware name: Hisilicon A9
[ 196.378575] [<c0012d3c>] (rtos_unwind_backtrace) from [<c000e518>] (show_stack+0x10/0x14)
[ 196.378611] [<c000e518>] (show_stack) from [<c023cd20>] (dump_stack+0x88/0xa8)
[ 196.378651] [<c023cd20>] (dump_stack) from [<c001fa6c>] (warn_slowpath_common+0x84/0xb0)
[ 196.378678] [<c001fa6c>] (warn_slowpath_common) from [<c001fb80>] (warn_slowpath_null+0x18/0x20)
[ 196.378703] [<c001fb80>] (warn_slowpath_null) from [<c0094140>] (module_put+0x78/0x13c)
[ 196.378730] [<c0094140>] (module_put) from [<c00d5ae4>] (do_init_module+0xd0/0x1e4)
[ 196.378752] [<c00d5ae4>] (do_init_module) from [<c0097648>] (load_module+0x1bc8/0x1c78)
[ 196.378773] [<c0097648>] (load_module) from [<c00978f0>] (SyS_finit_module+0x70/0x94)
[ 196.378794] [<c00978f0>] (SyS_finit_module) from [<c000abc0>] (ret_fast_syscall+0x0/0x40)
[ 196.378811] ---[ end trace d531998291dcf678 ]---
因为机器是双核的,机器内核默认是开启了 PLT section(s), 随便找一个自带的内核模块,用 objdump dump 下 symbol 。可以验证是开启了 PLT 。
[root@hs8145x6 ~]# objdump -t hi_gmac.ko | grep plt
00000000 l d .plt 00000000 .plt
00000001 l d .init.plt 00000000 .init.plt
但是用 linux 官方的内核,且开启了 PLT section(s)情况下编译的模块,无法正常运行。感觉海思好像改了 PLT , 但目前不知道改在哪里, 所以,烦请 有能力的大佬帮忙分析分析下。谢谢。
查了下4.4.197,/arch/arm/kernel/module.lds
SECTIONS {
.core.plt : { BYTE(0) }
.init.plt : { BYTE(0) }
}
section 里没有 .plt, 应该是 把 plt 拆分成 core.plt 和 init.plt。 同时,搜到这个patch,但似乎是更老的内核,没看懂
查了下4.4.197,/arch/arm/kernel/module.lds
SECTIONS {
.core.plt : { BYTE(0) }
.init.plt : { BYTE(0) }
}
section 里没有 .plt, 应该是 把 plt 拆分成 core.plt 和 init.plt。 同时,搜到这个patch,但似乎是更老的内核,没看懂
同时,我也查了下,4.x 系列的内核,到 4.9.30, 才改成
SECTIONS {
.plt : { BYTE(0) }
.init.plt : { BYTE(0) }
}
4.9-4.9.29 是
SECTIONS {
.plt : { BYTE(0) }
}
感觉有点乱,不知道如何打补丁
根据这个patch, 如果直接将4.4.197下面几个文件替换成4.9.30的
/arch/arm/include/asm/module.h
/arch/arm/kernel/module-plts.c
/arch/arm/kernel/module.lds
这个思路是否可行? 或者有其他更好的给内核某个功能打补丁的方法?
综合4.x各版本PLTs演变情况,猜测,海思攻城狮应该基于4.9.30以上关于PLTs部分代码修改情况,对4.4.197 的PLTs做了部分修改,(这个人应该很熟悉内核代码,极有可能参与过内核patch研究和提交)。 4.9.30 PLTs的Changelog
Since commit 35fa91eed817 ("ARM: kernel: merge core and init PLTs"),
the ARM module PLT code allocates all PLT entries in a single core
section, since the overhead of having a separate init PLT section is
not justified by the small number of PLT entries usually required for
init code.
However, the core and init module regions are allocated independently,
and there is a corner case where the core region may be allocated from
the VMALLOC region if the dedicated module region is exhausted, but the
init region, being much smaller, can still be allocated from the module
region. This puts the PLT entries out of reach of the relocated branch
instructions, defeating the whole purpose of PLTs.
So split the core and init PLT regions, and name the latter ".init.plt"
so it gets allocated along with (and sufficiently close to) the .init
sections that it serves. Also, given that init PLT entries may need to
be emitted for branches that target the core module, modify the logic
that disregards defined symbols to only disregard symbols that are
defined in the same section.
1
duforv2 2021-12-12 13:02:26 +08:00
在 v2 问某为,是在捅马蜂窝啊
|
2
yangxin0 2021-12-12 13:11:50 +08:00 via iPhone
没得华为内部支持估计你用起来都很难
|
3
jackmod 2021-12-12 13:28:13 +08:00
似乎没太大关系?好久没碰嵌入式,轻拍。
mod 需要的 kernel 名称( uname -a )需要和当前 kernel 名称完全匹配,一个字都不能差。 现在用的什么内核就要拿它的源码(或头文件)去 build 才可以。 |
4
gengchun 2021-12-12 13:39:47 +08:00 1
B 站上好像有用 Gentoo 的,做过海思的,你要不搜搜看,直接去问 UP 主。
|
5
feather12315 2021-12-12 13:49:35 +08:00 via Android 1
用 openeuler 的内核,4.19 或 5.10 试试。
openeuler 内核是华为所有使用 Linux 产品线内核的源头。 |
6
whenov 2021-12-12 14:01:43 +08:00
内核模块的版本要和内核版本对应上才行。不如先说下你的目的?
|
7
whenov 2021-12-12 14:02:40 +08:00
打补丁的话直接用 patch 或者 git apply 都可以吧,要看你本来的流程是怎样的
|
8
SpicaStar 2021-12-12 14:53:52 +08:00
好奇折腾光猫是有啥特殊需求吗
|
9
ysc3839 2021-12-12 15:16:42 +08:00 via Android
怀疑是 X-Y Problem https://coolshell.cn/articles/10804.html
建议直接说具体需求 |
10
v2000000001ex OP @jackmod 对,内核 ver magic 已经匹配过了,否则根本不会执行 ko ,直接提示 ver magic 错误,在我给的最简单的内核模块的链接的资源里有 config ,里面我都适配好了。
|
11
v2000000001ex OP |
12
whenov 2021-12-12 19:13:06 +08:00
为什么不直接用 4.9.30 的内核源码呢?
|
13
whenov 2021-12-12 19:14:18 +08:00
才注意到新光猫的内核是 4.4.197
|
14
v2000000001ex OP @whenov #13 对,如果用 4.9.30 ,在修改 config 中的版本,适配 ver magic ,编译出来的 ko ,虽然执行不报 vermagic 错误,但会出现内核 panic 。
|
15
flynaj 2021-12-12 20:46:03 +08:00 via Android
华为的硬件都很封闭,openwrt 适配不了。建议不要浪费时间。
|
16
v2000000001ex OP @flynaj 对,现在问题主要集中在 PLTs ,与硬件驱动无关。
|
17
v2000000001ex OP @feather12315 #5 看了下 openeuler 的 4.4.197 内核,PLTs 与官方源码 一致
|
18
yolee599 2021-12-13 08:33:06 +08:00 via Android
这个还是要找 FAE 吧,硬件太封闭
|