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.cc http://process.cc,您将看到在 32 位模式下,模拟的系统调用返回“3.0.0”,而在 64 位模式下,则返回“3.7. 0+”。在 crosstool-ng 中配置工具链时,有一个选项“CT_LIBC_GLIBC_MIN_KERNEL_VERSION”。如果这大于模拟的 uname() 报告的值,glibc 将致命()。
我注意到,如果我使用魔法树内 blob:
tests/test-progs/hello/bin/arm/linux/hello
那么这个blob有什么特别之处,它是如何生成的?
源代码上允许的源版本
823d9d177fded16af07114d70b5c26caaec6aa00 告诉我们,定义假内核版本的 x86 点是src/arch/x86/linux/process.cc
.
unameFunc(SyscallDesc *desc, int callnum, Process *process,
...
strcpy(name->release, "3.2.0");
类似的 grepping 告诉我们,arm 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,看看它是否解决了系统调用问题。
于 2018 年 5 月在 gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e 上测试。