고급 개발자로 가는 길
반응형

Embedded/Linux Kernel 16

[Linux Kernel] 테스크 디스크립터 매크로 함수

매크로 얘기에 앞서, 프로세스 생성 시 copy_process 함수를 통해 최종적으로 task_struct 메모리 영역을 슬럽 캐시를 통해 미리 할당해 놓고, ARMv7 의 경우 mmu에 page 2개로 할당하여 0x2000의 스택 메모리 영역을 할당 받게 된다. 참고로 스택영역은 페이지 사이즈의 2배이다. 실제 소스에서 PAGE_SIZEfiles, 0, nofile, flags); } 실제 위 함수는 프로세스의 파일 디스크립터 할당을 위한 함수로 current 매크로를 통해 files 에 접근해 전달 한다. 실제 전역이나 지역변수로 할당은 안되어 있지만, task_struct * 와 같이 동작하게 된다. 이 밖에도 수 많은 함수에서 current 매크로 확인이 가능하다. 즉, 현재 구동 중인 프로세스의..

[Linux Kernel] 스레드 자료구조 thread_info 간단 설명

thread_info 구조체 task_struct 는 프로세스의 속성을 관리하고, thread_info 구조체는 프로세스 실행 동작을 관리한다. 테스크 디스크립터는 프로세스의 공통 속성 정보를 저장하고 관리하는데, 실제 세부 실행 정보를 저장 또는 로딩하는 자료구조로는 thread_info 가 사용 된다. 구조체의 특징으로는 선점 스케줄링 실행 여부 시그널 전달 여부 인터럽트 컨텍스트와 soft irq 상태 휴면 상태로 진입하기 직전 레지스터 세트를 로딩 및 백업 thread_info 구조체는 프로세스 스택의 최상단 주소에 있다. 프로세스 마다 자신의 스택영역이 있으니, 즉, 프로세스 마다 1개의 thread_info 구조체가 있는 것이며, ARM32bit 에서 프로세스 실행되는 스택의 크기는 0x200..

[Linux Kernel] 테스크 디스크립터 자료구조

테스크 디스크립터 task_struct 구조체로, 프로세스의 속성 정보를 표현하는 가장 중요한 자료구조이다. TCB Task Control Block 이라고 Context switch 시 TCB 를 참고하여 진행이 된다. TCB 는 프로세스의 정보를 표현하는 자료구조이다. 리눅스 커널에서 프로세스의 정보를 표현하는 자료구조가 바로 테스크 디스크립터 인 것이다. 리눅스 bash 를 통해 입력되는 ps 정보 또한 테스크 디스크립터 필드에 저장 된 값을 읽어서 표현된다. 리눅스 시스템에서 구동중인 프로세스 목록 또한 init_task.tasks 인 연결리스트에 접근해 출력 된다. 그럼 각 중요 항목들을 정리해보면, 프로세스 식별 필드 pid_t pid; 정수형인 프로세스 ID 값인 pid 이다. char co..

[Linux Kernel] gcc 컴파일 옵션

gcc 옵션 -v : 컴파일 상태 출력 -O2 : 최적화 레벨 2 적용 -E : 전처리 과정 결과 출력. --save-temps 옵션 사용 추천 -S : cc1으로 전처리된 파일을 어셈블리 파일(.s) 까지만 컴파일 -c : as에 의한 어셈블까지만 수행하고 링크하지 않음 --save-temps : 전처리 파일(*.i) 과 어셈블리 파일(*.s) 를 지우지 않고 현재 디렉토리에 저장 (컴파일 오류 분석용) cpp0 옵션 (전처리기) -I : 헤더 파일 경로 (ex. -I/usr/local/include) -D[매크로]=[값] : #define 매크로 (ex. -DDEBUG, -DPACKAGE=1) -U[매크로] : #undef 매크로 -M : make를 위한 소스 파일의 모든 종속 항목 출력 -MM : ..

[Linux Kernel] ftrace 를 통한 유저 레벨 프로세스 분석(POSIX exit 종료 방식)

프로세스 종료 방식 프로세스 종료 방식은 크게 두 가지로 나뉜다. 1, 유저 레벨에서의 Signal 종료 아래 경로 글에서 Signal 방식의 종료에 대하여 ftrace 를 통해 분석하였다. 2022.02.07 - [Embedded/Linux Kernel] - [Linux Kernel] ftrace 를 통한 유저 프로세스 분석 [Linux Kernel] ftrace 를 통한 유저 레벨 프로세스 분석 먼저 유저 프로세스 생성을 위한 raspbian_test.c 파일 이다. #include #include #define PROC_TIMES 500 #define SLEEP_DURATION 3 // second unit int main() { int proc_times = 0; for(proc_times = 0..

[Linux Kernel] 프로세스 소멸 과정 소스 분석

