Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

11105
637
415734


[ARM프로세서] 익셉션(Exception)의 동작 원리를 잘 알아야 하는 이유 Arm: Exception Overview

실전 시스템 개발자 중에 "ARM 프로세서는 최소한의 지식만 배우고 실전 프로젝트에서 ARM 프로세서를 알아야 할 시점에 배우면 된다"라고 생각하는 분이 있습니다. 그래서 "ARM 프로세서의 익셉션의 원리를 나중에 배우자"라고 말하거나 아예 "ARM 익셉션의 동작 원리는 몰라도 된다"라고 놀라운 의견을 제시하기도 합니다.
 
임베디드 BSP 개발자는 ARM 프로세서 누구나 자신만의 학습 방향에 대한 견해가 다르기 마련이지만 이런 생각은 그리 바람직하지 않은 것 같습니다. ARM 아키텍처의 익셉션 동작 원리는 시스템 시스템(임베디드/BSP) 개발자가 배워야 하는 핵심 기법이기 때문입니다. 이번 절에서는 시스템 소프트웨어 개발자가 익셉션을 잘 알아야 하는 이유에 대해 알아봅시다.

실전 프로젝트에서 문제해결 능력을 키울 수 있다

이 책에서 설명하는 ARM 프로세서의 내용들 중에 SW 개발자에게 익셉션은 무엇보다 중요합니다. 특히 임베디드 BSP 개발자들은 익셉션의 동작 원리를 반드시 배워야 한다고 봅니다. 이제부터 그 이유에 대해 살펴보겠습니다.

SW 개발자가 작성한 코드에는 치명적인 논리적 오류가 있을 수 있습니다. 여기서 말하는 치명적인 논리적인 오류가 있는 코드란 무엇일까요? NULL 포인터에 접근하거나 프로세스의 스택을 오염시키는 코드를 예로 들 수 있습니다. 이런 코드는 다른 코드와 마찬가지로 컴파일이 돼 어셈블리 명령어로 변환되며, 이 명령어를 ARM 프로세서가 실행합니다. 

ARM 프로세서는 치명적인 오류가 잠재된 명령어를 실행하지 않고, 아예 ARM 프로세서만이 알고 있는 주소로 점프를 합니다. 다른 관점으로 설명하면, ARM 프로세서는 명령어를 실행하다가 치명적인 오류를 감지하면, 명령어의 실행을 아예 중단시키는 것입니다. 그리고 치명적인 오류를 처리하는 주소인 익셉션 벡터 주소로 이동합니다. 


정확히 말하면 ARM 프로세서는 기계어를 실행하나, SW 관점에서 기계어와 가장 가까운 언어가 어셈블리이므로 이렇게 표기합니다. 


그런데 ARM 프로세서의 익셉션의 원리를 잘 알아둬야 하는 이유는 다음과 같은 사실입니다.

   ❑ 익셉션이 발생하면 치명적인 오류를 유발하는 코드"가 실행되는 정보를 
       ARM 코어 내부의 다양한 레지스터가 알려준다.

이를 통해 다음와 같이 치명적인 오류를 유발하는 코드의 정보를 바로 확인할 수 있습니다.

   ❑ 익셉션을 유발하는 코드의 주소
   ❑ 함수의 호출 흐름
   ❑ 익셉션이 발생한 세부 원인

한 가지 예를 들어볼까요? 가끔 여러분이 어떤 프로그램을 사용하다가 갑자기 프로그램이 멈추고 파란 화면이 모니터에 출력되는 것을 본 적이 있나요? 이를 흔히 "블루 스크린이 떴다"라고 말하기도 합니다. 그렇다면 블루 스크린이 출력되는 원인은 무엇일까요? 프로그램의 명령어를 실행하다가 치명적인 오류를 감지하면, 명령어의 실행을 멈추고 특정 주소로 점프를 합니다. 특정 주소에는 바로 "블루 스크린을 출력하는 코드"가 있는데, 이 코드를 실행하는 겁니다.

그런데 "블루 스크린"을 유심히 보면 영어로 된 주소나 로그"가 보일 것입니다. 이런 로그는 어디서 출력이 되는 것일까요? 익셉션이 발생하면 CPU 코어에서 레지스터를 통해 익셉션이 발생한 원인을 알려주는 것입니다. 운영체제에서는 이 레지스터 정보를 읽어 익셉션이 발생한 세부 원인을 체크합니다.

이와 유사하게 ARM 코어가 익셉션을 감지해 유발하면 익셉션의 종류와 익셉션이 발생한 원인을 레지스터를 통해 알려줍니다. 이 정보를 활용하면 '익셉션을 유발하는 코드의 주소', '함수의 호출 흐름' 그리고 '익셉션이 발생한 세부 원인'을 알 수 있습니다.

