본문 바로가기

개발 이야기/리눅스 개발

리눅스 커널의 구조와 원리

728x90

 

리눅스 커널 구조와 원리에 대해 라즈베리파이3B 보드로

실습하면 배울 수 있는 유용한 영상이 있어 공유합니다.

https://www.youtube.com/watch?v=ScxepaOGTTU&list=PLRrUisvYoUw9-cTYgkbTbr9f9CpbGdq4F&index=5 

 

위 영상과 함께 참고하면 좋을 블로그를 공유합니다.

http://rousalome.egloos.com/9993264 

 

 

 

 

(추가1)

리눅스 커널 디버깅 방법은 아래와 같습니다.

printk()

dump_stack()

ftrace

 

(추가2)

ftrace 의 사용 방법은 아래와 같습니다.
=> https://www.youtube.com/watch?v=VZSQY1NzwX8&list=PLRrUisvYoUw9-cTYgkbTbr9f9CpbGdq4F&index=8 

*  ftrace는 리눅스 커널에서 제공하는 가장 강력한 트레이서
- Debugging the kernel using Ftrace - part 1/2
- https://lwn.net/Articles/365835/
- https://lwn.net/Articles/366796/

* ftrace의 특징

- 인터럽트, 스케줄링, 커널 타이머 등의 커널 동작을 상세히 추적 
- 함수 필터를 지정하면 지정한 함수를 호출한 함수와 전체 콜 스택까지 출력(물론 코드를 수정할 필요가 없음) 
- 함수를 어느 프로세스가 실행하는지 확인
- 함수가 실행된 시각 정보 확인
- ftrace 로그를 활성화해도 시스템 동작에 부하를 거의 주지 않음
- 컨텍스트 정보와 CPU 번호 확인

* ftrace를 사용하기 위한 커널 컨피그

CONFIG_FTRACE=y
CONFIG_DYNAMIC_FTRACE=y
CONFIG_FUNCTION_TRACER=y
CONFIG_FUNCTION_GRAPH_TRACER=y
CONFIG_IRQSOFF_TRACER=y
CONFIG_SCHED_TRACER=y
CONFIG_FUNCTION_PROFILER=y

* ftrace 이벤트 종류 

- sched_switch: 컨텍스트 스위칭 동작
- sched_wakeup: 프로세스를 깨우는 동작
- irq_handler_entry: 인터럽트가 발생한 시각과 인터럽트 번호 및 이름을 출력 
- irq_handler_exit: 인터럽트 핸들링이 완료
- softirq_raise: Soft IRQ 서비스 실행 요청
- softirq_entry: Soft IRQ 서비스 실행 시작
- softirq_exit: Soft IRQ 서비스 실행 완료

 

(추가3)

Trace32 로 디버깅 시 명령어들 입니다.

=> https://www.youtube.com/watch?v=PQe1Jf5tDug&list=PLRrUisvYoUw9-cTYgkbTbr9f9CpbGdq4F&index=35

$ v.f /task 0xF1618000
$ v.v %all (struct task_struct*)0xF1618740
$ v.v %all (struct task_struct*)0xF1606000
$ v.v %all (struct thread_info*)0xF1606000
$ r
$ v.f
$ R.S R13 0
$ R.S PC 0
$ r.s  sp 0xF1607F48
$ r.s pc 0xC0FF4658
$ v.f
$ v.f /task 0xF1618740
$ v.v %all (struct thread_info*)0xF1604000

 

(추가4)

인터럽트에서 top half와 bottom half로 나누어 인터럽트 후반부 처리를 하는 이유입니다.

https://www.youtube.com/watch?v=RXs9RXpiNBw&list=PLRrUisvYoUw9-cTYgkbTbr9f9CpbGdq4F&index=58 

 

 

(추가6)

[리눅스 커널의 구조와 원리]의 개요는 아래와 같습니다.

