Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

8179
1390
307630


[Arm프로세서] Armv8: 리눅스 커널에서 익셉션 레벨을 읽어서 제어하는 루틴 Armv8: 익셉션 레벨(EL)

먼저 리눅스 커널이 부팅하는 과정에서 익셉션 레벨을 읽어서 제어하는 루틴을 소개합니다. Armv8 기반 리눅스 커널이 부팅을 할 때 el2_setup 레이블이 호출되는데, 이 레이블에서는 현재 익셉션 레벨을 읽어서 관련된 처리를 수행합니다. 

다음은 el2_setup 레이블의 구현부입니다.

https://elixir.bootlin.com/linux/v5.10.60/source/arch/arm64/kernel/head.S
01 SYM_FUNC_START(el2_setup)
02 msr SPsel, #1 // We want to use SP_EL{1,2}
03 mrs x0, CurrentEL
04 cmp x0, #CurrentEL_EL2
05 b.eq 1f
06 mov_q x0, (SCTLR_EL1_RES1 | ENDIAN_SET_EL1)
07 msr sctlr_el1, x0
08 mov w0, #BOOT_CPU_MODE_EL1 // This cpu booted in EL1
09 isb
10 ret

먼저 02번째 줄을 보겠습니다.

02 msr SPsel, #1 // We want to use SP_EL{1,2}

'msr SPsel' 명령어는 익셉션 레벨 별로 스택을 설정할 때 사용되는데, 명령어에 전달되는 아규먼트에 따라 다린 방식으로 설정됩니다.

   * 'msr SPsel, #1': 익셉션 레벨 별로 스택(SP_EL0, SP_EL1)을 설정
   * 'msr SPsel, #0': 익셉션 레벨에 상관없이 하나의 스택을 설정 

이어서 03번째 줄을 보겠습니다.

03 mrs x0, CurrentEL

CurrentEL 시스템 레지스터에 접근해 현재 익셉션 레벨을 x0 레지스터에 로딩하는 동작입니다.

마지막으로 04번째 줄을 보겠습니다.

04 cmp x0, #CurrentEL_EL2
05 b.eq 1f

x0 레지스터의 값과 CurrentEL_EL2를 비교해 같으면 ‘1f’ 구문으로 브랜치하는 명령어입니다.
보통 리눅스 커널은 EL1으로 실행되므로 06~10번째 줄이 실행됩니다.

이어지는 포스트에서는 EL2에서 실행되는 XEN 하이퍼바이저에서 익셉션 레벨을 읽어 제어하는 코드를 살펴보겠습니다.

#Reference Armv8: 익셉션 레벨(ELx)


Written by <디버깅을 통해 배우는 리눅스 커널의 구조와 원리> 저자
* 2021년 대한민국 학술원 선정 우수도서



---




핑백

덧글

댓글 입력 영역