[커널 20차] 13주차

2023.07.30 22:36

이민찬 조회 수:107

2023.07.29 (13주차) - 약 18명 참여

1. 커널 코드 분석 

진행 상황: head.S의 preserve_boot_args 마무리 

1) arch/arm64/mm/cache.S 의 dcache_inval_poc

SYM_FUNC_START(__pi_dcache_inval_poc)
146         /* IAMROOT20 20230722
147          * x2에 cache line-size를 저장하고(64byte), x3에는 ctr_el0[19:16]의 값이 저장되어있다. 
148          * 매크로 위치 : /arch/arm64/include/asm/assembler.h
149          */
150         dcache_line_size x2, x3
151         /* 
152          * IAMROOT20 20230729
153          * 하위 비트를 mask off 하기 위한 준비.
154         */
155         sub     x3, x2, #1
156         tst     x1, x3                          // end cache line aligned?
157         bic     x1, x1, x3
158         /*
159          * IAMROOT20 20230729
160          * bic 다음에 b.eq 가 나오는 이유 : 파이프라인 flush로 인한 reload 방지
161          * - https://developer.arm.com/documentation/ddi0337/e/BABBCJII
162         */
163         b.eq    1f
164         /*
165          * IAMROOT20 20230729
166          * DC CIVAC : 지정한 주소의 데이터 캐시를 PoC까지 Clean & Invalidate를 수행.
167         */
168         dc      civac, x1                       // clean & invalidate D / U line
169 1:      tst     x0, x3                          // start cache line aligned?
170         bic     x0, x0, x3
171         b.eq    2f
172         dc      civac, x0                       // clean & invalidate D / U line
173         b       3f
174 2:      dc      ivac, x0                        // invalidate D / U line
175 3:      add     x0, x0, x2
176         cmp     x0, x1
177         b.lo    2b
178         /*
179          * IAMROOT20 20230729
180          * dsb : https://developer.arm.com/documentation/dui0473/m/arm-and-thumb-instructions/dsb
181         */
182         dsb     sy
183         ret
184 SYM_FUNC_END(__pi_dcache_inval_poc)

 

2) 논의 내용 

 

 

Q: bytes per word 사이즈가 왜 8이 아니고, 4인가?

A: arm64에서도 cache size는 4라고 한다. arm64에서는 arm32도 돌려야 하니 4로 둔 것으로 추측된다. 그러나 이후 코드에서 8로 바꾸는 코드가 있지 않을까?라고 추측도 해본다.

 

Q: dc ivac은 가상 주소를 사용하는 명령어인데, MMU가 꺼져있는 상태에서는 VA -> PA 변환이 안될텐데, 어떻게 이런 명령어 사용이 가능할까?

A: 매뉴얼에서는 Address translation을 좀 더 큰 개념으로 보고있다. MMU가 꺼져있는 상황에서도 address translation은 일어난다고 보고 있고 그 결과의 PA는 VA와 같다고 보고있다. 

 

Q: dc civac 명령어를 사용하는 이유

A: dc  civac은 지정한 주소의 데이터 캐시를 POC까지 Clean & Invalidate 하는 명령어이다.

Clean은 flush 시에 메모리에 write 까지 수행하는 것을 의미한다. Clean까지 하는 이유는 Invalidate 하려는 cache line에 다른 사용 중인 데이터가 씌어져있을 수 있기 때문이다. 즉, 지정한 주소의 시작과 끝이 캐시 라인 사이즈로 정렬되어있지 않은 경우에는 캐시 라인 전체를 invalidate 할 때, 다른 사용 중인 데이터를 clean 해줘야할 필요가 있다. 

 

Q: bic 명령어와 b.eq 명령어의 순서를 바꿔도 실행하는데 문제가 없지 않을까?

A: 실행하는 데 문제가 없을 것 같다. 하지만 bic를 먼저 수행하는 이유는 최적화 문제일 것 같다. Branch 명령어를 수행하면 파이프라인이 reload가 될테니까 branch 하기 전에 bic 명령어를 수행하는 것 같다. 

https://developer.arm.com/documentation/ddi0337/e/BABBCJII

 

Q: 반복문을 돌며 invalidate 하는 이유 

A: dcache_inval_poc는 범용적으로 사용하는 함수이다. 시작 주소와 끝 주소를 인자로 받아서 그 주소가 포함된 cache line을 invalidate 하는 목적이다. 분석을 하고 있는 지금은 32byte 크기인 boot_args를 invalidate 하고 있지만, 이 함수는 범용적으로 사용되므로 invalidate 할 주소 범위의 크기는 고정적이지 않다. 

 

