在系统调用仿真SE模式下运行gem5时如何解决"FATAL: kernel too old"?



Ubuntu 17.10, C 程序:

#include <stdio.h>
#include <stdlib.h>
int main(void) {
puts("hello");
return EXIT_SUCCESS;
}

GEM5 版本: DA79d6C6CDE0FBE5473CE868C9BE4771160A003B 2017 年 12 月

海湾合作委员会版本:

$ 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

编译并运行:

./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

结果:

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 

类似于 X86。

这在邮件列表中已经一遍又一遍地被问到,所以让我们在这里集中讨论并确定最佳解决方案。

  • https://www.mail-archive.com/gem5-users@gem5.org/msg13772.html
  • https://www.mail-archive.com/gem5-users@gem5.org/msg12385.html
  • https://www.mail-archive.com/gem5-users@gem5.org/msg12383.html
  • https://www.mail-archive.com/gem5-users@gem5.org/msg05538.html

https://www.mail-archive.com/gem5-users@gem5.org/msg12385.html 提供了一个很好的问题描述:

在 _start() 开始后不久,C 库发出 uname() 系统调用以验证最低内核版本。 如果你看一下gem5/src/arch/arm/linux/process.cchttp://process.cc,你会 看到在 32 位模式下,模拟的系统调用返回"3.0.0",而在 64 位模式下, "3.7.0+". 在crosstool-ng中配置工具链时,有一个选项 "CT_LIBC_GLIBC_MIN_KERNEL_VERSION"。 如果这大于模拟的 uname() 报告的内容,glibc 将 fatal()。

我注意到,如果我使用神奇的树内 blob:

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

那么这个斑点有什么特别之处,它是如何生成的呢?

源代码上允许的源版本

823d9d177fded16af07114d70b5c26caaec6aa00 告诉我们,定义假内核版本的 x86 点是src/arch/x86/linux/process.cc.

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

类似的 grepping 告诉我们,第 32 臂在 3.0,64 在 3.7.0。

crosstool-ng尝试

一个有希望的可能性是使用 crosstool-ng https://github.com/crosstool-ng/crosstool-ng 来生成编译器,这使得事情更加可控。

截至 ab3c204aee88f08481f1f63825d0e94b082ef84e 我尝试了以下两种配置:

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

使用 GCC 8.1 编译内核 4.16,然后在 gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e 上静态编译失败:

fatal: syscall openat (#322) unimplemented.

和:

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

但我真的不明白任何失败

  • openat是在更旧的内核 2.6.16 中引入的,它看起来并不那么奇特,那么为什么它还没有实现呢?

    然后我们可以在源代码上看到它是为 64 位实现的,但由于某种原因没有实现为 32 位。

    我还尝试将 arm 最低内核版本设置为 3.2,但不出所料,它没有帮助。

  • 为什么指令mrs不会实现?ARM 参考说此指令编码以以下方式结尾:

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

    即:

    d 5 2
    

    所以也许它与0x4d5380000相匹配,但我不确定。

尝试不同的 crosstool-ng 设置也会很有趣,特别是目标内核版本,在该修订版中默认为最新的 v4.16,以查看它是否解决了 syscall 问题。

在 gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e 上测试,2018 年 5 月

更新 gem5 May 2019

合并补丁 https://gem5-review.googlesource.com/c/public/gem5/+/17849 后,现在可以简单地"修复"问题:

gem5.opt se.py --param 'system.cpu[0].workload[:].release = "4.18.0"'

然后,您应该设置与您的工具链匹配或更新的内核版本。

我不知道如何轻松找到 Ubuntu 预构建跨工具链的最小值,但您可以尝试设置最新的内核版本,或者99.99.99.

版本太新可能会导致 glibc 使用 gem5 中尚未实现的可选新内核功能,但我相信这并不常见。

Ubuntu 18.04 with gem5 Oct 2018

在最近的一些 gem5 更新之后,一个适用于所有 x86、arm、aarch64 的 C hello 世界与预打包的 Ubuntu 工具链一起工作。这在以下位置有详细说明:如何使用 se.py 在 gem5 系统调用仿真模式下编译和运行可执行文件?

Crosstool-ng x86_64-unknown-linux-gnu

使用 gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e, ct-ng ab3c204aee88f08481f1f63825d0e94b082ef84e.出于某种原因,根据file为旧的 Linux 内核 3.2 生成可执行文件。

乌利布克

这可能是一个坏主意,但如果我们将 crosstool-ng 与 uclibc 一起使用而不是 glibc:

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

然后该实现没有内核检查,并且 hello world 适用于所有 Arch。

同样由于某种原因,在这种情况下没有使用mrs因为glibc倾向于在其pre-main函数上使用更多功能。但是,该问题在以后的提交中得到了解决,如中所述:如何使用 se.py 在gem5系统调用仿真模式下编译和运行可执行文件?

当然,在更复杂的程序上,其他未实现的系统调用注定会失败。

相关内容

最新更新