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() システムコールを発行して、最小カーネル バージョンを確認します。gem5/src/arch/arm/linux/process.cc http://process.ccを見ると、エミュレートされた syscall が 32 ビット モードで「3.0.0」を返し、64 で「3.7. 0+」。crosstool-ng でツールチェーンを設定すると、オプション「CT_LIBC_GLIBC_MIN_KERNEL_VERSION」があります。それがエミュレートされた uname() のレポートよりも大きい場合、glibc は fatal() を実行します。
魔法のツリー内ブロブを使用すると、次のことに気付きました。
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");
同様の grep は、アーム 32 が 3.0 で、アーム 64 が 3.7.0 であったことを示しています。
crosstool-ng
試み
有望な可能性の 1 つは、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 月でテスト済み。