2 분 소요

이 포스팅은 전 포스팅(Ubuntu에서 Android Kernel 빌드하기(1/2))에 이어 진행됩니다~.

8. Merge Build
전 포스팅에서 빌드한 커널 파일을, 실제 폰 위에서 동작하는 cyanogen ramdisk와 합쳐야 한다. 아이고 갈길이 멀고만 ㅜ

1) 파일시스템 확인하기 
$adb shell
을 쳐서 adb 안으로 들어온 후,
#cat /proc/mtd 라고 쳐보자.

dev:    size   erasesize  name
mtd0: 000e0000 00020000 "misc"
mtd1: 00400000 00020000 "recovery"
mtd2: 00380000 00020000 "boot"
mtd3: 09100000 00020000 "system"
mtd4: 05f00000 00020000 "cache"
mtd5: 0c440000 00020000 "userdata"

이건 내폰의 결과. 스마트폰마다 다 다르니까 확인하기.


2) 일단 뭔 짓을 하기전에, recovery와 boot는 백업을 해..주자.
#cat /dev/mtd/mtd1 > /sdcard/mtd1.img
#cat /dev/mtd/mtd2> /sdcard/mtd2.img


3) boot.img 추출하기 (또는 recovery.img 추출)
아 진짜 이번부터는 구글링과 온갖 삽질ㅜㅜ의 결과다.. 망할
$ adb pull /dev/mtd/mtd2 boot.img 로 부트이미지를 뽑아온다.
위에서 나의 "boot"는 mtd2였으니까 위와 같은 명령을 사용.
그럼 boot.img가 생김.


4) boot.img 분리하기
첨부한 unpack-booimg.pl 스크립트를 사용하여 커널과 램디스크를 분리시킨다.
아..
뭔말이냐면....(나도 잘모름ㅋㅋ) 아... 자.. 설명 들어감.

boot.img는 다음과 같이 구성되어있다. (recovery.img도 마찬가지)

+-----------------+ 
| boot header    | 1 page
+-----------------+
| kernel              | n pages  
+-----------------+
| ramdisk           | m pages  
+-----------------+
| second stage   | o pages
+-----------------+

n = (kernel_size + page_size - 1) / page_size
m = (ramdisk_size + page_size - 1) / page_size
o = (second_size + page_size - 1) / page_size

0. all entities are page_size aligned in flash
1. kernel and ramdisk are required (size != 0)
2. second is optional (second_size == 0 -> no second)

(퍼옴 출처는 포스팅 아래에)

저 상태에서 램디스크를 수정하고자 할 경우 또는 커널을 교체하고자 할 경우에 
boot.img 를 분리시켜서 수정후 다시 하나의 img로 만들고 다시 폰에 넣어줘야 한다.

즉 원래 있던 폰에서 boot.img 추출 -> 분리후 수정 -> 다시 합침 -> 폰에 넣음
의 과정으로 진행된다.
...라고 일단 이해했다 아놔 ㅡㅡ

저 ramdisk를 빼내는 방법은.. 즉 분리시키는 방법은
1번. boot.img를 hex editor로 연다
00 이 여러번 연속되다가 1F 8B 08 이 튀어나오면 1F부터 램디스크 부분이다
(이 무슨 매직넘버냐 하지만 진짜 매직넘버 맞다..-_-)
그럼 이부분만 샤샤샥 빼서 다른이름으로 저장하면 이게 바로 램디스크(....)
저 위의 그림에서 secong stage는 없는 시나리오로 가정한다.

2번. 첨부한 unpack-bootimg.pl 을 사용한다. (첨부파일클릭)
boot.img 와 같은 폴더에 다운받고.
그냥 펄스크립트 한번 돌려주면 알아서 커널, 램디스크 분리해준다.
사용법은
$perl unpack-bootimg.pl boot.img
물론 perl이 깔려있어야 겠지..

여튼 그래서 분리가 정상적으로 되었다면! (2번의 방법을 쓴걸로 가정함)
boot.img-ramdisk라는 폴더가 생겨서 안에  /data /dev /proc /system 등의
램디스크 파일들을 볼 수 있게 해준다. 물론 수정하려면 여기서 해줌!
그리고 boot.img-kernel.gz, boot.img-ramdisk.cpio.gz 이렇게 압축파일 두개가 생기는데
하나는 커널, 하나는 램디스크이다.
위의 폴더는 저 두번째 램디스크 압축파일 풀어준거일뿐..(스크립트가 풀어준것)

여튼, 램디스크 수정할사람은 하시고 난 아니니까 패스.


5) 다시 새 boot.img 만들기!
간단하게, 위에 같이 첨부한 repack-bootimg.pl 을 사용하면 된다.
그리고 이 스크립트를 돌리려면 프로그램 두개가 필요한데
mkbootimg 가 필요하다. 클릭해서 다운받자.
사용법은
$perl repack-bootimg.pl <새로넣을커널이름> <ramdisk폴더이름> <출력파일이름>
이다. 나의 경우에는
$perl repack-bootimg.pl zImage boot.img-ramdisk mynewboot.img
로 하였다. 

***** 참고로, 다운받은 mkbootimg에는 실행옵션이 없으니
$chmod +x mkbootimg
를 하여 실행 권한을 주고,
repack-bootimg.pl 을 열어 system("mkbootimg ~~ 이 부분을
system("./mkbootimg~~  로 바꿔주자
물론, 펄스크립트와 다운받은 파일, boot.img는 모두 한 폴더 안에 있어야함..
그리고 넥서스원 의 경우에는 mkbootimg의 실행 옵션에
--base 0x20000000 를 추가해주어야 한다!!!

아..
이제 이렇게 생성된 mynewboot.img 를 폰에 다시 넣기만 하면 완료!


9. 폰에...넣자.. ㄷㄷ
이제 이렇게 힘겹게 손에 넣은 mynewboot.img 를 폰에 다시 넣을 시간.
위에서 boot.img와 recovery.img 가 있다고 했는데, 사실
boot.img를 아무리 바꿔도 recovery.img가 다시 recovery 해버려서 날아간다고 한다.
기기에 넣을때는, 내가 만약 recovery.img로 작업을 했으면 그냥 recovery.img를 바꿔준 뒤 재부팅화면 되고,
boot.img로 작업했으면(이번 포스팅 케이스)
adb를 이용해서 폰에 올려야 한다.

$adb push mynewboot.img  /sdcard/
$adb shell  (이러면 adb 쉘로 진입하면서 쉘 모양이 $에서 #으로 변경됨)
#cat /dev/zero > /dev/mtd/mtd2
만약
write:No space left on device 라고 나온다 해도 이건 괜찮으니 무시 가능
#flash_image boot /sdcard/mynewboot.img
라고 하면 
mtd: successfully wrote block at xxxxxx
몇줄 주르륵 뜨면서 성공할 것이다.


10. 그럼 이제 재부팅...!! 하면 끝 ㅠㅠ!!
드디어 나의 커스텀 커널이 내 폰에 설치되었다 으하하하하하하하
이렇게 커스텀 커널을 설치하고 나면 와이파이 문제가 생긴다고 한다~ㅋㅋㅋ
해결법은 다음 포스팅에서 ㅜ ㅜ..



참고사이트

http://android-dls.com/wiki/index.php?title=HOWTO:_Unpack%2C_Edit%2C_and_Re-Pack_Boot_Images
http://blog.naver.com/PostView.nhn?blogId=odelay941&logNo=50126135790
http://wiki.cyanogenmod.org/wiki/Building_Kernel_from_source




카테고리:

업데이트:

댓글남기기