How to solve “FATAL: kernel too old” when running

2019-01-15 17:22发布

Ubuntu 17.10, C program:

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    puts("hello");
    return EXIT_SUCCESS;
}

gem5 version: da79d6c6cde0fbe5473ce868c9be4771160a003b dec 2017

GCC version:

$ sudo apt-get install gcc-arm-linux-gnueabi
$ arm-linux-gnueabi-gcc --version
arm-linux-gnueabi-gcc (Ubuntu/Linaro 7.2.0-6ubuntu1) 7.2.0

Compile and run:

./gem5/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./a.out
arm-linux-gnueabi-gcc -static kernel_module/user/hello.c

Outcome:

gem5 Simulator System.  http://gem5.org             
gem5 is copyrighted software; use the --copyright option for details.                                    

gem5 compiled Feb 23 2018 05:25:49                  
gem5 started Feb 24 2018 04:10:38                   
gem5 executing on ciro-p51, pid 3092                
command line: ./gem5/gem5/build/ARM/gem5.opt ./gem5/gem5/configs/example/se.py -c ./a.out                

Global frequency set at 1000000000000 ticks per second                                                   
warn: DRAM device capacity (8192 Mbytes) does not match the address range assigned (512 Mbytes)          
0: system.remote_gdb.listener: listening for remote gdb #0 on port 7000                                  
**** REAL SIMULATION ****                           
info: Entering event queue @ 0.  Starting simulation...                                                  
FATAL: kernel too old                               
warn: ignoring syscall rt_sigprocmask(...)          
      (further warnings will be suppressed)         
fatal: syscall gettid (#224) unimplemented.         
Memory Usage: 659680 KBytes 

Analogous on X86.

This has been asked over and over on the mailing lists, so let's centralize the discussion here and determine the best solution.

https://www.mail-archive.com/gem5-users@gem5.org/msg12385.html provides a good problem description:

Shortly after the beginning of _start(), the C library issues the uname() syscall to verify for the minimum kernel version. If you look at gem5/src/arch/arm/linux/process.cchttp://process.cc, you will see that in 32-bit mode the emulated syscall returns "3.0.0" and in 64, "3.7.0+". When you configured the toolchain in crosstool-ng, there is an option "CT_LIBC_GLIBC_MIN_KERNEL_VERSION". If that's greater than what the emulated uname() reports, glibc will fatal().

I have noticed that if I use the magic in-tree blob:

tests/test-progs/hello/bin/arm/linux/hello

so what is special about that blob, and how was it generated?

Allowed source version on the source code

823d9d177fded16af07114d70b5c26caaec6aa00 teaches us that the x86 point where the fake kernel version is defined is src/arch/x86/linux/process.cc.

unameFunc(SyscallDesc *desc, int callnum, Process *process,
    ...
    strcpy(name->release, "3.2.0");

Analogous grepping tells us that arm 32 was at 3.0 and 64 at 3.7.0.

crosstool-ng attempts

One promising possibility is to use crosstool-ng https://github.com/crosstool-ng/crosstool-ng to generate the compiler, which makes things more controlled.

As of ab3c204aee88f08481f1f63825d0e94b082ef84e I tried both of the following configs:

  • ./ct-ng arm-cortex_a15-linux-gnueabihf
  • ./ct-ng aarch64-unknown-linux-gnu

which compile for kernel 4.16 with GCC 8.1, and then static compilation fails on gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e respectively with:

fatal: syscall openat (#322) unimplemented.

and:

panic: Attempted to execute unimplemented instruction 'mrs' (inst 0x4d5380000)

but I don't really understand any of the failures:

  • openat was introduced in much older kernel 2.6.16, and it does not seem so exotic so why wouldn't it be implemented yet?

    We then can see on the source that it is implemented for 64 bit but is not implemented for 32 bit for some reason.

    I also tried to set the arm minimum kernel version to 3.2, but unsurprisingly it did not help.

  • why an instruction mrs wouldn't be implemented? The ARM reference says this instruction encoding ends in:

    1 1 0 1 0 1 0 1 0 0 1 1
    

    which is:

    d 5 2
    

    so maybe it matches the 0x4d5380000, but I'm not sure.

It would also be interesting to play around with different crosstool-ng settings, in particular the target kernel version, which at that revision defaults to the latest v4.16 to see if it solves the syscall problem.

Tested on gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e May 2018.

标签: gem5
1条回答
倾城 Initia
2楼-- · 2019-01-15 18:03

Ubuntu 18.04 with gem5 Oct 2018

After a few recent gem5 updates, a C hello world for all of x86, arm, aarch64 works with the pre-packaged Ubuntu toolchains. This is described in detail at: How to compile and run an executable in gem5 syscall emulation mode with se.py?

crosstool-ng x86_64-unknown-linux-gnu

Worked with gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e, ct-ng ab3c204aee88f08481f1f63825d0e94b082ef84e. Generates executables for old Linux kernel 3.2 according to file for some reason.

uclibc

This is likely a bad idea, but if we use crosstool-ng with uclibc instead of glibc:

./ct-ng aarch64-unknown-linux-uclibc

then that implementation does not have a kernel check, and the hello world works for all archs.

Also for some reason mrs was not used, so it must be a part of the glibc itself.

Of course, other unimplemented syscalls on more complex programs are bound to fail.

查看更多
登录 后发表回答