삼성 갤럭시 노트 3 네오 포팅하기

!
경고: 이 글이 작성된 지 365일이 넘었습니다. 글의 정보가 오래되어 부정확할 수 있습니다.

지난 몇 주 동안, 삼성 갤럭시 노트 3 네오에 TWRP와 커스텀 롬 포팅을 시도해봤습니다. 일단 현재로선 출시되어 있는 롬과 TWRP 빌드는 모두 패치롬(.zip을 언패킹해서 수동으로 편집한 빌드)이라, 기기에선 매우 불안정하게 작동합니다. 거기에다가 TWRP 빌드는 나온지 엄청 오래되었고 (킷캣 정도 때 포팅된 2.8.7.0 버전) 포팅도 잘 안되어 있어 그래픽과 버튼이 모두 망가져 있습니다.

팁 - 컴파일한 롬은 패치롬과 달리 매번 빌드마다 확인할 수 있는 결과물이 나오기에 안정적이고 훨씬 좋습니다.

이 글에선 포팅을 시도하면서 알아낸 것을 간략하게 적어보겠습니다.

커널 포팅하기 찾기

사실 포팅을 하면서 실수로 시간을 조금 낭비했는데, 커널을 만드려면 삼성에서 제공하는 GPL 덤프를 사용해서 빌드해야 하는 줄 알고 무슨 커널 커밋을 삼성이 사용했는지 확인하는데 시간을 많이 허비했습니다. 삼성이 제공하는 GPL 덤프는 tarball 파일이라, git 커밋 정보가 아예 없어서 스크립트로 무슨 커밋을 사용했는지 일일히 확인해야 되는데, 리눅스 커널이 커밋량이 많이 아렇게 찾는데 시간이 매우 오래 걸립니다.

운 좋게도, 같이 Team Bliss에서 일하고 있는 @Jackeagle이 LineageOS에서 이미 삼성 MSM8974 기기를 위한 커널 소스가 있다고 알려줬습니다. 그냥 이미 누군가 커밋을 다 찾아놓았네요. 그냥 가져와서 씁니다.

팁 - 거의 대부분의 SoC 커널 (예를 들어 samsung_msmxxxx 또는 oneplus_msmxxxx)은 기기와 호환되기에, 커밋을 대립 방식으로 찾기 전에 먼저 SoC 커널이 있는지 확인하세요!

그래서 위에 있는 repo를 fork한 다음, lineage_hltekor_defconfig 파일을 lineage_frescoltekor_defconfig로 복사해서 수정하기 시작했습니다.

defconfig 수정하기

다음으로 frescoltekor defconfig에서 몇 가지 설정을 수정했습니다:

CONFIG_SEC_FRESCO_PROJECT=y
CONFIG_SEC_LOCALE_KOR_FRESCO=y
CONFIG_MACH_FRESCOLTEKTT=y

이렇게 설정을 키면, 예전에 다른 기기(여기에서 사용한 예전 기기는 hltekor)를 위한 설정은 끄는 것을 기억하세요.

# CONFIG_SEC_H_PROJECT is not set
# CONFIG_SEC_LOCALE_KOR_H is not set
# CONFIG_MACH_HLTEKTT is not set

팁 - 삼성 기기에서는 X_PROJECT 설정 플래그도 있는데, 이것도 기기에 따라서 활성화해주거나 비활성화해야 합니다.

그런 다음, 한 번 컴파일을 실행했는데 바로 실패해버렸습니다. 에러가 I2C 쪽에서 나오는 것 같은데, Team Bliss의 @pivcer분이 정확한 NFC I2C 플래그를 활성화하라고 알려주셨습니다. 그래서 hltekor 플래그는 비활성화시키면서 동시에 알맞은 값을 설정해주었습니다:

# CONFIG_BCM2079X_NFC_I2C is not set
CONFIG_SEC_NFC_I2C=y
# CONFIG_SEC_NFC is not set
CONFIG_NFC_PN547=y

팁 - 에러 메시지를 읽으면서, 무슨 변수가 없는지, 무슨 부분이 이중으로 활성화되어 있는지 확인하세요. 그런 다음 grep -r "변수_이름" .를 사용해 소스의 무슨 모듈에 코드가 있는지 확인한 다음, 무슨 플래그를 defconfig에서 활성화/비활성화해야 하는지 확인하세요.

빌드를 또 했는데, 또 실패했습니다.

이상하게도 빌드 시스템이 변수 하나를 못 찾는 것 같습니다:

CC      init/version.o
  LD      init/built-in.o
  LD      .tmp_vmlinux1