▣ 01장: 리눅스 소개와 전망
1.1 리눅스와 리눅스 커널은 왜 배워야 할까?
__1.1.1 리눅스는 왜 배워야 할까?
__1.1.2 리눅스 커널은 왜 배워야 할까?
1.2 리눅스의 전망
__1.2.1 운영체제란 무엇인가?
__1.2.2 우리는 어떤 운영체제를 쓰고 있나?
1.3 리눅스의 역사
__1.3.1 유닉스의 탄생
__1.3.2 1991년: 리누스 토발즈의 등장
__1.3.3 리눅스가 인기 있는 이유는 무엇일까?
1.4 리눅스는 어디에 쓰일까?
__1.4.1 안드로이드
__1.4.2 자동차(AutoMotive)
__1.4.3 사물인터넷(IoT: Internet of Things) 디바이스
1.5 임베디드 리눅스 개발 단체
__1.5.1 리눅스 커널 커뮤니티
__1.5.2 CPU 벤더
__1.5.3 SoC 벤더
__1.5.4 보드 벤더 및 OEM
1.6 임베디드 리눅스 개발을 잘 하려면 무엇을 알아야 할까?
__1.6.1 디바이스 드라이버
__1.6.2 리눅스 커널
__1.6.3 CPU 아키텍처
__1.6.4 빌드 스크립트와 Git
1.7 라즈베리 파이와 리눅스 커널
__1.7.1 라즈베리 파이 실습 보드
__1.7.2 리눅스 커널 버전
__1.7.3 라즈비안 버전
__1.7.4 ARM 아키텍처
1.8 정리

▣ 02장: 라즈베리 파이 설정
2.1 라즈베리 파이란?
2.2 라즈베리 파이 설정
__2.2.1 라즈베리 파이 실습을 위한 준비물
__2.2.2 라즈베리 파이 설치
__2.2.3 라즈베리 파이 기본 설정
2.3 라즈베리 파이 커널 빌드
__2.3.1 라즈비안 버전과 커널 소스 버전
__2.3.2 라즈비안 커널 소스코드 내려받기
__2.3.3 라즈비안 리눅스 커널 빌드
__2.3.4 라즈비안 리눅스 커널 설치
__2.3.5 전처리 코드 생성
__2.3.6 리눅스 커널 소스의 구조
2.4 objdump 바이너리 유틸리티
2.5 라즈베리 파이 사용 시 주의사항
2.6 정리

▣ 03장: 커널 디버깅과 코드 학습
3.1 디버깅이란?
__3.1.1 디버깅은 문제 해결 능력의 지름길
__3.1.2 디버깅과 코드 학습 능력
3.2 printk
3.3 dump_stack() 함수
3.4 ftrace
__3.4.1 ftrace란?
__3.4.2 ftrace는 어떻게 설정할까?
__3.4.3 ftrace 메시지는 어떻게 분석할까?
__3.4.4 ftrace 로그는 어떻게 추출할까?
__3.4.5 ftrace는 커널 코드 분석의 안내자
3.5 임베디드 디버거의 전설 TRACE32
3.6 커널 디버깅용 Debugfs 드라이버 코드
3.7 정리

▣ 04장: 프로세스
4.1 프로세스 소개
__4.1.1 프로세스란?
__4.1.2 태스크란?
__4.1.3 스레드란?
4.2 프로세스 확인하기
__4.2.1 ps 명령어로 프로세스 목록 확인
__4.2.2 ftrace에서 프로세스 확인하기
4.3 프로세스는 어떻게 생성할까?
__4.3.1 _do_fork() 함수 소개
__4.3.2 유저 레벨 프로세스를 생성할 때 _do_fork() 함수의 처리 흐름
__4.3.3 커널 프로세스 생성 시 _do_fork() 함수의 흐름
4.4 유저 레벨 프로세스 실행 실습
__4.4.1 기본 유저 레벨 프로세스 실행 실습 및 ftrace 로그 분석
__4.4.2 exit() 함수로 프로세스가 종료되는 과정 및 ftrace 로그 분석
4.5 커널 스레드
__4.5.1 커널 스레드란?
__4.5.2 커널 스레드의 종류
__4.5.3 커널 스레드는 어떻게 생성할까?
4.6 커널 내부 프로세스의 생성 과정
__4.6.1 _do_fork() 함수
__4.6.2 copy_process() 함수 분석
__4.6.3 wake_up_new_task() 함수 분석
4.7 프로세스의 종료 과정 분석
__4.7.1 프로세스 종료 흐름 파악
__4.7.2 do_exit() 함수 분석
__4.7.3 do_task_dead() 함수 분석
__4.7.4 do_task_dead() 함수를 호출하고 난 후의 동작
4.8 태스크 디스크립터(task_struct 구조체)
__4.8.1 프로세스를 식별하는 필드
__4.8.2 프로세스 상태 저장
__4.8.3 프로세스 간의 관계
__4.8.4 프로세스 연결 리스트
__4.8.5 프로세스 실행 시각 정보
4.9 스레드 정보: thread_info 구조체
__4.9.1 thread_info 구조체란?
__4.9.2 thread_info 구조체 분석
__4.9.3 thread_info 구조체의 주소 위치는 어디일까?
__4.9.4 컨텍스트 정보 상세 분석
__4.9.5 cpu 필드에 대한 상세 분석
__4.9.6 thread_info 구조체 초기화 코드 분석
4.10 프로세스의 태스크 디스크립터에 접근하는 매크로 함수
__4.10.1 current 매크로란?
__4.10.2 current_thread_info() 매크로 함수 분석
4.11 프로세스 디버깅
__4.11.1 glibc의 fork() 함수를 gdb로 디버깅하기
__4.11.2 리눅스 유틸리티 프로그램을 이용한 실행 추적
4.12 정리

