본문 바로가기
Programming/Android Kernel,Native

안드로이드의 프로세스 - init process_1

by 개Foot/Dog발?! 2014. 10. 8.

URL : http://bulldozer121.tistory.com/10


.....


init process


어제 적었던 booting process 에 따르면 init process 는 kernel 이 부팅하고 나서 최초로 사용자 영역에서 실행 되도록 만들어진 process 이다. 그리고 이 init process 가 실행되고 나면 system 동작에 필요한 다른 process 들을 순차적으로 init process 가 실행을 시키는 것이다.


그리고 init process 는 부팅이 완전히 이루어지고 나서 사용자 이용환경이 완성된 이후에도 계속적으로 백그라운드에서 동작하면서 다른 process 들을 감시한다. 감시 중인 process 가 종료되면 조건에 따라 재실행을 시키는 역할을 한다.


kernel booting 에서 부터 init process 실행까지의 과정은 코드로 나타낼 수 있다.

start_kernel() -> init_post() -> run_init_process() -> init process 실행



지금은 드물지만 초기에 커스텀 커널을 빌드하던 개발자들의 글을 보면 종종 커널 패닉이라는 용어들을 보게된다.

그냥 단순히 커널이 작동을 안하는구나 라고 생각을 하며 관련 글들을 읽었었는데, 그 원인은 다음에 있다고 한다.

init process 가 정상적으로 실행이 되기 위해서는 kernel booting option 에 

"init=/init" 와 같은 조건이 주어져야 한다.

안드로이드 빌드 후에 생성되는 root file system 에서 init process 가 최상위 directory 에 있기 때문이다


root file system 의 최상위 directory 에 init process 가 없거나 booting option 에 

"init=" 을 설정하지 않으면 kernel 은 /sbin, /etc, /bin directory 에서 init file 을 찾는다고 한다. 

이러한 과정 중에 찾는 모든 directory 에 init file 이 존재하지 않으면 kernel 이 init process 를 실행하지 못하게 되고 이것을 kernel panic 이라고 부른다고 한다.


init process 가 하는 일은 간단히 4가지로 분류할 수 있다.

1. init.rc 파일 분석 및 실행

2. device driver node 생성 (application 이 driver 에 접근할 때 사용)

3. 자식 process 의 종료처리

4. property service (system 동작에 필요한 환경 변수를 저장)


*. init.rc 파일 분석 및 실행 과정

init.rc file parsing

init{hardware}.rc file parsing

early-init action list 실행

init action list 실행

early-boot & boot action list 실행

service list 실행


*. device driver nede 생성 과정

directory 생성 및 mount

device 정적 node 생성

poll event 등록

poll 대기

device 동적 node 생성


*. 자식 process 의 종료처리 과정

SIGCHLD signal handler 등록

UDS 를 위한 socket 생성

poll event 등록

poll 대기

자식 process 재 시작(or not)


*. property serivce 과정

property 초기화

property 초기 설정

property service 실행

poll event 등록

poll 대기

property service 제공


위 2, 3, 4 의 항목을 보면 poll 대기 부터는 중첩되는것을 알 수 있다.

poll 대기 부터 이후의 init process 내부의 과정을 이벤트 처리 루프라고 한다.


위 내용 중 SIGCHLD 라는 것은 linux process 들은 서로 정보를 교환하는데 그 message 를 signal 이라고 명기하며, 

각 process 는 다른 process 에서 발생하는 signal 을 처리하기 위한 routine 을 등록하는데 이를 signal handler 라고 한다.

init process 가 생성시킨 자식 process 의 종료시에 발생하는 signal 이다.

init process 가 백그라운드에서 자식 process 를 감시하고 있다가 자식 process 가 종료되게 되면 SIGCHLD 를 감지하여 추가적인 재시작 혹은 종료의 process 함수(signal handler)를 진행 시킨다.


그리고 init process 는 signal handler 를 등록한 이후에 booting 에 필요한 directory 를 생성 및 mount 한다.

주로 생성하는 directory 는

