首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >上未调用的内置平台驱动程序__initcall

上未调用的内置平台驱动程序__initcall
EN

Stack Overflow用户
提问于 2021-02-12 05:34:57
回答 1查看 427关注 0票数 0

背景

我正在通过Yocto为一些供应商提供的嵌入式硬件提供一个Linux内核。我已经将映像配置为使用initramfs和没有rootfs (有持久存储,但这完全用于用户空间应用程序)通过fitImage引导。想想看PXE直播的形象,你就不会离得太远了。

事情一直进展顺利,直到我的initramfs图像超过了~128 my的标记。在此和所有的启动,如预期和所有驱动程序是没有问题的绑定。在这个标记和内核之上仍然启动,但是许多驱动程序,尽管不是全部,都是不绑定的。这是相当令人费解的,因为所有驱动程序都是静态地内置到内核中的(在这个平台上没有使用模块)。不幸的是,其中一个模块运行平台监视狗,这将导致完全可预测的重新启动。

到目前为止,我已经验证了vmlinux映像中存在的所有符号:

代码语言:javascript
复制
$ objdump -x vmlinux | grep mtk_wdt
0000000000000000 l    df *ABS*  0000000000000000 mtk_wdt.c
ffffff800880ac40 l     F .text  000000000000004c mtk_wdt_stop
ffffff800880ac90 l     F .text  0000000000000040 mtk_wdt_shutdown
ffffff80091de778 l     F .init.text     0000000000000020 mtk_wdt_driver_init
ffffff800880acd0 l     F .text  000000000000004c mtk_wdt_ping
ffffff800880ad20 l     F .text  0000000000000070 mtk_wdt_set_timeout
ffffff800880ad90 l     F .text  0000000000000074 mtk_wdt_start
ffffff800880ae08 l     F .text  0000000000000144 mtk_wdt_resume
ffffff800880af50 l     F .text  0000000000000120 mtk_wdt_suspend
ffffff800880b070 l     F .text  0000000000000080 mtk_wdt_remove
ffffff80088977a8 l     F .text  0000000000000210 mtk_wdt_isr
ffffff80091fe0a0 l     F .exit.text     000000000000001c mtk_wdt_driver_exit
ffffff800880b4f0 l     F .text  0000000000000310 mtk_wdt_probe
ffffff8008c2acd8 l     O .rodata        0000000000000028 mtk_wdt_info
ffffff8008c2ad00 l     O .rodata        0000000000000050 mtk_wdt_ops
ffffff8008c2ad98 l     O .rodata        00000000000000b8 mtk_wdt_pm_ops
ffffff8008c2ae50 l     O .rodata        0000000000000190 mtk_wdt_dt_ids
ffffff80093a3cb8 l     O .data  00000000000000b0 mtk_wdt_driver
ffffff800a199368 l     O .bss   0000000000000008 mtk_wdt1
ffffff8009285598 l     O .init.data     0000000000000008 __initcall_mtk_wdt_driver_init6