▣ 05장: 인터럽트
5.1 인터럽트 소개
__5.1.1 인터럽트란?
__5.1.2 리눅스 커널 인터럽트의 주요 개념
__5.1.3 인터럽트를 잘 알아야 하는 이유
__5.1.4 리눅스 커널에서의 인터럽트 처리 흐름
5.2 인터럽트 컨텍스트
__5.2.1 인터럽트 컨텍스트란?
__5.2.2 ftrace와 커널 로그로 인터럽트 컨텍스트 확인해보기
__5.2.3 in_interrupt() 함수란?
__5.2.4 인터럽트 컨텍스트에서 스케줄링을 하면 어떻게 될까?
5.3 인터럽트 핸들러는 언제 호출될까?
__5.3.1 인터럽트 벡터 분석
__5.3.2. 인터럽트 벡터에서 스택 푸시 확인
__5.3.3. 인터럽트 핸들러의 호출 흐름 분석
5.4 인터럽트 핸들러는 어떻게 등록할까?
__5.4.1 인터럽트 핸들러의 등록 과정 분석
__5.4.2 인터럽트 핸들러의 초기화 과정 디버깅
__5.4.3 인터럽트 핸들러 등록 시 플래그 설정
5.5 인터럽트 디스크립터
__5.5.1 인터럽트 디스크립터란?
__5.5.2 인터럽트 발생 횟수는 어떻게 저장할까?
5.6 인터럽트는 언제 비활성화해야 할까?
5.7 인터럽트 디버깅
__5.7.1 /proc/interrupts
__5.7.2 ftrace 인터럽트 이벤트
__5.7.3 ftrace로 인터럽트 핸들러 함수 파악하기
5.8 정리

▣ 06장: 인터럽트 후반부 처리
6.1 인터럽트 후반부 기법이란?
__6.1.1 인터럽트 후반부 기법을 적용하는 이유
__6.1.2 인터럽트 컨텍스트에서 많은 일을 하면 어떻게 될까?
__6.1.3 Top Half/Bottom Half란?
__6.1.4 인터럽트 후반부 처리 기법의 종류
__6.1.5 어떤 인터럽트 후반부 처리 기법을 적용해야 할까?
6.2 IRQ 스레드(threaded IRQ)
__6.2.1 IRQ란?
__6.2.2 IRQ 스레드 확인
6.3 IRQ 스레드는 어떻게 생성할까?
__6.3.1 IRQ 스레드는 언제 생성할까?
__6.3.2 라즈베리 파이에서 IRQ 스레드 생성 과정 디버깅
6.4 IRQ 스레드는 누가 언제 실행할까?
__6.4.1 IRQ 스레드를 깨우는 코드 분석
__6.4.2 IRQ 스레드 핸들러인 irq_thread() 함수 분석
__6.4.3 IRQ 스레드의 전체 실행 흐름 정리
6.5 IRQ 스레드 디버깅 실습
__6.5.1 ftrace를 이용한 IRQ 스레드 동작 확인
__6.5.2 IRQ 스레드 생성 실습
__6.5.3 IRQ 스레드 처리 함수 실행 시각 측정
6.6 Soft IRQ 소개
__6.6.1 Soft IRQ 서비스란?
__6.6.2 Soft IRQ의 전체 흐름
__6.6.3 후반부 기법으로 Soft IRQ를 언제 쓸까?
__6.6.4 Soft IRQ는 왜 알아야 할까?
6.7 Soft IRQ 서비스
__6.7.1 Soft IRQ 서비스
__6.7.2 Soft IRQ 서비스 핸들러는 언제 등록할까?
__6.7.3 Soft IRQ 서비스 핸들러의 등록 과정 실습
6.8 Soft IRQ 서비스는 언제 요청할까?
__6.8.1 Soft IRQ 서비스 요청의 전체 흐름
__6.8.2 raise_softirq() 함수 분석
__6.8.3 irq_stat 전역변수 분석
__6.8.4 Soft IRQ 서비스를 요청했는지는 누가 어떻게 점검할까?
6.9 Soft IRQ 서비스는 누가 언제 처리할까?
__6.9.1 Soft IRQ 서비스 실행 진입점은 어디일까?
__6.9.2 Soft IRQ 서비스 요청 점검
__6.9.3 Soft IRQ 서비스 실행
__6.9.4 ksoftirqd 스레드 깨우기
6.10 ksoftirqd 스레드
__6.10.1 ksoftirqd 스레드란?
__6.10.2 ksoftirqd 스레드는 언제 깨울까?
__6.10.3 ksoftirqd 핸들러 run_ksoftirqd() 함수 분석
6.11 Soft IRQ 컨텍스트에 대해
__6.11.1 Soft IRQ 컨텍스트 시작점은 어디일까?
__6.11.2 Soft IRQ 컨텍스트는 언제 시작할까?
__6.11.3 Soft IRQ 컨텍스트 확인
6.12 태스크릿
__6.12.1 태스크릿이란?
__6.12.2 태스크릿 자료구조
__6.12.3 태스크릿은 어떻게 등록할까?
__6.12.4 태스크릿의 전체 실행 흐름 파악
__6.12.5 태스크릿 실행 요청은 어떻게 할까?
__6.12.6 태스크릿은 언제 실행할까?
6.13 Soft IRQ 디버깅
__6.13.1 ftrace의 Soft IRQ 이벤트 소개
__6.13.2 /proc/softirqs를 이용한 Soft IRQ 서비스 실행 횟수 확인
6.14 정리

