Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

74261
1501
219116


[리눅스커널] 시간관리: jiffies와 jiffies_64 변수란 8. 커널 타이머 관리

jiffies와 jiffies_64 변수란

지금까지 커널에서 jiffies 개념에 대해 알아봤습니다. 그렇다면 커널 코드에서 어떤 변수가 jiffies일까요?

     jiffies와 jiffies_64 변수이다. 

뭔가 이상합니다. 어떻게 2개의 변수를 jiffies라고 말할 수 있을까요? 
이해를 돕기 위해 한 가지 예를 들겠습니다.
[https://github.com/raspberrypi/linux/blob/rpi-4.19.y/drivers/base/power/wakeup.c]
1 void pm_wakeup_ws_event(struct wakeup_source *ws, unsigned int msec, bool hard)
2 {
3 unsigned long flags;
4 unsigned long expires;
....
5 expires = jiffies + msecs_to_jiffies(msec);

5 번째 줄 코드를 보겠습니다. 
msecs_to_jiffies(msec) 함수 반환값에 jiffies를 더해 expires 지역 변수에 저장합니다.
5번째 줄에 있는 jiffies는 현재 시각 정보를 담고 있는 전역 변수입니다.

이번에는 다른 예제 코드를 보겠습니다.
[https://github.com/raspberrypi/linux/blob/rpi-4.19.y/kernel/time/timekeeping.c]
1 void do_timer(unsigned long ticks)
2 {
3 jiffies_64 += ticks;
4 calc_global_load(ticks);
5}

위 코드 3번째 줄을 보면 jiffies_64 전역 변수에 do_timer() 함수 인자인 ticks를 더하는 연산을 수행합니다. 3번째 줄에서 보이는 jiffies_64도 현재 시각 정보를 담고 있는 전역 변수입니다. 
 
여기서 한 가지 의문이 생깁니다. 

    pm_wakeup_ws_events() 함수에서 쓰는 jiffies와 do_timer() 함수에서 증감하는 
     jiffies_64 변수는 다른 값일까요?

정답은 같은 값입니다. 그러면 두 변수가 같은지 알아보기 위해 먼저 주소 위치를 알아볼까요?

라즈비안을 빌드하면 다음 경로에 System.map 파일이 생성됩니다.
이 파일에서 jiffies와 jiffies_64 심볼 주소를 확인해 볼까요?
80c03d00 D jiffies
80c03d00 D jiffies_64

jiffies와 jiffies_64 전역 변수가 같은 주소 공간에 있습니다.

어떤 원리로 서로 다른 두 변수가 같은 주소에 있을까요? 그 비밀은 링커 스크립트인  vmlinux.lds.S 파일을 열어보면 알 수 있습니다.
[https://github.com/raspberrypi/linux/blob/rpi-4.19.y/arch/arm/kernel/vmlinux.lds.S]
... 
jiffies = jiffies_64;

링커 스크립트는 커널 이미지를 빌드할 때 코드 내용이 반영됩니다. 위 코드의 목적은 jiffies와 jiffies_64 변수를 같은 주소에 지정하는 것입니다.

다음 그림을 보면 jiffies와 jiffies_64 변수의 관계를 알 수 있습니다.
 
[그림  jiffies와 jiffies_64 변수의 주소 위치

두 변수는 주소가 같지만 사이즈가 다른 것입니다. jiffies는 jiffies_64 시작 주소 기준으로 4바이트 주소 공간에 있는 값을 저장합니다.

 중요한 점은 jiffies로 상대적인 시간을 표현하다는 사실입니다. 현재 jiffies와 미래 시점(1분 후, 2분 후)의 jiffies 차이로 시간 흐름을 관리합니다. 따라서 jiffies 값 그 자체는 공학적으로 의미는 없습니다.

리눅스 커널에서는 왜 jiffies와 jiffies_64이란 변수가 두 개가 있을까
처음 리눅스 커널 코드는 타이머를 관리하는 변수인 jiffies는 u32 크기였습니다. 이후 64비트 아키텍처를 도입하면서 더 큰 변수를 저장할 수 있는 u64타입 jiffies_64 전역 변수를 쓰기 시작했습니다. 그런데 문제가 생겼습니다. 기존에 jiffies라는 변수로 드라이버 코드를 작성한 개발자들이 jiffies를 jiffies_64로 바꿔야 했습니다. 그런데 리눅스 개발자들은 실행 흐름을 jiffies 변수로 처리하는데 익숙했습니다. 결과 리눅스 커널 소스 관리가 어렵게 됐습니다. 그래서 두 변수를 같은 주소 공간에 위치하게 링커 스크립트를 바꾼 것입니다. 링커 스크립트로 jiffies와 jiffies_64를 같은 주소에 위치시켜 이런 문제를 없앤 것입니다.

다른 변수인데 기존 jiffies와 jiffies_64 변수가 어떻게 같이 공존할 수 있을까요? 그 이유는 두 변수는 상대적인 시각을 표현하기 때문입니다.

* 강의 동영상도 있으니 같이 들으시면 좋습니다.






#커널 시간관리 목차
커널 타이머 관리 주요 개념 소개
jiffies란
커널 타이머 제어
동적 타이머 초기화
동적 타이머 등록하기
동적 타이머는 누가 언제 실행하나?
라즈베리파이 커널 타이머 실습 및 로그 분석

"혹시 궁금점이 있으면 댓글로 질문 남겨주세요. 아는 한 성실히 답글 올려드리겠습니다!"


# Reference: For more information on 'Linux Kernel';

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

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



 




핑백

덧글

댓글 입력 영역