Как решить "FATAL: ядро слишком старое" при запуске gem5 в режиме SE эмуляции syscall?
Программа Ubuntu 17.10, C:
#include <stdio.h>
#include <stdlib.h>
int main(void) {
puts("hello");
return EXIT_SUCCESS;
}
Версия gem5: da79d6c6cde0fbe5473ce868c9be4771160a003b декабрь 2017
Версия 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/, то увидите, что в 32-битном режиме эмулируемый системный вызов возвращает "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
Так что же особенного в этом сгустке и как он был создан?
Разрешенная исходная версия в исходном коде
823d9d177fded16af07114d70b5c26caaec6aa00 учит нас, что точка x86, где определяется поддельная версия ядра, src/arch/x86/linux/process.cc
,
unameFunc(SyscallDesc *desc, int callnum, Process *process,
...
strcpy(name->release, "3.2.0");
Аналогичная оценка говорит нам, что рука 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
который компилируется для ядра 4.16 с GCC 8.1, а затем статическая компиляция завершается неудачно на 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, чтобы посмотреть, решает ли она проблему системного вызова.
Проверено на gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e Май 2018 года.
1 ответ
Ubuntu 18.04 с gem5 окт 2018
После нескольких недавних обновлений gem5, C Hello World для всех x86, arm, aarch64 работает с предварительно упакованными наборами инструментов Ubuntu. Это подробно описано по адресу: Как скомпилировать и запустить исполняемый файл в режиме эмуляции syscall gem5 с помощью se.py?
crosstool-ng x86_64-unknown-linux-gnu
Работал с gem5 49f96e7b77925837aa5bc84d4c3453ab5f07408e, ct-ng ab3c204aee88f08481f1f63825d0e94b082ef84e. Генерирует исполняемые файлы для старого ядра Linux 3.2 в соответствии с file
по какой-то причине.
uclibc
Вероятно, это плохая идея, но если мы используем crosstool-ng с uclibc вместо glibc:
./ct-ng aarch64-unknown-linux-uclibc
тогда эта реализация не имеет проверки ядра, и hello world работает для всех архитектур.
Также по какой-то причине mrs
не был использован, поэтому он должен быть частью самого glibc.
Конечно, другие невыполненные системные вызовы в более сложных программах обречены на провал.