▣ 07장: 워크큐
7.1 워크큐 소개
__7.1.1 워크큐의 주요 개념
__7.1.2 워크큐의 특징
__7.1.3 워크큐와 다른 인터럽트 후반부 기법과의 비교
__7.1.4 워크큐로 인터럽트 후반부 코드를 설계하는 과정
__7.1.5 워크큐를 잘 알아야 하는 이유
7.2 워크큐의 종류
__7.2.1 alloc_workqueue() 함수 분석
__7.2.2 7가지 워크큐
7.3 워크란?
__7.3.1 work_struct 구조체
__7.3.2 워크는 어떻게 초기화할까?
7.4 워크를 워크큐에 어떻게 큐잉할까?
__7.4.1 워크를 워크큐에 큐잉하는 예제 코드 살펴보기
__7.4.2 워크큐 전체 흐름도에서 워크를 워크큐에 큐잉하는 과정
__7.4.3 워크를 워크큐에 큐잉하는 인터페이스 함수 분석
__7.4.4 __queue_work() 함수 분석
__7.4.5 __queue_work() 함수에서 호출하는 워크큐 내부 함수 분석
7.5 워크는 누가 언제 실행하나?
__7.5.1 워크 실행의 출발점인 worker_thread() 함수 분석
__7.5.2 process_one_work() 함수 분석
7.6 워커 스레드란?
__7.6.1 워커와 워커 스레드
__7.6.2 worker 구조체
__7.6.3 워커 스레드는 누가 언제 만들까?
__7.6.4 워커 스레드를 생성하는 create_worker() 함수 분석
__7.6.5 create_worker() 함수에서 호출한 워크큐 커널 함수 분석
__7.6.6 worker_thread() 함수 분석
7.7 워크큐 실습 및 디버깅
__7.7.1 ftrace 워크큐 이벤트
__7.7.2 라즈베리 파이에서 ftrace를 이용한 워크큐 동작 확인
__7.7.3 인터럽트 후반부 처리 실습과 로그 분석
7.8 딜레이 워크
__7.8.1 딜레이 워크란?
__7.8.2 딜레이 워크의 전체 흐름
__7.8.3 딜레이 워크는 어떻게 초기화할까?
__7.8.4 딜레이 워크 실행의 시작점은 어디일까?
__7.8.5 딜레이 워크는 누가 언제 큐잉할까?
7.9 라즈베리 파이에서의 딜레이 워크 생성 실습
__7.9.1 패치 코드의 내용과 작성 방법
__7.9.2 ftrace 로그 설정
__7.9.3 ftrace 로그 분석
7.10 정리


