直接读取 /proc/kallsyms 是获取当前运行内核实时符号表的最权威方式,它动态包含 vmlinux 本体及所有已加载模块的符号,但受 kptr_restrict 限制默认地址为 0;需 root 执行 echo 0 > /proc/sys/kernel/kptr_restrict 解除掩码后才能看到真实地址。

麒麟操作系统查看内核符号表,核心目标是获取当前运行内核中所有函数与全局变量的地址和名称映射关系,用于调试、安全分析或模块开发;但必须注意,默认状态下非 root 用户看到的全是 0 地址,这不是命令失效,而是内核主动掩码。
直接读取 /proc/kallsyms 获取实时符号表
这是最权威、最实时的方式,因为 /proc/kallsyms 是内核内存中动态构建的视图,包含 vmlinux 本体 + 所有已加载模块的符号。
在终端中执行:cat /proc/kallsyms。
若输出每行地址均为 【0000000000000000】,说明 kptr_restrict 已启用——这不是权限不足,而是内核安全策略强制隐藏,普通用户无法绕过。
临时解除掩码(需 root):执行 echo 0 | sudo tee /proc/sys/kernel/kptr_restrict,之后再运行 cat /proc/kallsyms 即可看到真实地址。
筛选特定符号快速定位
符号表通常超万行,直接翻阅不现实。用 grep 管道过滤是最常用做法,但要注意大小写和符号类型前缀。
查找名为 do_fork 的函数(x86_64 平台):grep " do_fork$" /proc/kallsyms。
查找以 kysec_ 开头的所有符号:grep "^kysec_" /proc/kallsyms。
注意末尾的 $ 符号——它确保只匹配完整函数名,避免误中 do_fork_init 或 do_fork_hook 等相似名。
对比 System.map 静态快照(仅限 vmlinux 本体)
System.map 是编译时生成的静态符号文件,不含任何模块符号,也不受 kptr_restrict 影响,但它反映的是编译那一刻的基址,不是当前运行时的真实地址。
先确认当前内核版本:uname -r,假设输出为 4.19.90-89.11.v2401.ky10.aarch64。
然后查找对应 map 文件:ls /boot/System.map-$(uname -r)。
若存在,用 cat /boot/System.map-$(uname -r) | grep " t " | head -20 查看前 20 个文本段函数符号(t 表示 text 段)。
【重要前提】该文件必须与当前运行内核版本严格一致,否则地址完全不可用;且 KASLR 启用时,实际加载地址 = System.map 中地址 + 随机偏移量。
验证符号是否可被模块安全调用
即使查到符号地址,也不代表能直接调用——很多函数未导出,模块加载会失败。
检查 kallsyms_lookup_name 是否可用(自 Linux 5.7 起部分发行版默认禁用):grep -q "kallsyms_lookup_name" /proc/kallsyms && echo "available" || echo "disabled"。
若返回 disabled,说明内核已移除该接口或设为 hidden,此时无法在模块中通过名字动态解析未导出符号。
模块中调用前必须加判空:if (!addr) return -EINVAL;,否则触发 oops。


