Q: create_idmap에서 id map이란?

A: 가상 주소와 물리 주소를 1:1로 정확히 같게 매핑시키는 것. 이 방식은 가상 주소를 물리 주소처럼 사용할 수 있다는 장점이 있다. MMU를 켜서 translation을 해도 물리 주소에 접근하는 것과 같은 효과를 가지고, 전체 주소 범위에 대해서 ID mapping을 하는 것이 아니라, 부팅에 필요한 일부 영역에 대해서만 ID mapping을 할 것이다.

 

2. 디버깅을 통해 배우는 리눅스 커널의 구조와 원리

 

 

4.2 프로세스 확인하기

Q. PID를 얻는 함수로 getpid()

A.  task_struct의 pid 필드는 우리가 알고 있는 PID와 다르며, tgid 필드가 PID 개념이다.

PID를 얻기 위해 사용하는 getpid()는 tgid를 가져오는 함수

  1. getpid() 는 sys_getpid() -> task_tgid_vnr() 를 호출하여 결국 tgid 필드 값을 가져온다.

 

Q. init, systemD의 차이점

A. https://mamu2830.blogspot.com/2021/07/init-systemd-difference.html

A.https://rudalson.tistory.com/entry/Linux%EC%9D%98-init-process-%EA%B7%B8%EB%A6%AC%EA%B3%A0-systemd

A.  init에서 systemd로 개선되어 변경, 무엇이 개선되었는지는 위 링크들을 통해 확인할 수 있다.



 

4.3 프로세스는 어떻게 생성할까

Q. 이미 생성된 프로세스에게 리소스를 물려받는다는 것은 어떻게 받는 것인지?, 할당과의      차이점은 무엇인지 궁금합니다
  - 질문배경
    프로세스 생성할때 복제하는 이유로
    프로세스 생성에 필요한 리소스를 각가 할당받으면 시간이 오래 걸리기 때문에
    이미 생성된 프로세스에게서 리소스를 물려 받는다고 합니다

A. 새로운 프로세스의 자료구조를 초기화 하는 것보다 이미 생성된 프로세스의 데이터를     복제하는 것이 더 효율적이라서 그러합니다



 

Q. 커널의 입장에서는 유저 프로세스와 커널 프로세스가 동일하게 보지만, 스레드의 경우 커널 스레드는 kthread_create로 생성되고, 유저 스레드는 ptrhead_create 함수로 실행이 됩니다. 그렇다면 커널 입장에서 유저 스레드와 커널 스레드도 동일하게 볼까요?

 

A. 동일하게 동작하며 유저프로세서는 syscall로 커널 리소스를 요청하고

 

커널프로세서는 커널 함수를 직접 호출하면 됩니다.

커널 쓰레드의 부모는 kthreadd 가 부모가 됩니다.

사용자 프로세스는의 최종 부모는 init, systemd 가 됩니다.

 

Q. 커널 스레드는 어떻게 시스템콜 없이 시스템 리소스 관리를 수행할 수 어떻게 할 수 있는 것일까요?

  1. 시스템 콜은 유저 공간에서 커널 공간으로 넘어가는 것이다

그러므로 커널 스레드는 애초에 커널 공간에 있으니까 시스템 콜이 필요가 없다

Q. 커널 공간에만 있으면 하드웨어 조작을 할수 있을까요?

  1. 커널공간 && 하드웨어 조작할 수 있는 권한이 있어야 가능하다

 

Q. init 프로세스는 프로세스 생성 외에 또 하는 역할이 있는가요?

  1. 고아(진짜 부모 프로세서가 이미 종료된)  프로세스의 종료 처리를 하는것도 있습니다.

 

Q. init 0, 6로 프로그램 종료되는 이유가init이 항상 떠 있어야해서 인가요?

  1. Init 0~6는run level이라서 관련되지 않는다 생각합니다

 

공유: fork.c의 __do_fork 함수의 이름 변경 -> kernel_clone() 으로 변경되었다.

번호 제목 글쓴이 날짜 조회 수
공지 [공지] 스터디 정리 노트 공간입니다. woos 2016.05.14 627
228 [커널 20차] 20주차 [2] 이민찬 2023.09.17 182
227 [커널 20차] 19주차 이민찬 2023.09.10 103
226 [커널 20차] 18주차 이민찬 2023.09.03 85
225 [커널 20차] 17주차 이민찬 2023.08.27 129
224 [커널 20차] 16주차 이민찬 2023.08.20 132
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 79
» [커널 20차] 13주차 이민찬 2023.07.30 107
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 78
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
XE Login