▣ 08장: 커널 타이머 관리
8.1 커널 타이머(저해상도 타이머)의 주요 개념
___8.1.1 HZ란?
___8.1.2 Soft IRQ의 타이머 서비스란?
___8.1.3 Soft IRQ 타이머(TIMER_SOFTIRQ) 서비스와 동적 타이머란?
___8.1.4 커널이 실행 시각을 관리하는 방식을 왜 잘 알아야 할까?
___8.1.5 커널 타이머 용어 정리
8.2 jiffies란?
___8.2.1 jiffies 소개
___8.2.2 jiffies와 jiffies_64 변수
___8.2.3 jiffies 값은 누가 언제 증가시킬까?
___8.2.4 msecs_to_jiffies() 함수란?
8.3 커널에서 시간을 흐름을 제어하는 방법
___8.3.1 time_after()/time_before() 매크로 함수
___8.3.2 time_after()/time_before() 함수의 사용 예
8.4 동적 타이머 초기화
___8.4.1 동적 타이머의 전체 흐름
___8.4.2 동적 타이머 자료구조
___8.4.3 동적 타이머 초기화 함수
8.5 동적 타이머 등록
___8.5.1 동적 타이머의 등록
___8.5.2 동적 타이머 등록 과정의 주요 함수
___8.5.3 동적 타이머 등록 과정에서 호출하는 함수 분석
8.6 동적 타이머는 누가 언제 실행할까?
___8.6.1 Soft IRQ 타이머 서비스에서 동적 타이머를 실행하는 과정
___8.6.2 Soft IRQ 타이머 서비스의 1~2단계 분석
___8.6.3 Soft IRQ 타이머 서비스에서 등록된 동적 타이머를 체크하는 단계의 코드 분석
___8.6.4 Soft IRQ 타이머 서비스 핸들러에서 등록된 동적 타이머를 실행하는 단계의 코드 분석
8.7 라즈베리 파이에서의 동적 타이머 실습 및 로그 분석
___8.7.1 ftrace의 동적 타이머 디버깅 이벤트 소개
___8.7.2 라즈베리 파이에서의 동적 타이머 등록 및 실행 과정을 ftrace로 확인하기
8.8 정리

▣ 09장: 커널 동기화
9.1 커널 동기화의 주요 개념
___9.1.1 임계 영역과 레이스 컨디션
___9.1.2 레이스 컨디션은 왜 발생할까?
___9.1.3 레이스 컨디션 관련 커널 패치
9.2 레이스 컨디션 발생 실습
___9.2.1 유저 프로세스에서 시스템 콜을 호출할 때 발생하는 레이스 컨디션
___9.2.2 커널 프로세스의 레이스 컨디션
___9.2.3 인터럽트 발생으로 인한 레이스 컨디션 발생
9.3 커널 동기화 기법
___9.3.1 스핀락과 뮤텍스 기법
___9.3.2 스핀락과 뮤텍스 기법의 차이점
9.4 스핀락
___9.4.1 스핀락의 특징
___9.4.2 스핀락 자료구조
___9.4.3 스핀락 사용 예제
___9.4.4 스핀락 처리 흐름
___9.4.5 spin_lock() 함수의 인라인 어셈블리 코드 분석
___9.4.6 spin_lock() 함수의 어셈블리 코드 분석
___9.4.7 spin_unlock() 함수 분석
___9.4.8 스핀락 플러그인 함수: spin_lock_irq()/spin_unlock_irq()
___9.4.9 스핀락 플러그인 함수: spin_lock_irqsave()/spin_unlock_irqrestore()
9.5 뮤텍스란?
___9.5.1 뮤텍스의 기본 개념
___9.5.2 뮤텍스의 fastpath 동작
___9.5.3 뮤텍스 slowpath: mutex_lock() 함수 분석
___9.5.4 뮤텍스 slowpath: mutex_unlock() 함수 분석
9.6 커널 동기화 디버깅
___9.6.1 스핀락
___9.6.2 뮤텍스 디버깅
9.8 정리

