[커널 20차] 17주차

2023.08.27 23:32

이민찬 조회 수:128

 

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 이 완료된 모습

6MT4af2ncLrIi5m5kJIoqhMGHAvSiRkI0k8gZvzd

 

2. init_pg_dir 영역을 R/W로 리매핑한 page table의 모습

: pmd[22] 의 값이 0x42c0_0781에서 0x42c0_0701로 바뀌었다. (RX 플래그 -> RW 플래그)

W1dz1VSulXPmN6kHd5CiBGkldaVCw-dPqtYT7_rb

< 과정 >

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:

q9OlAmPK05DU3M_ldar9f3-cUrStoZ2Um0Wyvpfr

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 메모리 맵의 구조도를 보면 알 수 있다. 저자의 표현을 이해하는 데 오해가 생긴 것 같다.6NclXba2fhLDYQHpLlIgfjOIUtMk6tnu7SP6nv27

 

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

 

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 626
248 [커널 19차] 103 주차 Min 2024.04.28 4
247 [커널 20차] 48주차 무한질주 2024.04.25 22
246 [커널 19차] 102 주차 Min 2024.04.20 37
245 [커널 19차] 101 주차 Min 2024.04.13 63
244 [커널 19차] 100 주차 Min 2024.04.13 16
243 [커널 19차] 99 주차 Min 2024.03.30 82
242 [커널 19차] 98 주차 Min 2024.03.23 55
241 [커널 19차] 97 주차 Min 2024.03.16 50
240 [커널 19차] 96 주차 Min 2024.03.14 32
239 [커널 19차] 95 주차 [2] Min 2024.03.03 111
238 [커널 20차] 32주차 brw 2023.12.16 386
237 [커널 20차] 29주차 brw 2023.11.27 161
236 [커널 20차] 27주차 brw 2023.11.21 86
235 [커널 20차] 26주차 brw 2023.11.21 48
234 [커널 20차] 28주차 이민찬 2023.11.19 64
233 [커널 20차] 25주차 이민찬 2023.10.30 120
232 [커널 20차] 24주차 이민찬 2023.10.22 744
231 [커널 20차] 23주차 이민찬 2023.10.14 81
230 [커널 20차] 22주차 이민찬 2023.10.08 76
229 [커널 20차] 21주차 이민찬 2023.09.23 116
XE Login