此外,我还有二进制内核的sha256校验和(例如。( linux.bin)、initramfs和设备树在fitImage程序集之前、fitImage组装之后和解压缩到系统内存后(通过引导加载程序);全部匹配。据我所知,构建的是什么被解压和引导。

此外,我还启用了initcall_debug,虽然我看到了其他的__initcall(),但非绑定驱动程序却不见了,这是不足为奇的。

我知道设备存在于设备树中,并且配置正确。启动后,在看门狗启动之前,我有大约5秒的控制台访问时间;只需花费足够的时间获得一两条命令即可。在“工作”映像(initramfs <~128 my )和失败映像(initramfs >~128 my)上,/sys/bus/platform/devices的内容是相同的,我可以看到(除其他外),我的看门狗:

代码语言:javascript
复制
$ ls -lha /sys/bus/platform/devices
...
lrwxrwxrwx 1 root root 0 Jan  1 00:00 10007000.watchdog -> ../../../devices/platform/10007000.watchdog

执行相同的测试,但比较/sys/bus/platform/devices显示没有__initcall()ed的驱动程序丢失。

其他一些我检查过的东西:

  • 设备树。同样的DTB用于工作图像和破碎图像。如前所述,我还验证了内存中的设备树.不使用设备树覆盖。
  • 实际内存负载抵消了。每件事都应该在哪里,每个地区都有足够的空间。我可以在内存中移动内核,无论位置如何,问题都会持续存在。
  • 不良记忆.此故障在多个单元中相同发生。
  • 坏压缩。这个问题不受内核/ initramfs压缩的影响。目前,我正在测试的所有未压缩的,以尽量减少断点。
  • Bad签署。我已经禁用了签名验证(最终应用于fitImage分区映像);那里也没有骰子。
  • 试图将initramfs直接捆绑到内核中。没有变化。现在,我有内置在fitImage中的initramfs,但以其他方式独立加载和验证。
  • 坏内核命令行参数。我正在使用root=/dev/ram initrd=0x48000000,384M,并一直跟踪到init/initramfs.c,在那里进行解压缩。我能够验证所传递的偏移量确实在正确的虚拟内存空间中,并且之和为384米。
  • 根据 论坛发布更新内核链接器脚本。我能够看到通过objdump在vmlinux中生成的.initramfs部分,但是问题仍然存在。

鉴于以上所述,我唯一不知道如何验证的就是从vmlinux跳转到linux.bin。这在Yocto通过讣告完成,如下所示:

代码语言:javascript
复制
[ -n "${vmlinux_path}" ] && ${OBJCOPY} -O binary -R .note -R .comment -S "${vmlinux_path}" linux.bin

问题

  1. 如何验证最终的linux.bin中包含了给定的符号?
  2. 什么机制会影响在构建时包含或排除给定的符号?
  3. 内核构建和运行时的哪些部分受initramfs大小的影响?
  4. 还有其他工具/技术/部落智慧可以帮助调试这种情况吗?

编辑1

下面是基本的内存地图,所有的土地和空间利用。如前所述和注释中,我可以将内核、DTB和initramfs重新定位到(几乎)任意位置,但问题仍然存在。

代码语言:javascript
复制
0x40000000 - 0x40001000 = Bootloader arg area (Fixed usage)
0x40080000 - 0x41EDFFFF = Kernel (~12MB / 29.5MB used)
0x41E00000 - 0x42FF5FFF = Trampoline (96 bytes / ~6MB used)
0x42FF6000 - 0x42FFFFFF = ATF BL3-1 (Fixed usage)
0x43000000 - 0x43FFFFFF = Trusted OS (~476K / 16M used)
0x44000000 - 0x44FFFFFF = DTB (~77.3K / 16M used)
0x45000000 - 0x47FFFFFF = Trusted OS memory (dynamic)
0x48000000 - 0x5FFFFFFF = Initramfs (~129MB / 384MB used)
0x60000000 - MEM END    = Free
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-02-13 23:24:29

因此,和大多数内核问题一样,真正的问题不是我想象的那样。事实证明,这一问题是由早先在init列表中挂着核心的其他司机之一造成的,阻止了看门狗司机注册。这如何受到initramfs的影响是我无法理解的,也是它自己的问题。

对于将来遇到这种情况的人,我以上具体问题的答案如下:

  1. 如何验证最终的linux.bin?中包含了给定的符号

我不知道如何静态地做这件事。也就是说,我能够在运行时通过将printk()s添加到do_initcall_level中的init/main.c中来打印init函数的地址。然后,打印的地址可以与vmlinux上的objdump输出进行比较(关于咒语,请参阅我的问题)。

一个非常有用和深入的描述initcall进程可以找到这里

请注意,您还可以打开initcall_debug,它将打印每个函数名。在我的例子中,我需要原始地址,这就是我选择printk()方法的原因。

  1. 在构建时,哪些机制会影响给定符号的包含或排除?

这其中的大部分归结为您的.config。绝大多数包含/排除是通过预处理器完成的。其他有用的项目是include/asm-generic/vmlinux.lds.h的链接器脚本公共标头和设备arch/<arch>/*/*.lds的平台链接器脚本。

  1. 内核构建和运行时的哪些部分受initramfs大小的影响?

还是不知道这件事。

  1. 还有其他工具/技术/部落智慧可以帮助调试这种情况吗?

不要惊慌

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66166820

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档