▣ 10장: 프로세스 스케줄링
10.1 스케줄링의 주요 개념
___10.1.1 스케줄링이란?
___10.1.2 선점 스케줄링과 비선점 스케줄링이란?
___10.1.3 컨텍스트 스위칭이란?
___10.1.4 스케줄링 정책이란?
___10.1.5 스케줄러 클래스란?
___10.1.6 런큐란?
___10.1.7 우선순위(nice)란?
10.2 프로세스 상태 관리
___10.2.1 프로세스 상태
___10.2.2. 프로세스 상태 변화
___10.2.3 어떤 함수가 프로세스 상태를 바꿀까?
___10.2.4 프로세스 상태를 ftrace로 확인하기
10.3 스케줄러 클래스
___10.3.1 스케줄러 클래스 자료구조
___10.3.2 5가지 스케줄러 클래스란?
___10.3.3 프로세스는 스케줄러 클래스를 어떻게 등록할까?
___10.3.4 프로세스는 스케줄러 클래스로 스케줄러의 세부 함수를 어떻게 호출할까?
10.4 런큐
___10.4.1 런큐 자료구조(rq) 소개
___10.4.2 runqueues 변수
___10.4.3 런큐에 접근하는 함수
___10.4.4 런큐 자료구조
10.5 CFS 스케줄러
___10.5.1 CFS 스케줄러의 주요 개념
___10.5.2 CFS 스케줄러 알고리즘
___10.5.3 CFS 관련 세부 함수 분석
___10.5.4 vruntime을 ftrace로 확인하는 실습
10.6 선점 스케줄링
___10.6.1 선점 스케줄링이란?
___10.6.2 선점 스케줄링 진입점은 어디일까?
___10.6.3 선점 스케줄링의 발생 시점을 아는 것은 왜 중요할까?
___10.6.4 선점 스케줄링의 진입점: 커널 모드 중 인터럽트 발생
___10.6.5 선점 스케줄링 진입점: 유저 프로세스 실행 중 인터럽트 발생
___10.6.6 선점 스케줄링 진입점: 유저 프로세스가 시스템 콜 처리를 마무리한 후
___10.6.7 선점 스케줄링 비활성화/활성화 함수 preempt_disable()/preempt_enable() 소개
10.7 프로세스는 어떻게 깨울까?
___10.7.1. 프로세스를 깨운다는 것은 무엇을 의미할까?
___10.7.2 프로세스를 깨울 때 호출하는 함수
___10.7.3 깨우는 프로세스를 런큐에 삽입하는 동작
10.8 스케줄링의 핵심 schedule() 함수
___10.8.1 schedule() 함수 분석
___10.8.2 schedule() 함수의 동작 정리
10.9 컨텍스트 스위칭
___10.9.1 컨텍스트 스위칭이란?
___10.9.2 컨텍스트 스위칭 관련 자료구조
___10.9.3 컨텍스트 스위칭의 세부 코드 분석
___10.9.4 ftrace를 이용한 컨텍스트 스위칭 동작 확인
___10.9.5 컨텍스트 스위칭 디버깅
10.10 스케줄링 디버깅
___10.10.1 ftrace: sched_switch와 sched_wakeup 이벤트 소개
___10.10.2 ftrace: 스케줄링과 프로세스를 깨울 때의 콜 스택 파악
___10.10.3 프로세스를 깨울 때의 콜 스택 분석
10.11 정리

▣ 11장: 시스템 콜
11.1 시스템 콜의 주요 개념
___11.1.1 시스템 콜이란?
___11.1.2 시스템 콜의 전체 흐름과 계층
___11.1.3 시스템 콜의 특징
___11.1.4 ARM 프로세서 관점의 시스템 콜 처리
___11.1.5 시스템 콜 테이블이란?
11.2 유저 공간에서 시스템 콜은 어떻게 발생할까?
___11.2.1 GNU C 라이브러리의 실행 흐름
___11.2.2 유저 공간에서 시스템 콜이 발생할 때의 어셈블리 코드 분석
11.3 커널 모드에서 시스템 콜을 어떻게 실행할까?
___11.3.1 소프트웨어 인터럽트 벡터 vector_swi는 어떻게 실행될까?
___11.3.2 소프트웨어 인터럽트 벡터 vector_swi 코드 분석
___11.3.3 커널 공간에서 시스템 콜 테이블 확인
11.4 시스템 콜 핸들러는 어떻게 동작할까?
___11.4.1 시스템 콜 종류별 시스템 콜 핸들러의 동작
___11.4.2 매개변수 점검
11.5 시스템 콜의 실행을 완료한 후에는 무슨 일을 할까?
___11.5.1 ret_fast_syscall 레이블의 복귀 과정
___11.5.2 ret_fast_syscall 레이블의 전체 실행 흐름
___11.5.3 시그널 전달 및 스케줄링 실행 조건 점검
___11.5.4 유저 공간으로 복귀
11.6 시스템 콜 관련 함수
___11.6.1 SYSCALL_DEFINEx 매크로 분석
___11.6.2 전처리 코드에서 시스템 콜 핸들러 확인
11.7 시스템 콜 디버깅
___11.7.1 ftrace 시스템 콜 이벤트
___11.7.2 ftrace 시스템 콜 핸들러의 콜 스택 확인
___11.7.3 strace를 이용한 시스템 콜 디버깅
___11.7.4 strace와 ftrace를 이용한 시스템 콜 디버깅
11.8 정리