프로세스 종료 방식 프로세스 종료 방식은 크게 두 가지로 나뉜다. 1, 유저 프로세스 레벨에서의 Signal 종료 아래 글에서 Signal 방식의 종료에 대하여 ftrace 를 통해 분석하였다. 2022.02.07 - [Embedded/Linux Kernel] - [Linux Kernel] ftrace 를 통한 유저 프로세스 분석 [Linux Kernel] ftrace 를 통한 유저 레벨 프로세스 분석 먼저 유저 프로세스 생성을 위한 raspbian_test.c 파일 이다. #include #include #define PROC_TIMES 500 #define SLEEP_DURATION 3 // second unit int main() { int proc_times = 0; for(proc_times =..

[Linux Kernel] ftrace 를 통한 유저 레벨 프로세스 분석(Signal 종료 방식)

먼저 유저 프로세스 생성을 위한 raspbian_test.c 파일 이다. #include #include #define PROC_TIMES 500 #define SLEEP_DURATION 3 // second unit int main() { int proc_times = 0; for(proc_times = 0; proc_times < PROC_TIMES; proc_times++) { printf("raspbian tracing \n"); sleep(SLEEP_DURATION); } return 0; } 위의 .c 파일을 빌드 하기 위한 Makefile 이며, make 를 통해 빌드 진행 하여 raspbian_proc 실행 파일 생성 raspbian_proc: raspbian_test.c gcc -o ra..

[Linux Kernel] 커널 스레드(프로세스) 생성 과정 소스 분석

systemd 프로세스는 유저 공간에서 생성된 프로세스의 부모 프로세스 역할을 수행한다. 보통은 init 프로세스라 부르기도 한다. 보통 유저 프로세스에서 부모 프로세스가 소멸 되면, init 프로세스가 부모 역할을 수행하게 된다. ps -ejH 프로세스 생성 과정 크게 두가지로 분류 할 수 있다. 1. 유저 레벨에서 생성된 프로세스 라이브러리(GNU C : glibc) 의 도움을 받아 커널에게 프로세스 생성 요청 2. 커널 레벨에서 생성된 프로세스 커널 내부의 kthread_create() 함수를 호출하여 커널 프로세스 생성 대부분 이를 커널 스레드 라고 부른다. 둘의 공통점은 _do_fork() 함수를 호출한다는 점이다. init 프로세스 : 유저 레벨 프로세스 생성 kthreadd 프로세스 : 커널..

[Linux Kernel] 커널에서의 프로세스 테스크 스레드 이해

실제로 개발을 하면서 프로세스, 테스크, 스레드 등을 자주 사용 한다. 객체지향인 C++ 에서도 API 에서 제공하는 스레드를 사용하기도 하고 MFC 로 개발할 경우 MFC 에서 제공하는 스레드를 사용하곤 한다. 물론 스레드는 프로세스와 다르게 메모리를 공유하여 컨텍스트 스위칭이 빠른 장점도 있지만, 그 만큼 임계영역을 나누어야 하며, 필자는 실무로 C++ 개발 시 임계영역으로 Critical Secsion 을 사용했었다. 이렇듯, OS 별로 사용 방식이 상이하다. 리눅스에서도 위의 개념이 존재하게 되는데, 유저영역과 커널영역에 따라 나누어진다. 이 글에서는 리눅스 시스템에서의 프로세스에 대하여 알아가 보도록 하자. 프로세스 우선 프로세스는 실제 리눅스 시스템 메모리에서 실행 중인 프로그램을 뜻한다. 리..

[Linux Kernel] 커널 디버깅용 Debugfs 드라이버 코드

우선 해당 드라이버 코드는 [LG전자 김동현님]의 코드를 참조한 것이다. 커널 소스를 수정하여 빌드 할 경우, 잘못 오류를 범하게 되면 커널 패닉이나, 시스템 락이 발생하여, 다시 이미지를 라이팅하는 상황이 발생할 수 있다. 그러한 경우를 방지하기 위해 Debugfs 드라이브 코드를 작성하여, 필요시에만 수정된 소스를 커널에 반영하는 방식을 알아 보도록 할 것이다. 먼저 아래 소스를 참고하면 된다. 내용은 간단하다. get, set 을 통해 raspbian_debug_state 전역변수에 값을 쓰고 읽는다. 눈치를 채신분도 계실텐데, 우리는 저 전역변수를 통해 if 문으로 제어 할 것이다. #include #include #include //#include #include #include #include..

[Linux Kernel] ftrace Log 포맷 해석 및 발생 경로 확인

ftrace 에는 크게 4가지 이벤트가 존재한다. sched_switch sched_wakeup irq_handler_entry irq_handler_exit 각 ftrace 이벤트 별로 당연히 발생되는 경로와 이유가 존재한다. 이번 글을 통해 어떻게 해석하고 어떻게 발생되는지를 알아가 보자. ftrace 로그를 분석하기 위해서는 공통 포맷을 알아야 한다. 아래는 sched_switch 로그의 예시이다. 컨텍스트 정보를 자세히 들여다보면, d... 총 4자리로 인터럽트 활성/비활성 여부 선점 스케줄링 설정 여부 인터럽트 컨텍스트 or Soft Irq 컨텍스트 여부 preempt count 값 으로 구성이 되어있다. 즉 Chromium-browse 프로세스에서 CPU2번에 인터럽트는 비활성된 상태이고 94..

