Egloos | Log-in
F/OSS study
F/OSS study
[Linux] x86용 커널 이미지 구성 및 부팅 과정의 개요
Linux kernel: 2.6.30


시스템의 /boot 디렉토리를 살펴본 적이 있거나
부트로더 메뉴를 자세히 살펴본 적이 있다면
커널 이미지가 vmlinuz라는 형태로 구성되는 것을 알고 있을 것이다.

원래 커널을 컴파일했을 때 생성되는 ELF 이미지 파일의 이름은 vmlinux이다.
vmlinuz라는 이름은 vmlinux를 압축했다는 것을 의미하며
커널이 로드된 후 압축된 이미지를 해제하는 루틴이 이미지 앞에 추가된다.
(최초에는 zlib을 이용하여 압축하였고, 지금은 추가적으로 bzip2와 lzma 방식도 지원한다.)

또한 real-mode로 부팅해야 하는 BIOS 환경에서
protected-mode로 전환하기 전에 초기화 및 정보 수집을 위한
setup (aka. real-mode kernel) 헤더 및 섹터들이 그 앞에 추가된다.

이를 그림으로 나타내면 다음과 같다.


real-mode kernel header라고 부르는 이 정보는
setup 헤더의 0x1f1 오프셋에서 시작하며
부트 프로토콜 버전에 따라 의미와 크기가 조금씩 달라진다.
(이에 대한 자세한 정보는 커널 소스의 Documentation/x86/boot.txt 문서를 참조하기 바란다.)

이 헤더의 내용은 arch/x86/boot/header.S 파일에 다음과 같이 정의되어 있으며
여기에 빠진 내용들은 커널 이미지 생성 시 boot/tools/build 프로그램에 의해 채워진다.

    # Kernel attributes; used by setup.  This is part 1 of the
    # header, from the old boot sector.

    .section ".header", "a"
    .globl    hdr
hdr:
setup_sects:    .byte 0            /* Filled in by build.c */
root_flags:    .word ROOT_RDONLY
syssize:    .long 0            /* Filled in by build.c */
ram_size:    .word 0            /* Obsolete */
vid_mode:    .word SVGA_MODE
root_dev:    .word 0            /* Filled in by build.c */
boot_flag:    .word 0xAA55

    # offset 512, entry point

    .globl    _start
_start:
        # Explicitly enter this as bytes, or the assembler
        # tries to generate a 3-byte jump here, which causes
        # everything else to push off to the wrong offset.
        .byte    0xeb        # short (2-byte) jump
        .byte    start_of_setup-1f
1:

    # Part 2 of the header, from the old setup.S

        .ascii    "HdrS"        # header signature
        .word    0x0209        # header version number (>= 0x0105)
                    # or else old loadlin-1.5 will fail)

setup 이미지를 빌드할 때 사용하는 setup.ld 스크립트에서
이 헤더 정보가 0x1f1 (=497) 오프셋에 존재하도록 설정한다.

SECTIONS
{
    . = 0;
    .bstext        : { *(.bstext) }
    .bsdata        : { *(.bsdata) }

    . = 497;
    .header        : { *(.header) }
    .inittext    : { *(.inittext) }
    .initdata    : { *(.initdata) }
    .text        : { *(.text) }
    .text32        : { *(.text32) }

부트로더는 커널 이미지의 첫 섹터를 읽어들인 후
setup_sects 필드의 값을 확인하여 얼마나 더 많은 setup 섹터를
읽어들어야 할 지 결정할 수 있다.

(setup 헤더를 제외한 setup 섹터의 첫 위치인)
0x200 오프셋에 있는 jump 명령은 (위의 코드 중 _start 부분에 해당)
setup 이미지가 실행될 때 최초로 실행되는 부분인데
헤더 이후의 실제 명령어가 있는 곳으로 제어를 넘기는 역할을 한다.

부트로더는 setup 이미지로 제어를 넘겨 (0x200으로 점프하여)
부팅에 필요한 정보들을 수집한 후 (32비트 protected-mode) 커널을 부팅하게 하거나
혹은 직접 이러한 정보를 채워넣은 후 setup 과정을 건너뛰고
바로 커널을 부팅하게 할 수 있다. (grub2의 경우)

부팅에 필요한 정보들은 boot_params 구조체에 정의되어 있으며
이는 역사적인 이유로 '제로(zero) 페이지'라고 부른다. (물론 4KB 크기이다.)
(이에 대한 정보는 Documentation/x86/zero-page.txt 문서를 참조하기 바란다.)
부팅 시 수집한 커널 헤더 정보도 제로 페이지의 일부로 포함된다.

by namhyung | 2009/06/25 02:14 | Kernel | 트랙백 | 덧글(0)
트랙백 주소 : http://studyfoss.egloos.com/tb/5018167
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글

◀ 이전 페이지 다음 페이지 ▶

카테고리
General
Application
System
Kernel
Book
Tips
태그
C synchronization binutils computer-architecture SMP block-layer kernel documentation vcs memory perf bash script CAaQA3 awk x86 compiler emacs elf CARM scm patch build blktrace linux gcc algorithm sed git glibc
전체보기
이글루 파인더

최근 등록된 덧글
Terima kasih atas informsi htt..
by ramdani at 01/03
1번은 call-stack 금방 확인이 ..
by 혁 at 11/13
해당 문법에 대한 자세한 가이드 같..
by ㅇㄷㅎ at 11/07
최근 등록된 트랙백
Tod's Ferrari Homme
by Tods Pas Cher,Kodak did ..
Mocassin Femme
by Mocassins Homme, I got so..
natural garcinia cambogia
by
rss

skin by jiinny


X