▣ 12장: 시그널
12.1 시그널이란?
___12.1.1 유저 프로세스 입장에서 시그널이란?
___12.1.2 시그널 번호와 동작 방식
___12.1.3 시그널을 받으면 프로세스는 어떻게 동작할까?
___12.1.4 커널에서 시그널은 어떻게 처리할까?
___12.1.5 커널이 시그널을 처리하는 동작을 왜 잘 알아야 할까?
12.2 시그널 설정은 어떻게 할까?
___12.2.1 유저 공간에서의 시그널 설정
___12.2.2 커널 공간에서의 시그널 설정
___12.2.3 시그널 관련 시스템 호출 함수는 무엇일까?
12.3 커널 공간의 시그널 설정 함수 분석
___12.3.1 유저 공간에서 sigaction() 함수를 호출했을 때의 커널 실행 흐름
___12.3.2 유저 공간에서 pause() 함수 호출 시의 커널 실행 흐름 파악
12.4 시그널 생성 과정의 함수 분석
___12.4.1 유저 프로세스의 kill() 함수 실행
___12.4.2 유저 프로세스의 tgkill() 함수 실행
___12.4.3 커널은 언제 시그널을 생성할까?
___12.4.4 __send_signal() 함수 분석
___12.4.5 complete_signal() 함수 분석
12.5 프로세스는 언제 시그널을 받을까?
___12.5.1 ret_fast_syscall 레이블 분석
___12.5.2 인터럽트 핸들링 후 __irq_usr 레이블 코드 분석
12.6 시그널 전달과 처리는 어떻게 할까?
___12.6.1 do_work_pending()/do_signal() 함수 분석
___12.6.2 get_signal() 함수 분석
___12.6.3 handle_signal() 함수와 시그널 핸들러 호출 코드 분석
12.7 시그널 제어 suspend() 제어를 위한 분석
___12.7.1 유저 공간의 suspend() 함수
___12.7.2 커널 공간의 sys_rt_sigsuspend() 함수 분석
12.8 시그널에 대한 ftrace 디버깅
___12.8.1 ftrace의 시그널 이벤트 소개
___12.8.2 ftrace를 이용한 시그널의 기본 동작 로그 분석
___12.8.3 ftrace의 시그널 핸들러 동작 로그 분석
12.9 정리

▣ 13장: 가상 파일 시스템
13.1 가상 파일 시스템 소개
___13.1.1 가상 파일 시스템이란?
___13.1.2 가상 파일 시스템의 공통 모델
___13.1.3 함수 오퍼레이션
___13.1.4 유저 프로세스 입장에서 파일 처리
___13.1.5 파일 시스템별 파일 함수 오퍼레이션의 처리 과정
13.2 파일 객체
___13.2.1 file 구조체 분석
___13.2.2 파일 객체의 함수 오퍼레이션
13.3 파일 객체의 함수 오퍼레이션 동작 방식
___13.3.1 파일을 오픈할 때의 open 함수 오퍼레이션
___13.3.2 파일을 쓸 때의 write 함수 오퍼레이션
___13.3.3 파일을 읽을 때의 read 함수 오퍼레이션
___13.3.4 파일 포인터의 위치를 갱신할 때의 lseek 함수 오퍼레이션
___13.3.5 파일을 닫을 때의 close 함수 오퍼레이션
13.4 프로세스는 파일 객체 자료구조를 어떻게 관리할까?
___13.4.1 파일 객체의 파일 디스크립터 테이블 등록
___13.4.2 파일 디스크립터로 파일 객체를 로딩
___13.4.3 파일 디스크립터 해제
13.5 슈퍼블록 객체
___13.5.1 슈퍼블록 객체
___13.5.2 super_block 구조체 분석
___13.5.3 슈퍼블록 함수 오퍼레이션
___13.5.4 슈퍼블록의 함수 오퍼레이션 관련 시스템 콜
___13.5.5 슈퍼블록 정보를 statfs 시스템 콜로 읽는 과정
13.6 아이노드 객체
___13.6.1 inode 구조체 분석
___13.6.2 아이노드 함수 오퍼레이션
___13.6.3 파일 속성을 읽는 stat 시스템 콜의 처리 과정
13.7 덴트리 객체
___13.7.1 덴트리 객체 소개
___13.7.2 dentry 구조체 분석
13.8 가상 파일 시스템 디버깅
___13.8.1 파일 객체의 함수 오퍼레이션 확인
___13.8.2 슈퍼블록 객체의 함수 오퍼레이션 확인
___13.8.3 아이노드 객체의 함수 오퍼레이션 확인
13.9 정리