/home/users/ericswpark/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 6 of arch/arm/crypto/built-in.o is not in EXIDX output section
/home/users/ericswpark/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 28 of arch/arm/mach-msm/built-in.o is not in EXIDX output section
/home/users/ericswpark/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 55 of mm/built-in.o is not in EXIDX output section
/home/users/ericswpark/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 40 of fs/built-in.o is not in EXIDX output section
/home/users/ericswpark/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 15 of crypto/built-in.o is not in EXIDX output section
/home/users/ericswpark/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 36 of block/built-in.o is not in EXIDX output section
/home/users/ericswpark/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 22 of lib/built-in.o is not in EXIDX output section
/home/users/ericswpark/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 24 of drivers/built-in.o is not in EXIDX output section
/home/users/ericswpark/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 6 of sound/built-in.o is not in EXIDX output section
/home/users/ericswpark/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 6 of arch/arm/oprofile/built-in.o is not in EXIDX output section
/home/users/ericswpark/arm-linux-androideabi-4.8/bin/arm-linux-androideabi-ld: warning: unwinding may not work because EXIDX input section 37 of net/built-in.o is not in EXIDX output section
drivers/built-in.o:leds-max77803.c:function max77803_led_get_en_value.part.0: error: undefined reference to 'led_flash_en'
drivers/built-in.o:leds-max77803.c:function max77803_led_get_en_value.part.0: error: undefined reference to 'led_torch_en'
drivers/built-in.o:leds-max77803.c:function max77803_led_probe: error: undefined reference to 'led_torch_en'
drivers/built-in.o:leds-max77803.c:function max77803_led_probe: error: undefined reference to 'led_flash_en'
drivers/built-in.o:leds-max77803.c:function max77803_led_probe: error: undefined reference to 'camera_class'
drivers/built-in.o:temphumidity_shtc1.c:function max77803_led_en: error: undefined reference to 'led_flash_en'
drivers/built-in.o:temphumidity_shtc1.c:function max77803_led_en: error: undefined reference to 'led_torch_en'
drivers/built-in.o:leds-max77803.c:function max77803_led_remove: error: undefined reference to 'camera_class'
Makefile:889: recipe for target '.tmp_vmlinux1' failed
make: *** [.tmp_vmlinux1] Error 1
ericswpark@buildbox:~/android_kernel_samsung_msm8974$

이 문제를 디버깅하느라 시간을 많이 썼는데, 결국 한 모듈이 제대로 빌드되지 않는 것을 확인했습니다. 이 모듈은 퀄콤 MSM 카메라 모듈인데, 설정 파일에서 제 기기의 플래그를 빼먹는 바람에 컴파일이 제대로 이루어지지 않았습니다. 기기 플래그를 추가했더니 정상적으로 컴파일이 돌아갑니다.

팁 - 어쩔 땐 커널 트리가 고장난 상태로 배포되는 경우가 종종 있습니다. OEM에서 오는 GPL 덤프라서, 또는 롬 팀에서 많이 쓰는 커널 트리라고 반드시 문제가 없는 것은 아니기에, 위의 예시처럼 부러진 부분에 대해서 직접 패치를 해야 되는 경우도 있습니다.

그래서 패치한 후 다시 빌드를 돌려보니 zImage 파일이 정상적으로 생성됐습니다.

TWRP 포팅하기

이제 비슷한 방법으로 TWRP 포팅을 시도했습니다. hltekor 기기 트리를 fork한 후, 그 repo 위에 변경사항을 추가했습니다. 이전 단계에서 컴파일한 커널을 복사한 후, 빌드를 시작했습니다.

만약 똑같이 해 보시면 오류가 발생할 수도 있는데, 그럼 Makefile에서 설정값을 몇 가지 변경하면서 오류를 수정하면 됩니다.

이 부분이 가장 지루한데, 저는 너무 결과물이 안 나와서 몇 주 정도 걸렸습니다. 마침내 빌드가 성공하면 엄청 뿌듯해집니다. (근데, 사실 아까 카메라 패치가 가장 뿌듯한것 같습니다. ^^)

(지금으로선) 끝

빌드 후, 컴파일된 이미지를 플래시해봤는데, 아쉽게도 폰이 새로운 커널은 인식하지 않고 부트루프에 빠져버립니다.

지금 추측할 수 있는 건 아마도 hltekor의 터치스크린 드라이버가 노트 3 네오 하드웨어와 충돌하는 것 같습니다. 왜냐하면 노트 3 네오는 720p 패널을 탑재했는데, 노트 3 (hltekor)은 1080p 패널을 탑재해, 두 폰 사이에 터치스크린 칩이나 패널 구성이 달라서 문제가 생기는 걸 수도 있습니다.

디버깅을 해보기 위해서 기기에서 /proc/last_kmesg를 다운받았는데, 유용한 정보는 표시되지 않았습니다. 커널 자체가 로드가 안 되는 것 같은데, 이게 참 이상한게 드라이버 문제가 발생하였더라도 기본 커널 자체가 부팅이 안 될 이유가 없기에 왜 부팅이 안 되는지 이해가 되질 않습니다. 디버그 케이블로 serial 연결을 할 수 있는지 확인했는데, 지금 납땜 도구가 없어서 일단 기다려야 될 것 같습니다.

그래서 일단 오늘 글은 여기까지만 적겠습니다. 만약 직접 해 보고 싶으시다면 기기와 커널 트리는 모두 제 깃허브에서 확인하실 수 있습니다. 만약 문제를 발견하셨다면 이메일로 연락주세요!

이 글을 쓰는 데 도와주신 MSM8974 커널 개발자분과 LineageOS hltekor 개발자분들께, 그리고 텔레그램 리눅스 커널 채팅방과 Team Bliss의 팀 멤버들께 감사의 말씀을 드립니다.

댓글