host에서 만든 파일이 target의 실행 규칙을 따라야 합니다
| 항목 | 뜻 | 확인할 질문 |
|---|---|---|
| ISA·word size | 실행할 명령 집합과 데이터 폭 | AArch64, ARM32, x86-64, RISC-V 중 무엇입니까? |
| ABI | 호출 규약·자료 배치·실행 형식의 약속 | ARM float ABI나 RISC-V ABI 등 target의 라이브러리와 일치합니까? |
| sysroot | target용 header·library 등을 찾는 기준 디렉터리 | host의 /usr/include나 library가 섞이지 않았습니까? |
| ELF interpreter | 동적 ELF를 시작할 loader 경로 | target rootfs에 그 경로의 loader가 있습니까? |
cross compiler의 prefix만 맞추는 것으로 빌드 전체가 target용이 되는 것은 아닙니다. configure 검사·pkg-config·CMake의 탐색 결과·생성 도구의 실행 위치도 구분해야 합니다. host에서 실행해야 하는 code generator를 target용으로 만들어 버리면 빌드 중 실행 단계에서 실패할 수 있습니다. CMake toolchain과 cross compilation
파일이 있는데 ENOENT가 나올 수 있습니다
file ./example-app
readelf -h ./example-app
readelf -l ./example-app
readelf -d ./example-app| 명령 | 읽을 부분 |
|---|---|
| file | ELF 종류·아키텍처·dynamic linking 관련 정보를 먼저 확인합니다. |
| readelf -h | Class, Data, Machine 등 대상 형식을 확인합니다. |
| readelf -l | INTERP segment가 요구하는 loader 경로를 확인합니다. |
| readelf -d | NEEDED, RPATH/RUNPATH 등 동적 연결 정보를 확인합니다. |
execve가 ENOENT를 반환하는 원인은 실행 파일 자체가 없는 경우뿐이 아닙니다. script interpreter나 ELF interpreter 경로가 없을 수도 있습니다. 따라서 파일이 보인다고 “권한 문제밖에 없다”고 단정하지 않습니다. 잘못된 아키텍처, 권한 문제, loader 이후의 library 오류도 구분해야 합니다. execve 오류 조건 동적 loader의 탐색 규칙
실행 파일에서 main까지 거치는 단계
- execve 요청
커널이 파일 형식·실행 가능 여부 등을 검사합니다.
ELF segment와 interpreter를 준비합니다.
- 동적 loader
필요한 shared object를 찾고 relocation 등 초기 작업을 합니다.
프로그램 시작 코드로 연결합니다.
- 프로그램 startup
runtime이 정한 초기화 절차를 수행합니다.
main 등 언어 실행 경로를 시작합니다.
- 애플리케이션
프로그램의 일반 코드가 실행됩니다.
화살표는 시작 절차입니다. main이 ELF의 첫 명령이거나 커널이 모든 shared library의 symbol을 직접 연결한다는 뜻은 아닙니다.
static binary는 동적 interpreter 의존성을 줄일 수 있지만, 지원 ISA·syscall·ABI와 프로그램이 직접 여는 파일의 문제까지 없애지는 않습니다. 임의의 loader symlink를 만들어 다른 ABI의 loader로 우회하는 것도 올바른 해결이 아닙니다.
커널 module은 사용자 ELF와 빌드 조건이 다릅니다
외부 module은 실행 중인 kernel의 올바른 빌드 tree와 설정을 기준으로 만들어야 합니다. 커널 release 문자열만 같은 소스 폴더를 찾는 것으로 충분하지 않을 수 있습니다. symbol versioning을 쓰는 경우 Module.symvers와 실제 빌드 산출물도 중요합니다.
make -C /path/to/target-kernel-build M="$PWD" modules외부 module 빌드의 형태를 보여 주는 명령입니다. 경로는 실제 target kernel의 빌드 디렉터리로 바꿔야 하며 cross build에서는 ARCH·toolchain 설정도 target과 맞춰야 합니다. modules_prepare는 필요한 준비를 하지만 CONFIG_MODVERSIONS에서 쓸 Module.symvers를 완전한 kernel build 대신 만들어 주지는 않습니다. 외부 module 빌드 조건