vmlinux 헤더에 커널 이미지의 길이가 포함되어 있습니까?

vmlinux 헤더에 커널 이미지의 길이가 포함되어 있습니까?

여러 부분으로 구성된 복합 파일을 디스어셈블하려고 합니다. 그 중 하나는 여러 다른 파일 사이에 끼어 있는 압축되지 않은 커널입니다. 어려운 것으로 판명된 커널 부분의 정확한 길이를 찾으려고 노력하고 있습니다.

vmlinux 헤더에 부트로더가 실행 전에 읽어야 하는 데이터 양에 대한 표시가 있습니까? 아니면 vmlinux 파일의 모든 내용이 부트로더에서 핸드오프될 때 로드되어야 한다고 가정합니까?

답변1

빠른 대답은 "아니오"입니다. 그러나 이것이 ELF 이미지라면 약간의 해킹을 통해 커널을 찾을 수 있을 것입니다. 아래 해킹 을 참조하세요 readelf.

부트로더는 커널과 루트 파일 시스템이 있는 모든 파일의 형식을 알아야 합니다. 여기에는 형식에 관계없이 커널 파일의 크기를 아는 것이 포함됩니다. PowePC 및 Blackfin에서 부트로더는 전체 커널이 압축된 경우 압축을 풀고 이를 RAM의 최종 위치에 쓰는 역할을 합니다. ARM에서는 커널이 자체 압축 해제될 수 있으며 부트로더는 원시 커널 파일을 RAM의 편리한 위치에 복사하고 실행을 시작하기만 하면 됩니다.

커널이 자체 압축 해제되는 경우 압축된 커널 파일의 크기를 나타내는 기호는 사용된 압축 해제 알고리즘에 따라 파일 시작 부분의 압축 해제 코드 어딘가에 있을 수도 있고 없을 수도 있지만 이를 알 수 있는 방법은 없습니다. 특정 커널 빌드에 대한 링커 맵이 없는 위치를 알 수 있습니다. 물론 부트로더는 알 방법이 없습니다.

압축되지 않은 커널 코드 자체는 두 개의 기호로 묶이고 주소 _stext_end커널 자체의 시작과 끝이지만 initramfs가 커널 바이너리에 연결된 경우 포함된 initramfs의 범위는 포함하지 않습니다. initramfs의 범위는 링커에 의해 두 개의 커널 기호 __initramfs_start__initramfs_end. 부트로더에는 일반적으로 커널 기호 테이블(파일에 있음)을 읽는 기능이 없으며 , 이 기능이 없으면 커널 파일에서 및 기호가 System.map어디에 있는지 알 수 없습니다 . 즉, 기호의 위치는 바이너리 파일의 시작 부분에서 고정된 오프셋이 아닙니다. 이는 링크 타임에 결정되며 커널 빌드 구성에 따라 달라질 수 있습니다._end__initrams_end

ELF 형식의 압축되지 않은 커널의 경우 ELF 헤더( 복합 파일의 덤프 177 E L F에 있음 ) 를 찾아 vmlinux 파일의 시작을 식별할 수 있습니다 . 그런 다음 이 지점에서 또는 파일의 나머지 부분에 대해 가장 높은 파일 오프셋( )이 있는 섹션을 찾을 od -c수 있습니다 . 이 오프셋에 섹션 크기를 추가하면 vmlinux가 끝납니다. 스트립되지 않은 PPC vmlinux를 사용하여 이 방법을 테스트한 결과 독립형 vnlinux 파일 크기와 정확히 일치하는 크기를 얻었습니다. 커널을 제거한 후 이 방법을 사용하면 제거된 이미지 크기보다 1283바이트가 부족한 결과가 나왔습니다.readelf -eobjdump -h.shstrtab

mkimage임베디드 시스템은 일반적으로 커널, rootfs, 장치 트리 및 기타 구성 요소를 압축하는 것과 같은 파일 형식을 사용합니다 . 예를 들어 U-boot는 mkimage를 인식하므로 mkimage 파일 내에서 커널 바이너리가 시작하고 끝나는 위치를 알고 커널이 압축되었는지 여부와 커널 파일을 쓸 RAM 주소를 알고 있습니다.

관련 정보