[커널 20차] 17주차
2023.08.27 23:32
2023.08.26 (17주차) - 약 10명 참여
1. Linux Kernel 6.4.2 코드 분석
head.S : create_idmap의 /* Remap the FDT after the kernel image */ 전까지 진행
주소 값은 문C 블로그에 정리된 이미지를 참고해 진행하였다. 값이 어떻게 변하는지 계산하면서 진행하였다.
< 결과 >
1. remap_region - 1st for init_pg_dir 이 완료된 모습
2. init_pg_dir 영역을 R/W로 리매핑한 page table의 모습
: pmd[22] 의 값이 0x42c0_0781에서 0x42c0_0701로 바뀌었다. (RX 플래그 -> RW 플래그)
< 과정 >
1. remap_region에 들어가기 전 레지스터 값 정리
/* Remap the kernel page tables r/w in the ID map */
x0 = 0x41e4_2000 (pmd[0])
x1 = 0x4020_0000 (_text)
x2 = 0x42c7_9000 (init_pg_dir)
x3 = 0x42c7_9000 (init_pg_end)
x4 = 0x42c0_0000
x5 = 0x701 (SWAPPER_RW_MMUFLAGS)
x6 = 21 (SWAPPER_BLOCK_SHIFT)
bl remap_region
2. remap_region의 populate_entries 들어가기 전 레지스터 값 정리
x0 = 0x41e4_2000 (tbl)
x4 = 0x42c0_0000 (rtbl)
x2 = 0x16 (index)
x3 = 0x16 (eindex)
x5 = 0x701 (flag)
x6 = 2M (inc)
x7 = 0x781 (tmp1)
Q: bfi 명령어
A:
3. populate_entries
Q: str \tmp1, [\tbl, \index, lsl #3] 의 이해
A: c언어로 바꿔봤을 때 배열의 주소 값 이해
#include <stdio.h> #include <stdlib.h> typedef unsigned long long u64; typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; int main() { u8 * p8 = (u8*) 1000; u16 * p16 = (u16*) 2000; u32 * p32 = (u32*) 3000; u64 * p64 = (u64*) 4000; for(int i = 0; i < 4; ++i) { printf("p8 %llu\n", &p8[i]); printf("p16 %llu\n", &p16[i]); printf("p32 %llu\n", &p32[i]); printf("p64 %llu\n", &p64[i]); printf("============================\n"); } return 0; } |
실행 결과: p8 1000 p16 2000 p32 3000 p64 4000 ============================ p8 1001 p16 2002 p32 3004 p64 4008 ============================ p8 1002 p16 2004 p32 3008 p64 4016 ============================ p8 1003 p16 2006 p32 3012 p64 4024 ============================ |
결국 tbl은 pmd의 시작 주소를 가리키고, index는 22, tmp1은 0x42c0_0701이니까 tbl[22] = 0x42c0_0701과 같다.
Q: cmp와 b.ls
A:
cmp index(2), eindex(1) => C set, Z clear
b.ls .Lpe => C clear or Z set
2. Arm 아키텍처의 구조와 원리
3.3 레지스터
1. 내용 정리
(1) 범용 레지스터
- X0 ~ X30
- X30은 링크 레지스터로 사용
(2) 스페셜 레지스터
1) 제로 레지스터 (XZR / WZR)
- 0 값을 가지고, 읽기만 가능.
2) 프로그램 카운터 (PC)
- 다음에 수행될 명령어의 주소
3) 스택 포인터 (SP_ELx)
- 각 레벨마다 존재
4) 프로그램 상태 레지스터 (SPSR_ELx)
- 레벨 1부터 3까지 존재
- PSTATE 정보를 백업하는 용도로 사용
- PSTATE 비트 필드 소개
5) 익셉션 링크 레지스터(ELR_ELx)
- 레벨 1부터 3까지 존재
+) SPSR_EL1을 사용해 이전 익셉션 레벨로 복귀하는 방식
: PC, PSTATE, SPSR, X30 값이 변경되는 과정
4.4.1 플래그 설정 명령어
1. 내용 정리
플래그를 설정하는 명령어로 CMP, CMN, TST, TEQ가 존재한다. 이 명령어는 {N,Z,C,V} 플래그를 업데이트한다. TBNZ와 같이 특정 플래그만 변경하는 명령어도 있다.
4.4.2 조건부 코드
접미사(EQ, NE 등등) 별 동작 및 플래그 정리
이런 것이 있구나 정도로 마침.
17.1 메모리 모델 소개
Q: 머지 액세스의 의미는 "메모리 공간에 여러 번 접근"하거나 연속된 메모리 공간에 접근하는 2개 이상의 명령어를 한번에 처리하는 동작입니다. 이 때, "메모리 공간에 여러 번 접근" 에 해당하는 경우가 연속된 메모리 공간에 접근하는 경우도 포함될까요?
A: 그러할 것 같다는 의견이 나왔습니다.
Q: 노멀 메모리를 표현할 때 주소의 어떤 비트를 이용해 표현하는지(플래그와 같이), 혹은 노멀 메모리 타입에 해당하는 주소 공간이 정의가 되어있는것인지
A: PTE(page table entry)에 [2-4] 비트에 속성이 있으며 여기에 NORMAL 메모리 타입이 있음.
/* arch/arm64/include/asm/memory.h */ #define MT_NORMAL 0 #define MT_NORMAL_TAGGED 1 #define MT_NORMAL_NC 2 #define MT_DEVICE_nGnRnE 3 #define MT_DEVICE_nGnRE 4 |
head.S에서 map_memory 에서 SWAPPER_RX_MMUFLAGS에 MT_NORMAL 옵션이 있다.
17.2 메모리 리오더링과 Weakly Ordered 속성
Q: 책에서 “Kernel이 Code에 있는 데이터는 실행만 가능하며 읽고/쓰기는 불가능합니다. 운영체제 커널 코드가 로딩된 영역이므로 코드를 읽거나 쓰면 코드 내용이 바뀌 므로 읽고/쓰기는 불가능하도록 설정합니다.” 라고 나와있습니다. Kernel Code에서 실행은 가능하지만 읽기를 해도 내용이 바뀌는 이유는 무엇일까요?
A: 커널 코드를 읽기 했을 때 내용이 바뀌지 않는다. 그림 17.1 메모리 맵의 구조도를 보면 알 수 있다. 저자의 표현을 이해하는 데 오해가 생긴 것 같다.
Q: 아래 수식에서 * 의 의미는 무엇일까요?
X2 = *(0x20000 + 0x08);
A: C 언어에서의 포인터입니다.
Q: 책에서 “명령어가 순차적으로 실행해도 프로세서 내부에서 메모리에 접근하는 순서는 순차적이지 않을 수 있다.” 라고 합니다. 그리고 577pg 상단에 은행 창구에 온 손님들을 비유로 듭니다. 이 부분이 CPU 스케줄링이랑 겹쳐보여서 “메모리에 접근하는 순서는 순차적이지 않을 수 있다”는 것도 CPU 스케줄링의 범주로 볼 수 있을까요?
A1: CPU 스케줄링은 프로세스 간에 일어나는 것이고, 메모리 리오더링은 하나의 프로세스 내부에서 일어나는 것입니다.
A2: 내부에 이런 동작들이 진행되는 것 같습니다.
https://en.wikipedia.org/wiki/Instruction_scheduling
Q: 메모리 버스트 모드가 뭘까요?
A: DMA의 동작에서 버스트 모드를 의미하는 것 같습니다.
17.3 메모리 배리어
Q: DMB와 volatile 의 관계? volatile 명령어는 내부에서 dmb 같은 요소를 사용하는 것인가요?
A1: 디바이스 드라이버를 직접 코딩해보지 않아서 정확하게는 모르겠지만, volatile을 사용하면 while(true) 같이 컴파일러가 최적화 하는 것을 막아준다고 합니다.
https://ko.wikipedia.org/wiki/Volatile_%EB%B3%80%EC%88%98
A2: volatile 컴파일 결과
int main() { foo = 1; foo = 2; foo = 3; foo = 4; return 0; } |
디스어셈블리 결과
000000000000714 <main>: 714: 90000100 adrp x0, 20000 <__libc_start_main@GLIBC_2.34> 718: 9100d000 add x0, x0, #0x34 71c: 52800021 mov w1, #0x1 // #1 720: b9000001 str w1, [x0] 724: 90000100 adrp x0, 20000 <__libc_start_main@GLIBC_2.34> 728: 9100d000 add x0, x0, #0x34 72c: 52800041 mov w1, #0x2 // #2 730: b9000001 str w1, [x0] 734: 90000100 adrp x0, 20000 <__libc_start_main@GLIBC_2.34> 738: 9100d000 add x0, x0, #0x34 73c: 52800061 mov w1, #0x3 // #3 740: b9000001 str w1, [x0] 744: 90000100 adrp x0, 20000 <__libc_start_main@GLIBC_2.34> 748: 9100d000 add x0, x0, #0x34 74c: 52800081 mov w1, #0x4 // #4 750: b9000001 str w1, [x0] 754: 52800000 mov w0, #0x0 // #0 758: d65f03c0 ret |
dmb와는 무관한 듯 보이며 최적화를 못하게 막는 역할을 하는 것 같습니다.
Q: pg581에서 “현재 프로그램 카운터보다 앞서 있는 주소의 명령어를 미리 페치합니다.” 의 페치가 무슨 의미일까요?
A1: instruction cycle을 키워드로 검색을 해보면, 하나의 명령어는 fetch, decode, execution 단계로 나누어지는 것을 알 수 있다. 페치는 여기서의 fetch를 의미한다.
A2: pg212에 파이프라인 그림이 나와있다. 그림은 3단계 파이프라인을 보여주고 있다. 3번째, 클럭 사이클부터는 서로 다른 명령어의 실행 디코딩 페치가 동시에 이루어진다. 이런 것을 보고 파이프라인이라고 한다. 또 실행하기 전에 미리 페치하는 것을 볼 수 있다.
A3: 컴공 수준의 설명이 나와있다.
https://velog.io/@ckstn0777/%EC%BB%B4%ED%93%A8%ED%84%B0%EA%B5%AC%EC%A1%B0-9htxi9jo
댓글 0
번호 | 제목 | 글쓴이 | 날짜 | 조회 수 |
---|---|---|---|---|
공지 | [공지] 스터디 정리 노트 공간입니다. | woos | 2016.05.14 | 631 |
228 | [커널 20차] 20주차 [2] | 이민찬 | 2023.09.17 | 184 |
227 | [커널 20차] 19주차 | 이민찬 | 2023.09.10 | 103 |
226 | [커널 20차] 18주차 | 이민찬 | 2023.09.03 | 85 |
» | [커널 20차] 17주차 | 이민찬 | 2023.08.27 | 132 |
224 | [커널 20차] 16주차 | 이민찬 | 2023.08.20 | 133 |
223 | [커널 19차] 64 주차 | Min | 2023.08.19 | 91 |
222 | [커널 20차] 15주차 | 이민찬 | 2023.08.13 | 126 |
221 | [커널 19차] 63 주차 | Min | 2023.08.12 | 60 |
220 | [커널 19차] 62 주차 | Min | 2023.08.05 | 80 |
219 | [커널 20차] 13주차 | 이민찬 | 2023.07.30 | 108 |
218 | [커널 19차] 61 주차 | Min | 2023.07.30 | 45 |
217 | [커널 20차] 12주차 | 이민찬 | 2023.07.22 | 87 |
216 | [커널 19차] 59 ~ 60 주차 | Min | 2023.07.22 | 37 |
215 | [커널 18차] 113주차 | kkr | 2023.07.22 | 79 |
214 | [커널20차] 11주차 | 이경재 | 2023.07.15 | 86 |
213 | [커널20차] 10주차 | 이경재 | 2023.07.09 | 90 |
212 | [커널20차] 9주차 | 이경재 | 2023.07.02 | 85 |
211 | [커널 19차] 58 주차 | Min | 2023.07.01 | 41 |
210 | [커널 19차] 56 ~ 57 주차 | Min | 2023.06.25 | 40 |
209 | [커널 18차] 109주차 | kkr | 2023.06.24 | 33 |
.