▣ 14장: 메모리 관리
14.1 가상 메모리 기법의 주요 개념
___14.1.1 가상 메모리의 주요 개념
___14.1.2 가상 메모리와 가상주소
___14.1.3 페이징에서 메모리 주소를 계산하는 방법
___14.1.4 페이지 프레임 번호와 페이지 디스크립터
___14.1.5 페이지 테이블이란?
14.2 가상주소를 물리주소로 어떻게 변환할까?
___14.2.1 가상주소 변환 과정의 전체 구조
___14.2.2 가상주소를 물리주소로 변환하는 단계
___14.2.3 페이지 테이블 관련 용어
___14.2.4 페이지 테이블의 종류
___14.2.5 가상주소를 물리주소로 변환하는 세부 원리
___14.2.6 가상주소를 물리주소로 직접 변환
14.3 메모리 존
___14.3.1 메모리 존의 종류와 개념
___14.3.2 메모리 존 자료구조 분석
___14.3.3 /proc/zoneinfo로 존 자료구조 확인하기
14.4 커널 동적 메모리 할당
___14.4.1 동적 메모리와 정적 메모리 할당
___14.4.2 kmalloc() 함수를 쓰는 이유
___14.4.3 kmalloc() 함수
___14.4.4 GFP(Get Free Page) 플래그
___14.4.5 kmalloc() 함수를 호출할 때의 주의 사항
14.5 슬랩 메모리 할당자와 kmalloc 슬랩 캐시 분석
___14.5.1 슬랩의 주요 개념
___14.5.2 kmalloc 슬랩 캐시
___14.5.3 kmalloc 슬랩 캐시 자료구조
___14.5.4 kmalloc 캐시 슬럽 오브젝트를 할당하는 커널 함수 분석
___14.5.5 슬럽 오브젝트를 해제하는 kfree() 함수 분석
14.6 디버깅으로 슬럽 오브젝트 할당과 가상주소 변환 방식 익히기
___14.6.1 ftrace를 이용한 메모리 할당 해제 확인
___14.6.2 가상주소를 물리주소로 변환하는 과정 확인
___14.6.3 kmalloc() 함수로 메모리 할당 후 슬랩 캐시 종류 확인
14.7 정리

▣ 부록A: GCC 지시어
A.1 __init과 __section()
A.2 inline
A.3 noinline
A.4 __noreturn
A.5 unused
A.6 __builtin_return_address() 함수
A.7 container_of

▣ 부록B: 리눅스 커널을 접하는 방법
B.1 블로그에 공부한 내용을 올리기
B.2 리눅스 사이트에서 답신 달기
B.3 커널 스터디 클럽
B.4 리눅스 커널 메일링 리스트 구독하기

▣ 부록C: 리눅스 커널 프로젝트에 기여하기
C.1 리눅스 커널 오픈소스 프로젝트 소개
__C.1.1 용어
__C.1.2 패치 반영 과정
C.2 설정 방법
__C.2.1 리눅스 배포판 소개
__C.2.2 git과 mutt 프로그램 설정
__C.2.3 리눅스 커널 소스코드 내려받기
__C.2.4 리눅스 커널의 git 정보
C.3 패치 코드를 작성한 후 이메일로 보내기
__C.3.1 패치 코드를 작성하기 전 커널 코드 분석
__C.3.2 커밋과 커밋 메시지 작성
__C.3.3 패치 코딩 룰 체크
__C.3.4 패치를 보낼 메일 수신자 확인
__C.3.5 mutt 프로그램으로 패치 전송
C.4 패치 코드 리뷰 과정과 업스트림(병합) 확인
C.5 리눅스 커널 오픈소스 프로젝트로 얻는 지식
__C.5.1 코드 리뷰
__C.5.2 Git 사용법
__C.5.3 개발자 간의 의사소통과 개발 문화

 

 

 

 

그럼,

    공유합니다.