SIGBUS на ARM Cortex при доступе к внешнему устройству

У меня есть Zynq UltraScale MPSoC с четырехъядерным процессором ARM Cortex, работающим под управлением Linux. Иногда происходит событие, которое генерирует ошибку SIGBUS. Я включил фрагмент анализа отладки ниже. Я был уверен, что значения dst и src находятся в законных регионах. Сам фактический доступ - это процедура копирования из ресурса памяти FPGA во внутреннюю область памяти ARM.

Я прочитал в другом посте, что причиной SIGBUS может быть сбой ввода-вывода. Может кто-нибудь рассказать о том, что "ошибка ввода / вывода" относится к ARM? Я предполагаю, что-то похожее на отказавший автобус признают.

Относительно ARM Cortex, есть ли эквивалент регистра проверки машины, который может дать дополнительное представление о причине SIGBUS?

#0 ecfm_copy_table_entry_backward (dst=dst@entry=0xee189830, src=<optimized out>, num_words=num_words@entry=72) at src/software/saos-sds/ecfm_driver/ecfm_driver.c:478
#1 0xf658347c in ecfm_copy_table_entry_backward (num_words=72, src=<optimized out>, dst=0xee189830) at src/software/saos-sds/ecfm_driver/ecfm_driver.c:1186
#2 ecfm_get_rx_stats (session_id=session_id@entry=2637, stat=stat@entry=0xee189830) at src/software/saos-sds/ecfm_driver/ecfm_driver.c:1185
#3 0x011c463c in eCfmApiGetRxProcessingStats (sessionId=<optimized out>, stat=0xee1898e0) at src/software/saos-sds/leos/platform/common/src/eCfmApi.c:1836
#4 0x011d6aac in halFPGAGetStats (pPlatformData=pPlatformData@entry=0xe7f98abc, lossStats=0xee1899a8, lossStats@entry=0xee1899a0)
at src/software/saos-sds/leos/platform/common/src/halEcfmFpgaApi.c:2214
#5 0x00a71870 in cfmAgentReadHwStats (data=0xe7f98a70, role=<optimized out>, testType=<optimized out>) at src/software/saos-sds/leos/common/src/genericSwitch/cfm/src/cfmApal.c:1760
#6 0x009fd39c in cfmTestSessionSmiSmEvent (pSession=0xe7f98a70, event=event@entry=CfmTestSmiEvent_DeltaTComplete)
at src/software/saos-sds/leos/common/src/genericSwitch/cfm/src/cfm.c:26242
#7 0x00a75f04 in cfmApalOamFpgaSessionStatusIntHdlr (context=<optimized out>, pMsg=<optimized out>) at src/software/saos-sds/leos/common/src/genericSwitch/cfm/src/cfmApal.c:2461
#8 cfmApalOamFpgaHalY1731IntHdlr (context=<optimized out>, pMsg=0x37b7768 <__func__.44940>) at src/software/saos-sds/leos/common/src/genericSwitch/cfm/src/cfmApal.c:2548
#9 0x00a7cf04 in oamMsgDispatchMsgList (msgList=msgList@entry=0x68dfae8, pMsgContext=pMsgContext@entry=0xee189bc8)
at src/software/saos-sds/leos/common/src/genericSwitch/cfm/src/oamMsg.c:92
#10 0x00a76e50 in cfmHalDispatchMsgList (cpe=<optimized out>, msgList=msgList@entry=0x68dfae8) at src/software/saos-sds/leos/common/src/genericSwitch/cfm/src/cfmApal.c:594
#11 0x00a8f2cc in CfmAgentMsgHdlr (sig=<optimized out>) at src/software/saos-sds/leos/common/src/genericSwitch/cfm/src/cfmAgent.c:1335
#12 0x00a9045c in cfmAgentTmoHdlr (cycle=<optimized out>, extraProcTimeMs=0) at src/software/saos-sds/leos/common/src/genericSwitch/cfm/src/cfmAgent.c:1383
#13 0x00a90598 in cfmAgentMain (arg=<optimized out>) at src/software/saos-sds/leos/common/src/genericSwitch/cfm/src/cfmAgent.c:1441
#14 0x0112ea8c in thread_prologue (arg=<optimized out>) at src/software/saos-sds/leos/os/linux/src/ose_shim.c:1273
#15 0xf704af8c in start_thread (arg=0xee18a3e0) at pthread_create.c:335
#16 0xf646b0a0 in ?? () at ../sysdeps/unix/sysv/linux/arm/clone.S:89
from /localdata/perforce/ankgoyal/oneos/branches/saos-sds/dev/main/build/saos-sds/fs/eredan_tarfs/debug/eredan/armv7a/lib/libc.so.6
Backtrace stopped: previous frame identical to this frame (corrupt stack?)
(gdb) ore was generated by `/mnt/apps/bin/leos -s'.
(gdb) Program terminated with signal SIGBUS, Bus error.

1 ответ

Решение

SIGBUS - это программный сигнал, генерируемый ядром Linux, поэтому вам необходимо понять, почему ядро ​​генерирует сигнал SIGBUS. Это может или не может быть из-за аппаратного исключения.

Убедитесь, что данные правильно выровнены по их типу и тому, что вы делаете с ним. Одной из причин SIGBUS является неправильное выравнивание. Попробуйте воспроизвести ошибку с помощью неоптимизированного кода (например, для GCC или Clang, не передавая -O опция).

Если вы убедились, что выравнивание не является проблемой, проверьте диапазон доступа. Если вы получаете SIGBUS из-за доступа к шине устройства, вам необходимо выяснить, как эта память отображается в вашем процессе и что устройство показывает по этому адресу.

Проверьте логи ядра. Они могут содержать отладочную информацию из поколения SIGBUS.

Если сигнал происходит из-за аппаратного сбоя, причина исключения действительно передается в регистр, но только ядро ​​может прочитать значение этого регистра. Соответствующими регистрами являются DFSR и DFAR для неудачной выборки или сохранения данных, а также IFSR и IFAR для ошибки инструкции. Однако вы можете использовать эту информацию только в том случае, если вам удастся выяснить, что происходит внутри ядра.

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