如何解决“致命的:内核太老了"?在syscall仿真SE模式下运行gem5时? [英] How to solve "FATAL: kernel too old" when running gem5 in syscall emulation SE mode?
问题描述
Ubuntu 17.10,C程序:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
puts("hello");
return EXIT_SUCCESS;
}
gem5版本:da79d6c6cde0fbe5473ce868c9be4771160a003b 2017年12月
GCC版本:
$ 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() syscall验证最低内核版本. 如果您查看gem5/src/arch/arm/linux/process.cc http://process.cc ,将要 看到在32位模式下,仿真的syscall返回"3.0.0",而在64位模式下, "3.7.0+". 在crosstool-ng中配置工具链时,有一个选项 "CT_LIBC_GLIBC_MIN_KERNEL_VERSION". 如果该值大于模拟的uname()报告的值,则glibc将致命().
我注意到,如果我使用魔术树内斑点:
tests/test-progs/hello/bin/arm/linux/hello
那么那个blob有什么特别之处,以及它是如何产生的?
允许在源代码上使用源版本
823d9d177fded16af07114d70b5c26caaec6aa00告诉我们,伪造的内核版本定义的x86点是 类似的grepping告诉我们,第32组的臂数为3.0,而第64组的臂数为3.7.0. 一种有前途的可能性是使用crosstool-ng https://github.com/crosstool- ng/crosstool-ng 生成编译器,这使事情得到了更好的控制. 从ab3c204aee88f08481f1f63825d0e94b082ef84e开始,我尝试了以下两个配置: 使用GCC 8.1为内核4.16编译,然后在gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e上的静态编译失败,分别为: 和: 但是我真的不理解任何失败: 然后我们可以在源上看到它. 我还尝试将arm的最低内核版本设置为3.2,但不足为奇的是. 为什么不会执行指令 这是: 所以它可能与 尝试使用不同的crosstool-ng设置(特别是目标内核版本)也很有趣,该版本在该版本中默认为最新的v4.16,以查看是否解决了系统调用问题. 已于2018年5月在gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e上进行测试. 更新gem5 May 2019 合并补丁后 https://gem5-review .googlesource.com/c/public/gem5/+/17849 现在可以通过以下方式简单地解决"该问题: 然后,您应该设置与您的工具链或更高版本匹配的内核版本. 我不知道如何轻松找到Ubuntu预构建跨工具链的最小值,但是您可以尝试设置最新的内核版本,或者也许是 版本太新可能会导致glibc使用尚未在gem5中实现的可选新内核功能,但这是不常见的. Ubuntu 18.04 with gem5 Oct 2018 最近对gem5进行了一些更新之后,所有x86,arm,aarch64的C hello世界都可以与预包装的Ubuntu工具链一起使用.有关详细信息,请参见:如何在带有se.py的gem5 syscall仿真模式下编译和运行可执行文件? 当然,在更复杂的程序上的其他未实现的系统调用注定会失败. Ubuntu 17.10, C program: gem5 version: da79d6c6cde0fbe5473ce868c9be4771160a003b dec 2017 GCC version: Compile and run: Outcome: 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: 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 Analogous grepping tells us that arm 32 was at 3.0 and 64 at 3.7.0. 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: which compile for kernel 4.16 with GCC 8.1, and then static compilation fails on gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e respectively with: and: but I don't really understand any of the failures: 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 which is: so maybe it matches the 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. update gem5 May 2019 After the merging of the patch https://gem5-review.googlesource.com/c/public/gem5/+/17849 it is now possible to "fix" the problem simply with: You should then set a kernel version that matches your toolchain or newer. I don't know how to find the minimal value easily for Ubuntu prebuild cross toolchains, but you could just try setting the newest kernel release, or maybe A version being too new might result in glibc using optional new kernel features not yet implemented in gem5, but this is not common I believe. 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 uclibc This is likely a bad idea, but if we use crosstool-ng with uclibc instead of glibc: then that implementation does not have a kernel check, and the hello world works for all archs. Also for some reason Of course, other unimplemented syscalls on more complex programs are bound to fail. 这篇关于如何解决“致命的:内核太老了"?在syscall仿真SE模式下运行gem5时?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!crosstool-ng
次尝试
./ct-ng arm-cortex_a15-linux-gnueabihf
./ct-ng aarch64-unknown-linux-gnu
fatal: syscall openat (#322) unimplemented.
panic: Attempted to execute unimplemented instruction 'mrs' (inst 0x4d5380000)
openat
是在较早的内核2.6.16中引入的,它似乎并不那么奇特,所以为什么还不实现呢?mrs
? ARM参考资料指出,该指令编码的结尾是:1 1 0 1 0 1 0 1 0 0 1 1
d 5 2
0x4d5380000
匹配,但是我不确定. gem5.opt se.py --param 'system.cpu[0].workload[:].release = "4.18.0"'
99.99.99
.#include <stdio.h>
#include <stdlib.h>
int main(void) {
puts("hello");
return EXIT_SUCCESS;
}
$ 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
tests/test-progs/hello/bin/arm/linux/hello
src/arch/x86/linux/process.cc
.unameFunc(SyscallDesc *desc, int callnum, Process *process,
...
strcpy(name->release, "3.2.0");
crosstool-ng
attempts
./ct-ng arm-cortex_a15-linux-gnueabihf
./ct-ng aarch64-unknown-linux-gnu
fatal: syscall openat (#322) unimplemented.
panic: Attempted to execute unimplemented instruction 'mrs' (inst 0x4d5380000)
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?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
d 5 2
0x4d5380000
, but I'm not sure. gem5.opt se.py --param 'system.cpu[0].workload[:].release = "4.18.0"'
99.99.99
.file
for some reason../ct-ng aarch64-unknown-linux-uclibc
mrs
was not used in that case because glibc tends to use more features on it's pre-main functions. That problem was however solved on a later commit as mentioned at: How to compile and run an executable in gem5 syscall emulation mode with se.py?