출처 : http://www.simtec.co.uk/products/SWLINUX/files/booting_article.html
오래된 자료라 3.0 버전과는 차이가 있을 수 있음을 염두해 두고 읽어 주세요.
5. Loading the kernel image
Kernel images generated by the kernel build process are either uncompressed "Image" files or compressed zImage files.
The uncompressed Image files are generally not used, as they do not contain a readily identifiable magic number. The compressed zImage format is almost universally used in preference.
The zImage has several benefits in addition to the magic number. Typically, the decompression of the image is faster than reading from some external media. The integrity of the image can be assured, as any errors will result in a failed decompress. The kernel has knowledge of its internal structure and state, which allows for better results than a generic external compression method.
=> 커널은 압축이 안된 Image 또는 압축이 된 zImage로 빌드 됩니다.
아래 제 빌드 트리 확인 결과 두배 이상 차이가 납니다.
The zImage has a magic number and some useful information near its beginning.
Table 2. Useful fields in zImage head code
Offset into zImage | Value | Description |
---|---|---|
0x24 | 0x016F2818 | Magic number used to identify this is an ARM Linux zImage |
0x28 | start address | The address the zImage starts at |
0x2C | end address | The address the zImage ends at |
The start and end offsets can be used to determine the length of the compressed image (size = end - start). This is used by several bootloaders to determine if any data is appended to the kernel image. This data is typically used for an initial RAM disk (initrd). The start address is usually 0 as the zImage code is position independent.
The zImage code is Position Independent Code (PIC) so may be loaded anywhere within the available address space. The maximum kernel size after decompression is 4Megabytes. This is a hard limit and would include the initrd if a bootpImage target was used.
=> 매직넘버, start 주소, end 주소의 용도에 대한 설명입니다.
0x24 주소를 보면 매직 넘버가(0x016F2818) 보입니다. 그런데 0x28, 0x2C가 ...으로 되어있네요.
(objdump 확인 결과)
(readelf 확인 결과)
0x28, 0x2C가 보입니다. 값이 둘다 0이군요.
=> zImage 는 position independent code라고 합니다. 공유 라이브러리 만들때 -fPIC 옵션 준다고 알고 있었는데
PIC의 뜻이 이거였군요. zImage는 어느 주소에도 로드가 될 수 있다고 하네요. (잘 이해가 안가네요.)
Note
Although the zImage may be located anywhere, care should be taken. Starting a compressed kernel requires additional memory for the image to be uncompressed into. This space has certain constraints.
The zImage decompression code will ensure it is not going to overwrite the compressed data. If the kernel detects such a conflict it will uncompress the image immediately after the compressed zImage data and relocate the kernel after decompression. This obviously has the impact that the memory region the zImage is loaded into must have up to 4Megabytes of space after it (the maximum uncompressed kernel size), i.e. placing the zImage in the same 4Megabyte bank as its ZRELADDR would probably not work as expected.
Despite the ability to place zImage anywhere within memory, convention has it that it is loaded at the base of physical RAM plus an offset of 0x8000 (32K). This leaves space for the parameter block usually placed at offset 0x100, zero page exception vectors and page tables. This convention is very common.
=> 관습적으로 커널은 베이스 주소 + 0x8000에 로드를 한다고 합니다.
초록색 글 부분 해석좀 해주세요. 정확히 해석을 못하겠네요. ㅋ
.section ".start", #alloc, #execinstr
위 코드에 의해 [5].start 섹션이 만들어 졌습니다. A(alloc), X(execinstr) 속성이 보이네요.
.type start,#function
위 코드에 의해 start 심볼의 타입이 FUNC가 되었습니다.
objdump, readelf 파일 첨부 하였습니다.
공부하다보니 ELF 포맷에 완전 무지 하다는 사실을 깨달았습니다.
공부해야지. ㅋ
댓글 5
-
천희진
2011.08.09 00:30
-
홍문화
2011.08.09 10:01
아하~ 천희진님 답글보고 다시 읽어보니 바로 해석이 되네요. ㅋ
커널 사이즈에 대한 문제는 이전에도 거론 된 적이 있었는데 아직 저도 정확히 이해를 못하고 있습니다.
일단 커널을 어디까지 볼것인가가 관건인거 같은데 드라이버를 모두 모듈로 뺀다면 커널 이미지 크기는
상당히 작아지지 않을까 생각합니다. 드라이버 제거하고 다시 컴파일 해봐야겠네요. ^^;
-
천희진
2011.08.09 01:04
자문자답입니다 ㅋ relocate가 별거는 아니고 memcpy 같은거네요. overwrite 안하면서 압축을 풀고 난 다음에 원래 있어야 될 주소로 커널 이미지를 다시 옮기는 것 같습니다.
-
홍문화
2011.08.09 10:05
참고 : http://wiki.kldp.org/KoreanDoc/html/EmbeddedKernel-KLDP/arm.src.analysis.html
네. 압축을 풀고 위치를 다시 재배치 하는것 같습니다.
분석하다 보면 나오겠죠.
-
홍문화
2011.08.09 17:35
PIC를 이해 하려다 PLT와 GOT를 만나 버렸습니다.
ELF에 한 발 담근 느낌? ㅋ
.
녹색부분은 영어만 놓고 보면 "압축을 풀때 압축해제한 결과가 압축된 데이터를 덮어쓰게 될 상황을 감지하면, 압축된 zImage 데이터 바로 다음에다 압축을 푼 후에 커널을 relocate 한다" 정도일 것 같은데, kernel relocate는 정확히 어떤 의미인가요?
그리고 커널 사이즈는 4MB가 hard limit라면서 Image 파일은 어떻게 6.5메가가 될 수 있는건지.. 제가 뭘 잘못 이해하고 있는거죠? ^^;