首页 > 解决方案 > /init 后退出代码 = 0x00000004 的内核恐慌

问题描述

我有一个带有处理器 AT91SAM9G45 的嵌入式 ARM 系统。我尝试为这个系统构建带有 initramfs 的 linux 内核。内核版本是 4.14.79。

在设备上加载内核和 initramfs 映像后,我有以下内容:

  1. 内核肯定会找到 initramfs 映像,将其解压缩并将其设置到内存中。

  2. 内核定义在 initramfs 映像中找到所有文件,我在添加到 linux 内核源代码中的调试消息中看到它。

  3. 解压 initramfs 映像内核后尝试启动 /init 进程。/init 进程启动并立即返回 0(0 表示没有错误),然后立即抛出内核恐慌消息:

释放未使用的内核内存:384K

这种架构没有内核内存保护。

在 /init 之前运行_init_process

在 /init 之后运行_init_process,结果 = 0

内核恐慌 - 不同步:试图杀死 init!退出代码=0x00000004

"run_init_process_BEFORE /init" 和 "run_init_process /init, result = 0" 是我添加到 linux 源代码中的调试消息。

Initramfs 镜像是使用busybox 构建的。

没有区别,我尝试启动的初始脚本或可执行文件是什么。结果是一样的。如果 /init 脚本尝试回显某些消息并休眠几秒钟,内核不会显示消息并且不会等待,并立即抛出恐慌消息。

所以我静态编译了这个简单的程序并尝试启动它:

#include <stdio.h>

int main(int argc, char *argv)
{
  printf("Hello world!\n");
  sleep(999999999);
}

结果相同,没有“Hello world!” 并且没有睡觉:

释放未使用的内核内存:384K

这种架构没有内核内存保护。

在 /hello 之前运行_init_process

在 /hello 之后运行_init_process,结果 = 0

内核恐慌 - 不同步:试图杀死 init!退出代码=0x00000004

如果我用 x86_64 gcc 编译器编译这个程序,结果是 -8:

结果相同,没有“Hello world!” 和睡觉:

释放未使用的内核内存:384K

这种架构没有内核内存保护。

在 /hello 之前运行_init_process

在 /hello 之后运行_init_process,结果 = -8

内核恐慌 - 不同步:试图杀死 init!退出代码=0x00000004

所以这意味着linux内核定义了文件在当前平台是否可执行。

如果我在没有静态链接的情况下编译 hello.c 程序,结果为 -2(以及此后的内核恐慌消息)。如果我将 .so 文件放入 /lib 文件夹中的 initramfs 映像中,结果为 0,并且在此之后出现内核恐慌消息。如果我放置使用 x86_64 编译器编译的 .so 文件,结果为 -13,并且在此之后出现内核恐慌消息。

那么这个消息的原因是什么?我找不到它。

标签: linux-kernelarmembedded-linuxpanic

解决方案


exitcode 是你从 wait() 得到的。挖掘 WEXITSTATUS 和 WTERMSIG 定义,这意味着程序以信号 4 的状态 0 退出。 4 是 SIGILL - 非法指令。

所以init程序出了点问题——它被破坏了,或者处理器类型错误,或者类似的东西。

它试图执行导致处理器调用“非法指令”异常的代码。内核尽职尽责地看到这一点并使用 SIGILL 杀死有问题的程序。然后它注意到那是init并且恐慌,因为现在没有什么可以运行了。


推荐阅读