[Linux Kernel] ftrace 디버깅 사용하기

필자가 사용하는 라즈비안(리눅스) 에서는 ftrace 가 자동으로 설정 되어있다. 기존의 linux 의 경우 arch/arm/configs/bcm2711_defconfig 에 trace 관련 CONFIG_###=y 를 해주면 된다. bcm2711_defconfig 는 커널 빌드 시 사용되는 config 파일이다. 결론은, 라즈비안의 경우 아래 경로를 통해 ftrace 설정파일을 확인 할 수 있다. /sys/kernel/debug/tracing 실제로 수많은 파일이 있지만 정작 자주 사용하는 파일은 많지 않다. 먼저 ftrace 설정하는 방법을 통해 위 디렉터리에 있는 파일이 어떤 기능을 수행하는지 확인 해 볼 것이다. ftrace 설정 자세한 내용은 주석을 달아놨으니 참고 바란다. #!/bin/bash ..

[Linux Kernel] objdump 바이너리 유틸리티

objdump 인 바이너리 유틸리티를 다루어 볼 것이다. 바이너리 유틸리티는 오브젝트 포멧의 파일을 조작 할 수 있다. 보통 라이브러리나 elf 형식의 파일을 어셈블리어 or 섹션 정보 등 출력이 가능하다. 아래는 vmlinux 를 vi 에디터로 열었을 때의 상황이다. objdump 를 통해 아래 파일을 분석 해보자 먼저 objdump 의 옵션을 아래와 같이 볼 수 있다. -x 옵션을 통해 섹션 정보 확인이 가능하다. start 어드레스 영역과 아키텍처 정보도 확인 가능하다. objdump -x vmlinux | more 다음은 -d 옵션을 통해 어셈블리어로 확인 가능하다. objdump -d vmlinux | more 하지만 위 처럼 많은부분을 어셈블리어 만으로 보기는 힘들다. 그럴땐 address 로..

[Linux Kernel] 전처리 코드 생성 : 특정 전처리 파일 추출

전체 전처리 방식이 궁금하다면 아래 글을 참고하길 바란다. 2022.01.27 - [Embedded/Linux Kernel] - [Linux Kernel] 전처리 코드 생성 : 전체 전처리 파일 추출 [Linux Kernel] 전처리 코드 생성 : 전체 전처리 파일 추출 리눅스 커널은 캡슐화나 다형성 등 객체지향 방식으로 구현이 된 소스들이 많다. 사실 필자는 객체지향 언어를 좋아하다 보니 오히려 편하다. 본론으로 돌아와 그래서 매크로로 구현된 코드가 darkengineer.tistory.com 이 글 에서는 특정 전처리 파일 추출 방법에 대해 설명해 보겠다. 전체 전처리 추출 방식은 많은 메모리를 잡아 먹게 된다. 그리고 빌드를 수시로 해야되는 단점도 존재한다. 그래서 이럴 때 특정 전처리 추출 방식이..

[Linux Kernel] 전처리 코드 생성 : 전체 전처리 파일 추출

리눅스 커널은 캡슐화나 다형성 등 객체지향 방식으로 구현이 된 소스들이 많다. 사실 필자는 객체지향 언어를 좋아하다 보니 오히려 편하다. 본론으로 돌아와 그래서 매크로로 구현된 코드가 많다. 이러한 매크로가 소스 분석의 걸림돌로 작용한다. 바로 전처리 코드는 이러한 매크로를 모두 풀어서 표현을 한다. 즉, 편하게 소스코드를 분석 할 수 있게 된다. 전처리 코드는 GCC 컴파일 오브젝트 생성 과정에서 추출된다. 커널에서 전처리 코드를 추출 하는 방법은 크게 두 가지 이다. 전체 전처리 파일 추출 특정 전처리 파일 추출 이 글에서는 전체 전처리 파일 추출하는 방법을 알아보도록 하자. 전체 전처리 파일 추출 방법 Makefile 에 '-save-temps=obj \' 구문 추가가 필요하다. 아래 500번 라인..

[Linux Kernel] 리눅스 커널 빌드 flex, bison 오류 해결하기

커널 빌드를 진행 하면 아래와 같은 Error 를 보는 경우가 있다. 원인은 flex 와 bison 패키지 설치가 안되어 있어서 이다. 리눅스에서는 gcc 컴파일러를 사용하는데, 바로 gcc에서 flex 와 bison을 사용하기 때문이다. 아래 명령어로 패키지 설치를 진행한다. sudo apt-get install flex sudo apt-get install bison 진행 후 커널 빌드를 진행하면 해당 문제가 해결되는 것을 확인 할 수 있다.

반응형