다음은 ARM 코어에서 알려주는 레지스터 정보를 활용해 복원한 데이터 어보트 익셉션이 발생했을 때의 콜 스택입니다.

-000|do_DataAbort()
-001|__dabt_svc(asm)
 -->|exception
-002|test_and_set_bit() 
-003|bit_spin_lock(inline)
-003|hlist_bl_lock(inline)
-003|mb_cache_shrink_scan()
-004|shrink_slab_node()
-005|shrink_slab()
-006|kswapd_shrink_zone(inline)
-006|balance_pgdat(inline)
-006|kswapd()
-007|kthread()
-008|ret_from_fork(asm)
-009|ret_fast_syscall(asm)

002 줄에서 test_and_set_bit() 함수가 실행됐을 때 데이터 어보트가 발생했음을 알 수 있습니다. 함수의 호출 흐름을 정확히 파악하니 어느 함수에서 어떤 로직으로 문제가 생겼는지 쉽게 디버깅할 수 있습니다.

여러분이 실전 프로젝트에 투입되면 다양한 문제를 만나는데 이를 효율적으로 해결하기 위한 기반 지식이 익셉션입니다. 따라서 임베디드 BSP 개발자는 ARM 프로세서의 익셉션의 원리를 잘 알아둬야 합니다. 


임베디드 BSP 개발자인 저도 운영체제의 커널이나 RTOS 그리고 하이퍼바이저 코드를 처음 분석할 때 가장 먼저 익셉션과 관련된 익셉션 핸들러 코드를 분석합니다.


운영체제에 대한 깊이 있는 이해

ARM의 익셉션의 동작 원리를 배워야 하는 또 다른 이유는, 리눅스 커널과 같은 운영체제의 핵심 기능이 ARM의 익셉션을 활용해 구현됐기 때문입니다. 선점(Preemptive) 스케줄링, 시스템 콜, 시그널, IRQ(인터럽트 서브 시스템)과 같은 주요 기능은 익셉션 중 인터럽트 익셉션을 활용해 동작하며, 핵심 코드는 ARM 어셈블리 코드로 구현돼 있습니다. 여러분이 ARM의 익셉션을 잘 알고 싶지 않아도 운영체제의 핵심 원리를 배우려면 만나게 되는 관문이 익셉션입니다.

하이퍼바이저, 트러스트 존의 기반 지식은 익셉션입니다

트러스트존이나 하이퍼바이저를 이해하려면 익셉션의 동작 원리를 알아야 합니다.

ARM은 원래 RISC 기반으로 설계된 프로세서로 소형 임베디드 기기에 주로 탑재됐습니다. 하지만 현재 ARM 프로세서는 컴퓨터에 사용되며 클라우드 서버와 같은 고성능 컴퓨터에도 그 영역을 확장하고 있습니다. 고성능 사양의 컴퓨터에 ARM 프로세서가 사용되려면 컴퓨터를 사용하는 유저의 요구사항을 지원하는 기능을 지원해야 합니다. 이를 위해 ARM 프로세서는 다양한 기능을 제공하는데, 그 중 가장 대표적인 기법이 트러스트존과 하이퍼바이저입니다. 

트러스트 존은 시스템의 보완을 위해 ARM 프로세서에서 지원하는 기능인데, 트러스트 존의 세부 구현 방식을 배우려면 익셉션의 동작 원리를 알아야 합니다. 마찬가지로 하이파이저는 ARMv8 아키텍처의 EL2(익셉션 레벨)에서 실행되는데 익셉션을 통해 EL1에서 구동되는 가상머신과 인터페이싱을 하므로 익셉션을 배워야 합니다.

ARM의 트러스트 존을 이용한 보안 기능이나 하이퍼바이저 기능은 모두 ARMv8 에서 지원하는 익셉션 위에 쌓아 올린 기법들입니다. 가끔 트러스트 존을 이용한 보안 애플리케이션이나 하이퍼바이저 관련 업체가 배포한 문서를 보면 이게 ARM 프로세서의 스팩 문서인지 분간하기 어려울 경우도 많습니다.

---
"이 포스팅이 유익하다고 생각되시면 공감 혹은 댓글로 응원해주시면 감사하겠습니다. 
"혹시 궁금한 점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답변 올려드리겠습니다!"

​Thanks,
Guillermo Austin Kim(austindh.kim@gmail.com)
---



Reference: ARM 프로세서 익셉션 소개

익셉션이란? 
익셉션의 주요 개념  
    ❑ 익셉션의 타입 소개
익셉션과 같이 배워야 하는 운영체제 지식

Written by <디버깅을 통해 배우는 리눅스 커널의 구조와 원리> 저자






핑백

덧글

댓글 입력 영역