2017-02-17 33 views
3

Я выполняю ряд действий, чтобы убедиться, что Redis хорошо работает в комплекте встроенных систем, в том числе с малиной PI. Чтобы исправить определенные пути кода Redis, где выполняются нерациональные обращения к памяти (из-за изменения, внесенного в Redis 3.2), я пытаюсь заставить PI либо регистрировать сообщение на неуправляемых обращениях к памяти, либо посылать сигнал процессу, когда Бывает. Таким образом, я могу убедиться, что Redis будет работать хорошо, если неприглаженные обращения являются нарушением, и что он будет работать быстрее на платформах, где вместо этого такие обращения могут выполняться, но медленнее. ARM v6, он используется в PI v1, по-видимому, в состоянии иметь дело с выровненным доступа к памяти, поэтому, если я использую следующую команду, чтобы настроить Linux, чтобы отправить сигнал в процессе выполнения невыровненное доступа:Unaligned accesses не обнаружены Raspberry PI версии 1

echo 4 > /proc/cpu/alignment 

И затем выполнить следующую программу:

#include <stdio.h> 
#include <stdint.h> 

int main(int argc, char **argv) { 
    char *buf = "foobareklsjdfklsjdfslkjfskdljfskdfjdslkjfdslkjfsd"; 
    uint32_t *l = (uint32_t*) (buf+1); 
    printf("%p\n", l); 
    printf("%d\n", (int)*l); 
    return 0; 
} 

Я не могу увидеть любой сигнал, полученный с помощью процесса, или счетчиков на /proc/cpu/alignment инкрементирования.

Мое предположение заключается в том, что это связано с тем, что ARM v6 автоматически справляется с несогласованными адресами, если установлен заданный флаг конфигурации ЦП. Мой вопрос в том, правильно ли моя гипотеза? И если это так, то как заставить PI-версию 1 на самом деле создать исключение в случае неприсоединения доступа, чтобы ядро ​​Linux могло его захватить и отправить сигнал, зарегистрировать доступ и т. Д. Согласно/proc/cpu/alignment настройки?

EDIT: Следует отметить, что не все инструкции могут выполнять неравномерные обращения даже в ARM v6. Например, STMDB, STMFD, LDMDB, LDMEA и аналогичные инструкции с несколькими словами действительно вызовут исключение и будут захвачены ядром Linux.

ответ

4

Я думаю, что я в конце концов нашел мои ответы:

  1. Да я правильно, до размера слова ARM v6 (или больше) может молча обрабатывать выровненный доступ к такому не генерируется ловушка, и является полностью прозрачным для ядра Linux. Ничего не будет зарегистрировано, и счетчик ловушек в /proc/cpu/alignment будет увеличиваться.
  2. AFAIK. Я не могу заставить ядро ​​улавливать неодинаковый доступ к размеру слов, поскольку для этого, по-видимому, должен быть сконфигурирован процессор, чтобы улавливать несогласованные адреса в каждом случае, но ядро ​​Linux не делает что AFAIK, вероятно, потому, что внутри самого ядра есть небезопасный код выравнивания. Проверка исходного кода ядра Linux действительно можно увидеть:

    if (cpu_is_v6_unaligned()) { 
         set_cr(__clear_cr(CR_A)); 
         ai_usermode = safe_usermode(ai_usermode, false); 
    } 
    

    Что это означает, что бит SCTLR.A всегда очищается, поэтому не ловушка не будет генерироваться для выровненным доступ ARM v6 может справиться.

  3. Существует множество инструкций, которые будут генерировать ловушки при использовании с неуправляемыми адресами, например, несколько инструкций хранения/загрузки, загрузка и сохранение двойных значений.

  4. Однако есть указания, что GCC (версия поставляется по умолчанию в дистрибутиве малин Linux) будет счастливо произведенными , не обрабатываемые в Linux ядре правильно, которые приведут к SIGBUS генерируемого даже когда /proc/cpu/alignment установлен в исправить доступ.

Так пункт № 4 в основном означает, что, это не очень хорошая идея, чтобы установить программы для запуска в ARM v6 просто позволить ядру Linux обрабатывать невыровненные адреса для нас, даже когда последствия производительности выровненным адресов являются не проблема: программа все еще может потерпеть крах, так как не все инструкции обрабатываются.

Как надежно найти все неравномерные обращения в программе остается открытым вопросом AFAIK, так как, к сожалению, в противном случае замечательная программа valgrind, никогда не реализовывала эту функцию. Раньше мне приходилось использовать QEMU для эмуляции Sparc, однако это очень медленный процесс. Валгринд был бы тривиальным способом сделать это.

+1

ARMv4 и v5 также допускаются для неравномерных доступов, некоторые рычаги управления по умолчанию включены другими, а в любом случае вы можете включить или отключить его. Более старшее поведение ядра для неприсоединения доступа было другим/странным для того, что можно было бы ожидать, оно вращало байты вокруг слова, а не погружалось бы в следующий адрес. Это имеет смысл, так как вы получаете правый байт на нулевой байт-полосе для доступа к байтам (или полуслову), более чем один способ скинуть этот кот. –

+1

Обратите внимание, что вы можете получить x86 для ловушки при неправильном доступе в Linux, если вы просто хотите найти несовместимые обращения вообще в программном обеспечении, а не специально для ARM. – EOF

+0

EOF да, я обнаружил, что если вы имеете в виду регистр AC. Однако я не нашел надежного способа обмануть его в своей программе, если не с помощью команды gdb set. – antirez

 Смежные вопросы

  • Нет связанных вопросов^_^