2
votes

I have an embedded ARM system with processor AT91SAM9G45. I try to build linux kernel with initramfs for this system. Kernel version is 4.14.79.

After loading kernel and initramfs image at device I have following:

  1. Kernel definitely finds out initramfs image, unpacks it and sets it into memory.

  2. Kernel definityle finds all files in initramfs image, I see it in debug messages I've added into linux kernel source code.

  3. After unpacking initramfs image kernel tries to start /init process. /init processes starts and instantly returns 0 (0 means no errors) and then instantly throws kernel panic message:

Freeing unused kernel memory: 384K

This architecture does not have kernel memory protection.

run_init_process BEFORE /init

run_init_process AFTER /init, result = 0

Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004

"run_init_process_BEFORE /init" and "run_init_process /init, result = 0" are debug messages that I've added to linux source code.

Initramfs image is build by using busybox.

There is no difference, what an initial script or executable file I try to start. Results are same. If /init script tries to echo some message and sleep for some seconds, kernel does not show message and does not wait, and throws panic message instantly.

So I compiled statically this simple program and tried to start it:

#include <stdio.h>

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

Same result, with no "Hello world!" and with no sleeping:

Freeing unused kernel memory: 384K

This architecture does not have kernel memory protection.

run_init_process BEFORE /hello

run_init_process AFTER /hello, result = 0

Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004

If I compile this program with x86_64 gcc compiler, result is -8:

Same result, with no "Hello world!" and sleeping:

Freeing unused kernel memory: 384K

This architecture does not have kernel memory protection.

run_init_process BEFORE /hello

run_init_process AFTER /hello, result = -8

Kernel panic - not syncing: Attempted to kill init! exitcode=0x00000004

So it means that linux kernel defines whether the file is executable at current platform.

If I compile hello.c program with no static linking, result is -2 (and kernel panic message after this). If I put .so files into initramfs image at the /lib folder, result is 0, and kernel panic message after this. If I put .so files that are compiled with x86_64 compiler, result is -13, and kernel panic message after this.

So what's the reason of this message? I cannot find it out.

2
Comments are not for extended discussion; this conversation has been moved to chat.Samuel Liew♦

2 Answers

2
votes

The exitcode is what you would get from wait(). Digging for WEXITSTATUS and WTERMSIG definitions, this means the program exited with status 0 from signal 4. 4 is SIGILL - illegal instruction.

So something's wrong with the init program - it's corrupted, or for the wrong processor type, or something like that.

It's trying to execute code that causes the processor to invoke an "illegal instruction" exception. The kernel dutifully sees this and kills the offending program with a SIGILL. Then it notices that was init and panics because now there is nothing to run.

1
votes

Did you use the right cross-compiler?

In my case, I followed the link below too boot ARM Linux over QEMU and I was getting the same error with exit code 0x00000004, when I used arm-linux-gnueabihf- (i.e., hard-float) gcc compiler.

https://www.zachpfeffer.com/single-post/Build-the-Linux-kernel-and-Busybox-and-run-on-QEMU

When I recompiled everything with arm-linux-gnueabi-, the kernel booted successfully. Please check if this resolves your problem.