Toolchain glibc library의 dynamic link 경로 문제
안녕하세요.
툴체인을 직접 구성하여 타겟보드에 올리려 하고 있습니다.
툴체인 구성은 아래와 같습니다.
binutils-2.20.1
glibc-2.11.3
gcc-4.4.3
kernel-2.6.35
busybox-1.15.0
각 소스코드를 컴파일하여 툴체인을 /opt/arm-none-linux-gnueabi 하위 디렉토리에 구성하였습니다.
/opt/arm-none-linux-gnueabi/lib, /opt/arm-none-linux-gnueabi/bin 등등 을 통하여 rootfs를 구성했고
타겟보드에 업데이트 하였습니다.
그리고나서 타겟보드 부팅시 아래와 같은 에러메시지가 발생합니다.
==================================================================================================
/sbin/init: error while loading shared libraries: libc.so.6: cannot open shared object file: No such file or directory
Kernel panic - not syncing: Attempted to kill init!
Backtrace:
[] (dump_backtrace+0x0/0x114) from [] (dump_stack+0x18/0x1c)
r7:c7c16bc0 r6:c7c16bc0 r5:be92aa08 r4:c02d7de0
[] (dump_stack+0x0/0x1c) from [] (panic+0x60/0xe0)
[] (panic+0x0/0xe0) from [] (do_exit+0x74/0x5e8)
r3:c02bba2c r2:00000000 r1:c7c19e2c r0:c0273c90
[] (do_exit+0x0/0x5e8) from [] (do_group_exit+0x94/0xc8)
[] (do_group_exit+0x0/0xc8) from [] (sys_exit_group+0x18/0x24)
r5:be92aa08 r4:40024000
[] (sys_exit_group+0x0/0x24) from [] (ret_fast_syscall+0x0/0x2c)
==================================================================================================
busybox를 실행하는데 libc.so.6을 찾지 못하고 있습니다. rootfs의 lib폴더에 libc.so.6 있는것을 확인했는데도 말이죠. 링크도 모두 이상이 없습니다.
/opt/arm-none-linux-gnueabi/lib$ ll libc.so.6
lrwxrwxrwx 1 root root 14 2월 23 18:13 libc.so.6 -> libc-2.11.3.so*
그런데, readelf로 libc-2.11.3.so 파일을 확인해보면 program interpreter 의 경로가 문제가 있어 보입니다.
==================================================================================================
/opt/arm-none-linux-gnueabi/lib$ arm-none-linux-gnueabi-readelf -l libc-2.11.3.so
Elf file type is DYN (Shared object file)
Entry point 0x1564c
There are 10 program headers, starting at offset 52
Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
EXIDX 0x119e6c 0x00119e6c 0x00119e6c 0x011e0 0x011e0 R 0x4
PHDR 0x000034 0x00000034 0x00000034 0x00140 0x00140 R E 0x4
INTERP 0x11948c 0x0011948c 0x0011948c 0x00030 0x00030 R 0x4
[Requesting program interpreter: /opt/arm-none-linux-gnueabi/lib/ld-linux.so.3]
LOAD 0x000000 0x00000000 0x00000000 0x11e1b4 0x11e1b4 R E 0x8000
LOAD 0x11e6e4 0x001266e4 0x001266e4 0x02268 0x04de8 RW 0x8000
DYNAMIC 0x11ff18 0x00127f18 0x00127f18 0x000e8 0x000e8 RW 0x4
NOTE 0x000174 0x00000174 0x00000174 0x00020 0x00020 R 0x4
TLS 0x11e6e4 0x001266e4 0x001266e4 0x00008 0x00040 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4
GNU_RELRO 0x11e6e4 0x001266e4 0x001266e4 0x0191c 0x0191c R 0x1
Section to Segment mapping:
Segment Sections...
00 .ARM.exidx
01
02 .interp
03 .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_d .gnu.version_r .rel.dyn .rel.plt .plt .text __libc_freeres_fn __libc_thread_freeres_fn .rodata .interp .ARM.extab .ARM.exidx .eh_frame .hash
04 .tdata .fini_array .ctors .dtors __libc_subfreeres __libc_atexit __libc_thread_subfreeres .data.rel.ro .dynamic .got .data .bss
05 .dynamic
06 .note.ABI-tag
07 .tdata .tbss
08
09 .tdata .fini_array .ctors .dtors __libc_subfreeres __libc_atexit __libc_thread_subfreeres .data.rel.ro .dynamic
==================================================================================================
program interpreter 경로가 /lib/ld-linux.so.3으로 되어야 할거 같은데, /opt/arm-none-linux-gnueabi/lib로 되어 있습니다.
제 생각인데, 저거땜시 busybox가 /lib/libc.so.6를 동작시킬때 잘못된 경로때문에 찾지를 못하고 있는것 같은데.... 맞는건가요?
libc.so 파일을 확인해 봐도 경로가 이상합니다.
/opt/arm-none-linux-gnueabi/lib$ more libc.so
/* GNU ld script
Use the shared library, but some functions are only in
the static library, so try that secondarily. */
GROUP ( /opt/arm-none-linux-gnueabi/lib/libc.so.6 /opt/arm-none-linux-gnueabi/lib/libc_nonshared.a AS_NEEDED ( /opt/arm-none-linux-gnueabi/lib/ld-linux.so.3 ) )
이 부분을 해결하지 못해 2주동안 계속 제자리 걸음 입니다. 제발 도와주세요.
/sbin/init: error while
에서 lib.so.6 은 파일 이름이 아니라 SONAME 입니다.
라고 하셨으니,
명령으로 SONAME 이 맞는지 확인해 보십시오. 파일 이름을 libc.so.6 으로 하는 것은 효과가 없습니다. SONAME을 맞추기 위해서는 rebuild 가 필요 합니다. 현 상황에서는 busybox를 변경 하든지 glibc를 변경 하든지 해야 할 듯 싶네요.
하나하나 알아가는 귀중한...
안녕하세요 답변 정말 감사합니다.
정말 감사히도 많은 분들이 포스팅 해놓으신 자료를 보고 하나하나 알아가고 있습니다.
이런 소중한 기회를 삼아서 제대로 이해하고 싶은 심정입니다.
말씀해주신 SONAME에 대해서 알아보니..(https://wiki.kldp.org/HOWTO/html/Program-Library/Program-Library-HOWTO-3.html)
"libc.so.6 → libc-2.11.3.so*" 의 경우, libc.so.6이 SONAME, libc-2.11.3.so 가 REAL-NAME 이라는 걸로 이해했습니다.
또한 libc-2.11.3.so 파일의 dynamic section에 대해 확인해 봤습니다.
위 결과로 봐서 SONAME은 libc.so.6 으로 맞게 설정된것 같습니다.
그 다음,
라고 하셨는데, 이 부분은 잘 이해가 가질 않았습니다. "SONAME을 맞추기 위해서는..." 이란 말씀은 libc-2.11.3.so의 SONAME이 잘못된 것이니, 바로 맞춰야 합니다... 라는 의미로 이해가 됩니다만,
그렇다면 readelf의 SONAME 결과가 잘못된 것인가요?? (잘못된 것이라면) 어떤 SONAME이 올바른 것인지요??
readelf의 SONAME 이 올바른 것이라면 이 다음부터 어떤 부분으로 확인을 거쳐야 하는지 알고 싶습니다.
libc-2.11.3.so 의 SONAME이 libc
libc-2.11.3.so 의 SONAME이 libc.so.6 이 맞다면 rebuild issue는 생각하지 않아도 됩니다. 다를 경우 SONAME을 맞추기 위해 rebuild를 해야 한다는 것이고요.
그렇다면 이 경우는, 기본으로 읽어들이는 library path가 문제라는 얘기 같은데요.
실제로 빌드를 해서 실행을 했을 경우, /opt/arm-none-linux-gnueabi 경로가 / 가 되는 것이 맞는지요? SONAME이 동일하다면 결국에는 library path의 위치가 틀렸다는 걸로 보이네요.
embeded 는 제가 해 본 적이 없어 더 이상 조언이 힘드네요 :(
추정하지 말고 직접 확인해보세요.
추정하지 말고 직접 확인해보세요.
busybox 를 static link 빌드해서 집어넣어 타겟 보드를 부팅시켜 놓고,
dynamic link 로 빌드된 다른 실험용 실행파일을 가지고 뭐가 잘못됐는지 알아보세요.
gcc specs 에서 바꿀 수 있습니다.
예전엔 외부 파일에 기록해서 참조시키는게 default 였는데, 지금은 built-in 이 default 가 되도록 바뀌었나보네요...
default dynamic linker(loader) 가 잘못 기록된다면, 툴체인을 잘 못 만들었다는 뜻입니다. prefix 와 install path 는 다른 개념인데 이 둘을 같은 것으로 착각하시고 뭔가를 하신 것 같네요.
댓글 달기