Как решить "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/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.

Конечно, другие невыполненные системные вызовы в более сложных программах обречены на провал.

Другие вопросы по тегам