안녕하세요~^^
Bulldozer 입니다~^^
한참 맛클에서 공부할 때는 여러 방면으로 관심을 많이 갖고 깊숙히 파고드시는 분들이
많으셨는데 요즘은 제가 눈팅유저로 살고 있어서 잘은 모르지만 OTL...
분위기가 조금은 달라진듯 하여 ^^;;
제 블로그에 예전에 적었던 글인데 혹시 이 글을 보고 이런 방면으로도 관심을 갖게 되실 분들이
있을까 싶어 제 글을 제가 퍼왔습니다 ^^;;
전 극히 개인적인 용도로 블로그에 포스팅을 하기 때문에 글이 다소 건방지다고?? ^^;;
느끼지실 수도 있습니다만~ OTL...
있는 그대로 가져왔기에 이해바랍니다 ^^;;
[110427_댓글 중 Bvlgari 님의 요청??으로 유저 노하우 게시판으로 옮깁니다. 그리고 제목 수정]
----------------------------------------------------------------------------------------------------------
어제 저녁에 기본적인 안드로이드의 booting process 에 대해 간략하게 적었다.
확실히 느낀 부분인데 그냥 책을 읽는것과 글을 적으며 정리를 하는것은 큰 차이가 있는것 같다.
글을 적고난 이후에 확실히 더욱 머릿속에 명확히 정리가 되는 느낌이다.
요즘 이쪽으로 공부를 하면서 조금 안타까운 부분이라면...
대부분의 스마트폰 유저들은 자신만의 custom kernel 을 build 하여 사용해 보고 싶다는 욕구를 가지고 있는듯한데
정확히 kernel 이 무슨 일을 하는지, init process, init.rc 등에 대한 원리나 여러가지에 대해서는 관심도가 낮은듯 하다.
정확한 원리과 구조를 먼저 공부한다면 더 깊이있는 지식을 얻을 수 있을것 같은데...
그리고 이쪽을 공부하다보니 아직은 linux 나 여러 주변 지식이 부족하여 못하고 있지만
조금만 원리에 대해 그리고 구조에 대해 공부를 하면 결코 어려운것은 아닌듯 하다.
원리와 구조의 이해를 배재하고 방법을 쫒아가는 방향으로 지식을 쌓으려 하지 말아야겠다.
오늘 맛클에 올라온 글을 보니 해외판 진저브레드 갤럭시 S 의 초기 펌웨어가 유출된듯 하다.
맛클 유저중 한명이 odin 으로 펌웨어를 입혀보았으나 당연한 결가일지 모르지만 잘 작동은 하지 않는듯 하다.
곧 국내판 진저브레드 펌웨어도 나올듯 한데 얼마만큼의 최적화를 이룰 수 있을지가 관건인듯 하다.
사실 진저브레드라고 해서 뭐 특별히 갤럭시 S 의 성능이 극대화 되거나 기능이 향상되는 것을 기대하기는
힘들다고 생각하기에 최적화에 초점이 잘 맞춰졌으면 좋겠다.
init process
어제 적었던 booting process 에 따르면 init process 는 kernel 이 부팅하고 나서 최초로 사용자 영역에서
실행 되도록 만들어진 process 이다. 그리고 이 init process 가 실행되고 나면 system 동작에 필요한 다른 process 들을
순차적으로 init process 가 실행을 시키는 것이다.
그리고 init process 는 부팅이 완전히 이루어지고 나서 사용자 이용환경이 완성된 이후에도 계속적으로 백그라운드에서
동작하면서 다른 process 들을 감시한다. 감시 중인 process 가 종료되면 조건에 따라 재실행을 시키는 역할을 한다.
(SIGCHLD 와 관련된 내용인데 이 부분은 아래쪽에 init 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 이라고 부른다고 한다.
아직 안드로이드의 원리에 대해 공부를 하고 있기 때문에 딱 한번 오픈 소스에서 zImage 를 추출해본 경험 한번 뿐이라서
이 부분에 대한 경험이 없다고 볼 수 있다. android process 에 대한 공부가 끝나고 나면 kernel 과 application 에 대한 공부를
할 생각인데 kernel 에 대한 공부를 할 때 경험을 해보면서 더 자세히 확인할 생각이다. 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 가 존재하는 공간이다.
(/proc, /sys 에 대해서는 아직 정확한 역할을 알지 못하고 있다.
단지, /proc 에는 application 이 kernel 공간의 data 에 접근할 수 있는 가상 파일 시스템이 존재한다는 것과
/sys 에는 proc, devfs, devpts file system 을 하나로 통합한 파일 시스템이 존재한다는 것 정도인데...
사실 이부분은 전문 지식이 부족하여 이해가 잘 되지 않는다...)
init.rc
이제 위의 내용들 보다는 사람들이 관심을 많이 갖는 init.rc 에 대한 내용을 적겠다.
왜 사람들이 init.rc 에 관심을 갖는 지는 custom kernel 을 build 하기 위해서는 init.rc 의 내용을 수정해야 하기 때문이다.
zImage 내부에 initramfs.cpio 내부에 init.rc 가 존재하며 이 init.rc 는 init process 가 수행할 일을 지정하는 파일이기
때문이다.
사실 init.rc 의 내용을 정확히 눈으로 확인하기 좋은 방법은 PC 에 vmware 를 설치하고 나서
ubuntu 를 설치하여 linux 환경에서 init.rc 의 file source code 를 확인하는것이다.
sh 스크립트 파일이나 rc 그리고 h 파일들은 윈도우 환경에서는 바로 확인을 할 수 없지만 ubuntu 에서는
내부의 모든 내용을 확인할 수 있다. 아래의 내용은 ubuntu 환경에서 init.rc 를 보게되면 모두 확인할 수 있는
내용들이다. 단지 그 구분이나 여러 부분에 대해 서적을 보고 도움이 될만한 정리를 한 개념일 뿐이다.
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 하기 위해서 만들어 놓은 공간.
이 외에도 여러 directory 가 존재하며 다른 부분들은 추가로 공부를 하다 확인을 하게 되면 업데이트 할 생각이다.
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 이다.
다음에 적을 글은 아마도 init.rc 에서 수행되는 device node file 생성과 관련된 내용과 그 내용 중
uevent 에 관한 부분 그리고 init process 가 생성시키는 자식 process 와 init process 의 관계 그리고 마지막으로
property service 에 대해 적을 것 같다.
추측이다.
맘 내키는데로 써나가기 때문에 전혀 다르게 일전에 적은 적이 있듯이 루팅 어플이나 adb 에 대한 내용이 될수도
그렇지 않으면, Trouble shooting 에 대한 내용이 될지도 모르겠다.
-----------------------------------------------------------------------------------------
관심을 갖게 되시는 분들이 있다면 종종 제 글을 제가 퍼와도 될까요? ^^;;
하지만 수박겉핡기식이라도 알아두면 좋은것은 분명하겠네요^^
스크랩해서 정독해봐야겠습니다^^