我有一个带处理器AT91SAM9G45的嵌入式ARM系统。我尝试为此系统使用initramfs构建linux内核。内核版本为4.14.79。
在设备上加载内核和initramfs映像后,我有以下内容:
内核肯定会找到initramfs映像,将其解压缩并将其设置到内存中。
内核定界符在initramfs映像中找到所有文件,我在添加到linux内核源代码中的调试消息中看到了它。
解压缩initramfs后,映像内核尝试启动/ init进程。 / init进程启动并立即返回0(0表示没有错误),然后立即引发内核恐慌消息:
释放未使用的内核内存:384K
此体系结构没有内核内存保护。
run_init_process在/ init之前
run_init_process之后/ init,结果= 0
内核恐慌-不同步:试图杀死init! exitcode = 0x00000004
“ run_init_process_BEFORE / init”和“ run_init_process / init,结果= 0”是我已添加到linux源代码中的调试消息。
Initramfs映像是通过使用busybox构建的。
我尝试启动的初始脚本或可执行文件没有区别。结果是一样的。如果/ init脚本试图回显某些消息并进入休眠状态几秒钟,则内核将不显示消息且不等待,并立即引发紧急消息。
所以我静态地编译了这个简单的程序并尝试启动它:
#include <stdio.h>
int main(int argc, char *argv)
{
printf("Hello world!\n");
sleep(999999999);
}
结果相同,没有“ Hello world!”而且没有睡觉:
释放未使用的内核内存:384K
此体系结构没有内核内存保护。
run_init_process在/ hello之前
run_init_process之后/ hello,结果= 0
内核恐慌-不同步:试图杀死init! exitcode = 0x00000004
如果我使用x86_64 gcc编译器编译该程序,结果为-8:
结果相同,没有“ Hello world!”和睡觉:
释放未使用的内核内存:384K
此体系结构没有内核内存保护。
run_init_process在/ hello之前
run_init_process之后/ hello,结果= -8
内核恐慌-不同步:试图杀死init! exitcode = 0x00000004
因此,这意味着linux内核定义了该文件在当前平台上是否可执行。
如果我在没有静态链接的情况下编译hello.c程序,则结果为-2(此后出现内核恐慌消息)。如果将.so文件放入/ lib文件夹的initramfs映像中,结果为0,并且此后出现内核恐慌消息。如果我将使用x86_64编译器编译的.so文件放入,结果为-13,然后出现内核恐慌消息。
那么此消息的原因是什么?我找不到它。
答案 0 :(得分:0)
退出代码是您从wait()中获得的代码。挖掘WEXITSTATUS和WTERMSIG定义,这意味着程序从信号4以状态0退出。 4是SIGILL-非法指令。
所以init程序出了点问题-它已损坏,或者处理器类型不正确,或者类似的问题。
它正在尝试执行导致处理器调用“非法指令”异常的代码。内核忠实地看到了这一点,并使用SIGILL杀死了有问题的程序。然后,它注意到init
和恐慌,因为现在没有任何可运行的内容。
答案 1 :(得分:0)
您使用了正确的交叉编译器吗?
就我而言,我使用下面的链接也通过QEMU引导ARM Linux,并且当我使用 arm-linux-gnueabihf-时,我遇到了相同的错误,退出代码0x00000004(即,硬-float)gcc编译器。
https://www.zachpfeffer.com/single-post/Build-the-Linux-kernel-and-Busybox-and-run-on-QEMU
当我使用 arm-linux-gnueabi-重新编译所有内容时,内核成功启动。请检查是否可以解决您的问题。