Part 1
요약·해설
v2m_beetle build, single-thread configuration, ARMv7/8 MPU fault와 Cortex-M0+ lockup 확인 절차를 설명합니다.
BUS · MPU fault
Hard fault · Lockup
GDB · PC 0xfffffffe
Part 2
접을 수 있는 영어 원문 전체
영어 원문 전체 펼치기
5547DD974A631135C4EBB3A6A03D7238C9C6B1858D471701400936123CA340F5
.. _mpu_test:
Memory Protection Unit (MPU) Sample
###################################
Overview
********
This application provides a set options to check the correct MPU configuration
against the following security issues:
* Read at an address that is reserved in the memory map.
* Write into the boot Flash/ROM.
* Run code located in SRAM.
If the MPU configuration is correct each option selected ends up in an MPU
fault.
Building and Running
********************
This project can be built and executed as follows:
.. zephyr-app-commands::
:zephyr-app: samples/arch/mpu/mpu_test
:board: v2m_beetle
:goals: build flash
:compact:
To build the single thread version, use the supplied configuration file for
single thread: :file:`prj_single.conf`:
.. zephyr-app-commands::
:zephyr-app: samples/arch/mpu/mpu_test
:board: v2m_beetle
:conf: prj_single.conf
:goals: run
:compact:
To build a version that allows writes to the flash device, edit
``prj.conf``, and follow the directions in the comments to enable the
proper configs.
Sample Output
=============
When running the above on an ARMv7 or ARMv8 CPU, the output of each command may look
like the following.
.. code-block:: console
uart:~$ mpu read
<err> os: ***** BUS FAULT *****
<err> os: Precise data bus error
<err> os: BFAR Address: 0x24000000
<err> os: r0/a1: 0x00009a5c r1/a2: 0x00000008 r2/a3: 0x20001aa8
<err> os: r3/a4: 0x24000000 r12/ip: 0x00000000 r14/lr: 0x000029b7
<err> os: xpsr: 0x21000000
<err> os: Faulting instruction address (r15/pc): 0x000003c8
<err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
<err> os: Current thread: 0x20000708 (shell_uart)
<err> os: Halting system
.. code-block:: console
uart:~$ mpu write
write address: 0x4000
<err> os: ***** MPU FAULT *****
<err> os: Data Access Violation
<err> os: MMFAR Address: 0x4000
<err> os: r0/a1: 0x00000000 r1/a2: 0x0000000e r2/a3: 0x0badc0de
<err> os: r3/a4: 0x00004000 r12/ip: 0x00000004 r14/lr: 0x000003ab
<err> os: xpsr: 0x61000000
<err> os: Faulting instruction address (r15/pc): 0x000003b2
<err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
<err> os: Current thread: 0x20000708 (shell_uart)
<err> os: Halting system
.. code-block:: console
uart:~$ mpu run
<err> os: ***** MPU FAULT *****
<err> os: Instruction Access Violation
<err> os: r0/a1: 0x00009a5c r1/a2: 0x00000001 r2/a3: 0x20001aa8
<err> os: r3/a4: 0x20000000 r12/ip: 0x00000000 r14/lr: 0x00006673
<err> os: xpsr: 0x60000000
<err> os: Faulting instruction address (r15/pc): 0x20000000
<err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
<err> os: Current thread: 0x20000708 (shell_uart)
<err> os: Halting system
When running this test on an ARMv6 CPU (specifically on a Cortex-M0+), the output will
look different, as ARMv6 handles MPU faults as generic hard faults. Moreover, when
running the ``mpu run`` command, Zephyr's hard fault handler for AArch32 tries to
dereference the program counter from the exception stack frame, causing a second fault
and silently placing the processor into a lockup state.
To verify that the ``mpu run`` test in particular is running correctly, one can
* start the MPU test under gdb with ``west debug``
* execute ``mpu run`` over UART
* then interrupt gdb with Ctrl-C and show the program counter by running ``l`` in gdb.
The program counter should display as ``0xfffffffe``, indicating a lockup state.
.. code-block:: console
uart:~$ mpu read
<err> os: ***** HARD FAULT *****
<err> os: r0/a1: 0x0800a54c r1/a2: 0x00000008 r2/a3: 0x08003
<err> os: r3/a4: 0x24000000 r12/ip: 0x00000040 r14/lr: 0x0800d
<err> os: xpsr: 0x01000000
<err> os: Faulting instruction address (r15/pc): 0x08000486
<err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
<err> os: Current thread: 0x200006a8 (shell_uart)
<err> os: Halting system
.. code-block:: console
uart:~$ mpu write
<err> os: ***** HARD FAULT *****
<err> os: r0/a1: 0x00000000 r1/a2: 0x0000000e r2/a3: 0x0000e
<err> os: r3/a4: 0x0badc0de r12/ip: 0x00000000 r14/lr: 0x08009
<err> os: xpsr: 0x61000000
<err> os: Faulting instruction address (r15/pc): 0x0800046a
<err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
<err> os: Current thread: 0x200006a8 (shell_uart)
<err> os: Halting system
.. code-block:: console
uart~$ mpu run
<no output>
Part 3
한국어 전문 번역
개요
이 application은 다음 보안 문제에 대해 MPU configuration이 올바른지 확인하는 option 집합을 제공합니다.
- Memory map에서 reserved로 지정된 주소 읽기
- Boot Flash/ROM에 쓰기
- SRAM에 위치한 code 실행
MPU configuration이 올바르면 선택한 각 option은 MPU fault로 끝납니다.
Build와 실행
다음 명령으로 project를 build하고 실행할 수 있습니다.
west build -b v2m_beetle samples/arch/mpu/mpu_test
west flash
Single-thread version을 build하려면 제공된 prj_single.conf configuration file을 사용합니다.
west build -b v2m_beetle samples/arch/mpu/mpu_test -- -DCONF_FILE=prj_single.conf
west build -t run
Flash device 쓰기를 허용하는 version을 build하려면 prj.conf를 편집하고 comment의 안내에 따라 필요한 configuration을 활성화합니다.
Sample 출력
ARMv7 또는 ARMv8 CPU에서 위 sample을 실행하면 각 명령의 출력은 다음과 비슷합니다.
uart:~$ mpu read
<err> os: ***** BUS FAULT *****
<err> os: Precise data bus error
<err> os: BFAR Address: 0x24000000
<err> os: r0/a1: 0x00009a5c r1/a2: 0x00000008 r2/a3: 0x20001aa8
<err> os: r3/a4: 0x24000000 r12/ip: 0x00000000 r14/lr: 0x000029b7
<err> os: xpsr: 0x21000000
<err> os: Faulting instruction address (r15/pc): 0x000003c8
<err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
<err> os: Current thread: 0x20000708 (shell_uart)
<err> os: Halting system
uart:~$ mpu write
write address: 0x4000
<err> os: ***** MPU FAULT *****
<err> os: Data Access Violation
<err> os: MMFAR Address: 0x4000
<err> os: r0/a1: 0x00000000 r1/a2: 0x0000000e r2/a3: 0x0badc0de
<err> os: r3/a4: 0x00004000 r12/ip: 0x00000004 r14/lr: 0x000003ab
<err> os: xpsr: 0x61000000
<err> os: Faulting instruction address (r15/pc): 0x000003b2
<err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
<err> os: Current thread: 0x20000708 (shell_uart)
<err> os: Halting system
uart:~$ mpu run
<err> os: ***** MPU FAULT *****
<err> os: Instruction Access Violation
<err> os: r0/a1: 0x00009a5c r1/a2: 0x00000001 r2/a3: 0x20001aa8
<err> os: r3/a4: 0x20000000 r12/ip: 0x00000000 r14/lr: 0x00006673
<err> os: xpsr: 0x60000000
<err> os: Faulting instruction address (r15/pc): 0x20000000
<err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
<err> os: Current thread: 0x20000708 (shell_uart)
<err> os: Halting system
ARMv6 CPU, 특히 Cortex-M0+에서 이 test를 실행하면 ARMv6가 MPU fault를 일반 hard fault로 처리하므로 출력이 다릅니다. 또한 mpu run 명령을 실행하면 AArch32용 Zephyr hard fault handler가 exception stack frame에서 program counter를 dereference하려고 시도합니다. 이때 두 번째 fault가 발생해 processor가 아무 출력 없이 lockup 상태가 됩니다.
특히 mpu run test가 올바르게 실행되는지 확인하려면 다음 절차를 따릅니다.
west debug로 gdb에서 MPU test를 시작합니다.- UART에서
mpu run을 실행합니다. - Ctrl+C로 gdb를 중단한 뒤 gdb에서
l을 실행해 program counter를 표시합니다.
Program counter가 0xfffffffe로 표시되면 lockup 상태임을 뜻합니다.
uart:~$ mpu read
<err> os: ***** HARD FAULT *****
<err> os: r0/a1: 0x0800a54c r1/a2: 0x00000008 r2/a3: 0x08003
<err> os: r3/a4: 0x24000000 r12/ip: 0x00000040 r14/lr: 0x0800d
<err> os: xpsr: 0x01000000
<err> os: Faulting instruction address (r15/pc): 0x08000486
<err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
<err> os: Current thread: 0x200006a8 (shell_uart)
<err> os: Halting system
uart:~$ mpu write
<err> os: ***** HARD FAULT *****
<err> os: r0/a1: 0x00000000 r1/a2: 0x0000000e r2/a3: 0x0000e
<err> os: r3/a4: 0x0badc0de r12/ip: 0x00000000 r14/lr: 0x08009
<err> os: xpsr: 0x61000000
<err> os: Faulting instruction address (r15/pc): 0x0800046a
<err> os: >>> ZEPHYR FATAL ERROR 0: CPU exception on CPU 0
<err> os: Current thread: 0x200006a8 (shell_uart)
<err> os: Halting system
uart~$ mpu run
<no output>
Source
출처
영어 원문에는 문단, 문서 지시문, 표, 코드, 코드 심벌, 경로를 그대로 보존했습니다.