/dev[tmpfs]

/proc[proc]

/sys[sysfs] 

이다


/dev 는 hardware 장치를 접근하기 위한 device driver 가 존재하는 공간이다.


init.rc


.....

zImage 내부에 initramfs.cpio 내부에 init.rc 가 존재하며 이 init.rc 는 init process가 수행할 일을 지정하는 파일이기 때문이다.


.....


init.rc 파일은 action list service list 로 나뉜다.


action list 는 on keyword 로 시작하고, system 환경 변수를 등록하거나 linux 명령어 들을 통해 booting 시 필요한 directory 생성 및 특정 file 에 대한 permission 을 지정한다.


service list 는 service keyword 로 시작하고, booting 시 실행하는 process 를 기술한다.


action list 에서 보면

on init section 의 내용 중 참고할 만한 내용은 우리가 주로 알고 있는 /system 과 /data derectory 에 대한 mount 를 action list 에 의해서 on init 과정에서 진행된다는 것이다.

on init section 주문에 의해서 /system 과 /data directory 가 mount 되면 안드로이드 의 루트 파일 시스템이 완성된다.


root 영역에는 

/proc, /dev, /sbin, /etc, /system, /data, /dbdata, /cache, /mnt 등의 directory 가 존재한다.

간단히 linux 의 directory 에 대해 적어보면


/ -> root directory_절대 경로의 기준 directory, 모든 directory 의 출발점이자 다른 파티션의 연결점.

/sbin -> system 관리용 실행 file 들이 존재.

/proc -> process directory_process 들이 file 형태로 존재, kernel 의 function 을 제어, 쓰기 가능 file 에 parameter 를 지정하면 kernel 의 function 을 조작이 가능.

/dev -> device directory_device driver 들이 저장되어져 있는 공간.

/etc -> system 설정 file directory_system 에 관한 각 환경 설정에 연관된 file 과 directory 들이 존재.

/mnt -> mount directory_이동형 장치를 mount 하기 위해서 만들어 놓은 공간.


on boot section 의 내용 중 참고할 만한 내용은 application 종료 조건 설정, application 구동에 필요한 directory 및 file permission 설정 등이 on boot 과정에서 진행된다는 것이다.

여기에서 참고할 만한 부분이 있다.

우리가 galaxy tuner application 을 사용하는 옵션 중에 memory manager 가 있다.

이 부분에 대한 OOM(out of memory) 조정값(ADJ) 을 지정하는 과정에 on boot section 에서 이루어진다.

application group 은

foreground_app (ADJ = 0)

visible_app (ADJ = 1)

secondary_server (ADJ = 2)

home_app (ADJ = 4)

hedden_app_min (ADJ = 7)

content_provider (ADJ = 14)

empty_app (ADJ = 15)

이다. ADJ 값은 기본값을 나타냈다.


OOM 은 kernel 상에서 application 에 할당하는 memory 를 monitoring 하면서 memory 가 부족할 때 application 을 종료시키는 역할을 한다. ADJ 값이 높을 수록 종료 우선순위가 높은것이다.

on porperty section 에서는 property 값이 변경될 경우 실행되는 명령이 기술되어 있다.


serivce list 에서 보면

service section 은 init process 가 실행 시키는 process 를 기술한다.

여기에서 init process 가 실행시키는 자식 process 에는 일회성 process 와 daemon process 가 있다.

일회성 process 는 부팅과정에서 실행되었다가 종료되는 process 로써 간단히는 부팅음 출력과 같은 process 가 있다.

daemon process 는 백그라운드에서 구동되면서 application 이나 system 운용에 계속적 으로 관여를 하는 process 이다.

기본적인 daemon list 는 앞장인 booting process 에 적어놓았다.


추가적으로 init.rc 에 저장되는 내용은 AIL이라는 문법을 사용한다.

여기에서 AIL 은 android init language 의 약자이다.

간단히 AIL 은 네 가지 종류로 구분이 되는데

Action, Commands, Services, Options 이다.