일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- python
- 인공지능
- Linux
- 우분투
- 해외직구
- 김경문
- 데이터베이스
- 손민한
- 타이젠
- ubuntu
- 프로야구
- arm
- ubuntu 12.04
- 문파문파
- 애플
- 뉴스타파
- 단통법
- 디자인 패턴
- 안드로이드
- 조세피난처
- Tizen
- NC 다이노스
- mysql
- 야구
- 문파문파 공략
- 리뷰
- NC다이노스
- 블로그
- 태그를 입력해 주세요.
- 국정원
- Today
- Total
꿈꾸는 사람.
[리눅스 3.16.6] Init call mechanism. 디바이스 드라이버 초기화 호출 체계. 본문
리눅스 디바이스 드라이버는 특정한 하드웨어나 장치를 구동하는 커널의 일부로 동작하는 프로그램이다.
리눅스에는 디바이스 드라이버들의 초기화 코드를 호출하는 최적화된 체계가 있다.
이번 글은 리눅스의 내장(built-in) 디바이스 드라이버의 초기화 호출 체계를 분석한다.
1. 디바이스 드라이버 작성
디바이스 드라이버는 커널 공간에 적재될 때 장치를 제어하는 기능을 하며 이를 위해 다음 함수를 만들어야 한다.
module_init(my_func_init);
module_exit(my_func_exit);
my_func_init가 커널이 부팅될 때 어떻게 불리는지 찾아보자.
2. 디바이스 드라이버 호출 과정.
my_func_init이 호출되는 함수 호출 과정은 아래 그림과 같다.
do_one_initcall 함수의 fn()이 my_func_init()이다.
if (initcall_debug) ret = do_one_initcall_debug(fn); else ret = fn();
이 과정을 소스를 추적하며 분석한다.
3. 초기화 호출 체계 분석
커널 내장 모듈의 module_init은 매크로로 아래와 같이 확장된다.
#define module_init(x) __initcall(x);
#define __initcall(fn) device_initcall(fn)
#define device_initcall(fn) __define_initcall(fn, 6)
#define __define_initcall(fn, id) \ static initcall_t __initcall_##fn##id __used \ __attribute__((__section__(".initcall" #id ".init"))) = fn; \ LTO_REFERENCE_INITCALL(__initcall_##fn##id) |
static initcall_t __initcall_my_func_init6 __used __attribute__((__section__(".initcall6.init"))) = my_func_init; |
__initcall_my_func_init6 심벌이 만들어 지고 .initcall6.init란 EFL 영역에 추가 한다.
정리된 내용은 아래 그림과 같다.
for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++) do_one_initcall(*fn);
module_init으로 초기화 되는 모든 내장 모듈들은 6번째 레벨이고 __initcall6_start에서 시작해서 __initcall7_start 직전에 끝난다.
__initcall6_start는 .initcall6.init 영역에 등록된 첫 함수 포인터의 주소이다.
6번째 레벨의 함수들이 초기화 되는 순서는 Makefile내의 파일 순서를 따른다.
obj-y += gpio/
...
obj-y += tty/
즉, gpio 디바이스 드라이버가 tty 디바이스 드라이버보다 먼저 생성되고 올라 온다.
정리한 내용 전체는 파일로 첨부한다.
'IT > Linux' 카테고리의 다른 글
[Ubuntu 14.04] hostname 변경. (0) | 2015.03.16 |
---|---|
cygwin x widow, connect to server using GUI. (0) | 2015.01.09 |
리눅스 커널 빌드. 커널 구성. 커널 컴파일. 커널 설치 후 재부팅. (2) | 2014.10.27 |
[Ubuntu 14.04 LTS] 해상도 문제. virtualbox 게스트 확장 설치. 해상도 문제 해결. (5) | 2014.10.21 |
Ubuntu 14.04 LTS 설치. [무료 가상화 시스템 VirtualBox] (0) | 2014.08.20 |