리눅스 부팅 과정 상세 분석

14.1 전원 공급 및 BIOS 단계

전원 버튼을 누르면 컴퓨터에 전원이 공급되고, CPU 회로가 활성화되어 CPU가 동작을 시작합니다. CPU가 실행되면서 BIOS 코드로 점프합니다.

BIOS는 전원이 켜진 후 가장 먼저 실행되는 프로그램입니다. BIOS는 CMOS에 저장된 정보를 읽어 하드웨어 자체 점검(POST), 하드웨어 시간, 디스크 크기 및 모델 등의 일부 하드웨어 정보를 파악합니다. BIOS 설정 화면에서 볼 수 있는 정보들은 모두 이 단계에서 수집됩니다. 부팅 과정에서 가장 중요한 것은 부팅 가능한 장치와 해당 장치들의 부팅 순서(위에서 아래로) 정보를 가져오는 것입니다.

하드웨어 검사 및 정보 수집이 완료되면 하드웨어 초기화를 시작하고, 첫 번째 부팅 순서에 있는 장치의 MBR을 읽습니다. 첫 번째 장치에서 유효한 MBR을 찾지 못하면 두 번째 장치로 넘어가 올바른 MBR을 찾을 때까지 계속합니다.

14.2 MBR 및 다양한 부트로더 단계

이 절에서는 여러 BR(부트 레코드)과 다양한 부트로더에 대해 간략히 설명합니다.

MBR(마스터 부트 레코드)은 디스크의 첫 번째 섹터에 위치하며, 파티션이나 운영체제와 무관하게 BIOS가 항상 읽는 레코드입니다.

MBR에는 부트로더, 파티션 테이블, BRID가 저장됩니다. 부트로더는 446바이트를 차지하며 부팅을 로드하는 역할을 합니다. 파티션 테이블은 64바이트로, 각 주 파티션 또는 확장 파티션은 16바이트를 사용합니다. 16바이트 중 첫 번째 바이트가 0x80이면 해당 파티션이 활성 파티션(Active Partition)임을 의미하며, 활성 파티션은 하나만 존재할 수 있습니다. 마지막 2바이트는 BRID(부트 레코드 식별자)로, 고정값 0x55AA이며, BIOS가 이 값을 확인하여 유효한 MBR인지 판단합니다. 값이 다르면 다음 부팅 장치를 읽습니다.

14.2.1 부트로더

MBR의 부트로더는 446바이트로 제한되므로, 코드 저장 공간이 작아 로드할 수 있는 부트로더에 한계가 있습니다. 따라서 디스크의 여러 위치에 다양한 부트로더가 설계되었습니다.

파일 시스템을 생성할 때 일부 파티션의 첫 번째 블록에 부트 섹터가 생성됩니다. 이 부트 섹터에도 부트로더가 위치하지만, 크기가 매우 제한적입니다. 주 파티션의 부트 섹터는 VBR(볼륨 부트 레코드), 논리 파티션의 부트 섹터는 EBR(확장 부트 섹터)라고 합니다. 하지만 이러한 방식은 불편하여 부트 관리자(LILO, GRUB) 등장 이후 거의 사용되지 않게 되었지만, 파티션에는 여전히 부트 섹터가 존재합니다.

14.2.2 파티션 테이블

하드 디스크 파티션의 장점 중 하나는 여러 운영체제를 다른 파티션에 설치할 수 있다는 점이며, 부트로더는 각 운영체제가 어떤 파티션에 있는지 알아야 합니다.

파티션 테이블의 크기는 64바이트이며, 4개의 항목으로 구성됩니다. 각 항목은 16바이트입니다. 따라서 하나의 디스크에는 최대 4개의 주 파티션만 생성할 수 있습니다.

각 주 파티션 테이블 항목의 16바이트는 6개 부분으로 구성됩니다.

(1) 첫 번째 바이트: 0 또는 0x80. 0x80은 활성 파티션, 0은 비활성 파티션을 의미합니다. 하나의 디스크에는 하나의 주 파티션만 활성 상태가 될 수 있습니다.
(2) 두 번째~네 번째 바이트: 주 파티션의 첫 번째 섹터 물리적 위치 (실린더, 헤드, 섹터 번호 등).
(3) 다섯 번째 바이트: 주 파티션 유형.
(4) 여섯 번째~여덟 번째 바이트: 주 파티션의 마지막 섹터 물리적 위치.
(5) 아홉 번째~열두 번째 바이트: 주 파티션의 첫 번째 섹터 논리적 주소.
(6) 열세 번째~열여섯 번째 바이트: 주 파티션의 총 섹터 수.

마지막 4바이트인 '주 파티션 총 섹터 수'는 해당 주 파티션의 크기를 결정합니다. 총 섹터 수는 최대 2의 32승을 넘을 수 없으며, 각 섹터가 512바이트일 경우 단일 파티션은 최대 2TB를 초과할 수 없습니다.

14.2.3 VBR/EBR 방식을 통한 운영체제 부팅

GRUB 없이 VBR과 EBR 방식으로 운영체제를 부팅하는 과정을 살펴보겠습니다. BIOS가 MBR의 부트로더를 읽은 후 파티션 테이블을 계속 읽습니다. 다음 두 가지 경우가 있습니다.

(1) 파티션 테이블에서 어떤 주 파티션의 첫 번째 바이트가 0x80인 활성 파티션을 찾으면, 해당 주 파티션에 운영체제가 설치된 것입니다. 그런 다음 메모리에 로드된 MBR 부트로더 코드를 실행하여 해당 활성 주 파티션의 VBR 부트로더를 로드합니다. 이 시점부터 제어권은 VBR의 부트로더로 넘어갑니다.

(2) 운영체제가 주 파티션이 아닌 논리 파티션에 설치된 경우, 주 파티션 테이블을 찾은 후 확장 파티션 테이블을 계속 검색하여 EBR이 있는 파티션을 찾습니다. MBR의 부트로더는 제어권을 해당 EBR의 부트로더로 넘깁니다.

즉, 하나의 디스크에 여러 운영체제가 설치된 경우 부트로더는 VBR, EBR 등 여러 위치에 분산될 수 있지만, MBR은 BIOS에 의해 항상 존재해야 합니다. Linux 설치 시 MBR 설치 위치를 묻는 단계가 있는데, 이 MBR은 실제 MBR, VBR, EBR 중 하나가 될 수 있습니다. 단일 디스크에 여러 운영체제를 공존시키려면 MBR이 덮어쓰여지면 안 됩니다.

다음은 단일 디스크에 3개의 운영체제를 설치한 파티션 구조 예시입니다. /dev/sda{1,2,3}은 첫 번째 CentOS 6, /dev/sda{5,6,7}은 두 번째 CentOS 7, /dev/sda{8,9,10}은 세 번째 CentOS 6 시스템이며, 각 운영체제의 파티션 순서는 /boot 파티션, 루트 파티션, 스왑 파티션입니다.

첫 번째 운영체제 설치 시 부트로더를 /dev/sda 또는 /dev/sda1에 설치할 수 있습니다. 이는 MBR과 VBR을 설치하는 것이며, 하나를 선택해도 다른 하나도 함께 설치됩니다. 두 번째 운영체제부터는 MBR이 아닌 EBR을 설치해야 하며, 부트로더 위치를 수동으로 지정해야 합니다. 기본 옵션으로 설치하면 기존 MBR이 덮어쓰여집니다.

이러한 방식의 메뉴 관리에는 stage1, stage1.5, stage2 개념이 필요 없습니다. VBR 또는 EBR로 점프하면 해당 파티션의 운영체제 부팅을 직접 로드할 수 있습니다. 하지만 현재는 GRUB이 주로 사용되므로, 부트로더 설치 위치를 수동으로 지정하지 않고 MBR이 덮어쓰여져도 GRUB 설정 파일만 수정하면 다중 운영체제 공존이 가능합니다.

14.3 GRUB 단계

GRUB을 사용하여 부팅을 관리하면, MBR의 부트로더가 GRUB 프로그램에 의해 설치되며, 다른 부트로더도 함께 설치됩니다. CentOS 6은 기존 GRUB을, CentOS 7은 GRUB2를 사용합니다.

기존 GRUB을 사용하면 stage1, stage1_5, stage2 부트로더가 설치됩니다. GRUB2를 사용하면 boot.img와 core.img가 설치됩니다. 두 방식은 차이가 있으므로 따로 설명합니다.

14.3.1 GRUB2 부팅 과정

GRUB2 프로그램이 GRUB을 설치하면 /boot/grub2/i386-pc/ 디렉토리에 boot.img와 core.img 파일이 생성됩니다. 또한 파일 시스템 모듈을 비롯한 여러 모듈 파일도 생성됩니다.

# find /boot/grub2/i386-pc/ -name '*.img' -o -name "*fs.mod" -o -name "*ext[0-9].mod"
...
/boot/grub2/i386-pc/ext2.mod
...
/boot/grub2/i386-pc/core.img
/boot/grub2/i386-pc/boot.img

boot.img는 MBR에 설치되는 부트로더입니다. GRUB2-install은 boot.img를 MBR 부트로더 영역에 맞는 코드로 변환하여 기록합니다. core.img는 두 번째 부트로더 단계로, MBR 바로 다음 영역인 MBR 갭(최소 31KB, 일반적으로 1MB)에 설치됩니다.

core.img는 여러 img 파일의 결합체입니다. boot.img 부트로더의 유일한 역할은 core.img의 첫 번째 섹터(diskboot.img)로 점프하는 것입니다. 디스크 부팅의 경우, diskboot.img는 core.img의 나머지 내용을 로드하고, 압축된 kernel.img(운영체제 커널이 아닌 GRUB 커널)를 로드하여 GRUB 런타임 환경을 초기화합니다. GRUB 설치 시 파일 시스템 모듈(예: ext2.mod)이 core.img에 포함되어 있으므로, kernel.img는 /boot 파티션의 파일 시스템을 인식하고 GRUB 설정 파일(/boot/grub2/grub.cfg)을 찾아 부트 메뉴를 표시합니다.

메뉴 항목을 선택하면 kernel.img는 설정 파일에 따라 해당 운영체제 커널(/boot/vmlinuz-*)과 initramfs를 로드합니다.

menuentry 'CentOS 6' --unrestricted {
    search --no-floppy --fs-uuid --set=root f5d8939c-4a04-4f47-a1bc-1b8cbabc4d32
    linux16 /vmlinuz-2.6.32-504.el6.x86_64 root=UUID=edb1bf15-9590-4195-aa11-6dac45c7f6f3 ro quiet
    initrd16 /initramfs-2.6.32-504.el6.x86_64.img
}

운영체제 커널 로드 후 GRUB2는 제어권을 커널로 넘깁니다.

14.3.2 기존 GRUB 부팅 과정

기존 GRUB의 부트로더는 stage1과 stage2입니다. stage1에서 stage2로 점프할 때 대부분 stage1_5가 사용됩니다. stage1은 MBR에 위치하며, stage1_5의 첫 번째 섹터로 점프한 후, 해당 섹터의 코드가 나머지 내용을 로드하여 stage2로 점프합니다.

stage1_5는 파일 시스템을 인식하기 위한 중간 역할을 합니다. stage2는 크기가 커서 디스크에 포함되지 않고 /boot 파티션에 저장되며, stage1은 파일 시스템을 인식하지 못하므로 stage1_5가 필요합니다. 다양한 파일 시스템 유형에 따라 여러 stage1_5가 존재합니다.

# ls -C /boot/grub/*stage1_5*
/boot/grub/e2fs_stage1_5     /boot/grub/jfs_stage1_5
/boot/grub/fat_stage1_5      /boot/grub/minix_stage1_5
...

각 부트 파티션은 하나의 stage1_5만 사용하며, 이는 MBR 갭에 포함됩니다. stage1_5가 /boot 파티션을 인식하면 stage2의 첫 번째 섹터를 찾아 점프합니다. stage2는 /boot/grub/grub.conf를 로드하여 메뉴를 표시하고, 선택된 운영체제의 커널을 로드한 후 제어권을 넘깁니다.

GRUB 설치 시 setup (hd0) 명령은 stage 파일들을 확인하고, stage1_5를 디스크에 포함시킨 후 stage1을 설치합니다.

14.4 커널 로드 및 초기화 단계

이제 커널이 메모리에 로드되어 제어권을 가지며, 부트로더로부터 커널 부트 파라미터와 initramfs 경로를 전달받았습니다. 모든 커널은 bzImage 방식으로 압축되어 있으며, 커널이 정상 작동하려면 압축 해제가 필요합니다.

압축 해제 후 PID가 0인 idle 프로세스가 생성됩니다. 이 프로세스는 이후 모든 프로세스의 부모가 되며, CPU 절전 도구에서 사용됩니다. 그다음 PID 1(init)과 PID 2(kthread)의 커널 스레드가 생성됩니다. PID 2는 init 프로그램 호출 전 커널 환경 초기화 및 설정 작업을 수행하며, 전달된 커널 파라미터를 기반으로 initramfs를 로드합니다.

14.4.2 initramfs

initramfs는 initrd보다 발전된 방식입니다. initrd는 파일 시스템이므로 커널이 해당 파일 시스템 드라이버를 필요로 하지만, initramfs는 단순한 압축 이미지 파일이므로 별도의 드라이버가 필요 없습니다. 로드 시 커널은 압축 해제된 내용을 tmpfs에 넣습니다.

initramfs의 핵심 차이는 init 프로세스 처리 방식입니다. initramfs는 init 프로그램을 이미지 파일에 포함시켜, tmpfs에 로드될 때 바로 init을 실행하여 루트 파일 시스템을 찾는 작업을 init이 수행하도록 합니다. 즉, 커널 스레드가 아닌 init이 루트 파일 시스템을 마운트합니다. /sbin/init은 initramfs에 init이 없을 경우 대비한 백업 역할을 하며, 정상 운영 환경에서도 신호 전송 등의 작업에 사용됩니다.

initramfs는 많은 작업을 포함하며, 압축 해제 시 실제 운영 환경과 유사한 디렉토리 구조를 확인할 수 있습니다.

14.5 운영체제 초기화

init 프로세스가 제어권을 가지면 사용자 공간으로 진입했음을 의미하며, 이후 작업은 사용자 공간 중심으로 진행됩니다. init은 운영체제 환경을 초기화합니다. 이 과정은 런레벨 읽기, 시스템 환경 초기화, 런레벨별 환경 초기화, rc.local 실행, 터미널 로드 등을 포함합니다.

14.5.1 런레벨

sysV 스타일 시스템에서는 런레벨 개념을 사용합니다. 각 런레벨은 다른 시스템 환경을 초기화합니다. Linux는 0~6의 7개 런레벨을 정의합니다.

0: halt (종료)
1: 단일 사용자 모드
2: NFS 없는 다중 사용자 모드
3: 완전 다중 사용자 모드
4: 예약
5: X11 (그래픽 모드)
6: reboot (재부팅)

종료 또는 재부팅 명령의 본질은 init 프로세스에 0 또는 6 런레벨을 전달하는 것입니다. sysV의 init은 /etc/inittab 파일을 읽어 기본 런레벨을 가져옵니다. systemd 관리 시스템에서는 이 파일이 없거나 경고용으로만 존재합니다.

14.5.2 시스템 환경 초기화

/etc/init/rcS.conf 파일은 시스템 환경 초기화를 정의합니다. 이 파일은 /etc/rc.d/rc.sysinit을 실행하며, 다음을 포함합니다.

(1) 호스트 이름 확인
(2) /proc, /sys 등 특수 파일 시스템 마운트
(3) udev 시작 (장치 관리자)
(4) 하드웨어 파라미터 초기화 (드라이버 로드, 시계 설정 등)
(5) 호스트 이름 설정
(6) fsck 실행 (디스크 건강 검사)
(7) /etc/fstab의 파일 시스템 마운트 (/proc, NFS 제외)
(8) 스왑 활성화
(9) 작업 로그를 /var/log/dmesg에 기록

14.5.3 런레벨 환경 초기화

시스템 초기화 후 /etc/init/rc.conf가 런레벨 초기화를 수행합니다. 이 파일은 /etc/rc.d/rc $RUNLEVEL을 호출합니다. 각 런레벨(0~6)에 대한 스크립트는 rc[0-6].d 디렉토리에 위치합니다.

# ls -l /etc/rc.d/
...
drwxr-xr-x. 2 root root  4096 Jun 11 02:42 rc0.d
drwxr-xr-x. 2 root root  4096 Jun 11 02:42 rc1.d
...

/etc/init.d/의 스크립트가 실제 스크립트이며, rcN.d 디렉토리의 파일들은 이에 대한 심볼릭 링크입니다. S로 시작하는 파일은 해당 런레벨 시작 시 실행, K로 시작하는 파일은 종료 시 중지됩니다. 예를 들어 S99local/etc/rc.d/rc.local을 가리키며, 이는 사용자 정의 명령을 실행할 수 있는 파일입니다.

14.6 터미널 초기화 및 로그인

Linux는 다중 작업, 다중 사용자 운영체제로, 여러 사용자가 동시에 접속할 수 있습니다. 로그인 전에 터미널이 초기화되어야 합니다.

14.6.1 터미널 초기화

Linux는 부팅 시 모든 지원되는 가상 터미널을 자동으로 시작합니다. 이 터미널들은 getty 명령(예: mingetty, agetty)에 의해 생성되며, getty는 로그인 프로그램(/bin/login)을 호출합니다. getty 프로세스는 init에 의해 감시되며(respawn), 종료 시 즉시 재시작됩니다. 로그인 성공 시 getty는 bash와 통합되어 표시되지 않지만, 완전히 사라지는 것은 아닙니다. /etc/init/tty.conf가 터미널 로드를 처리하며, /etc/sysconfig/init에서 활성 터미널 목록(예: tty[1-6])과 단일 사용자 모드 셸을 설정합니다.

14.6.2 로그인 과정

SSH를 통한 로그인은 getty 프로세스 생성 단계에서 부팅 과정이 사실상 종료됩니다. 로그인 시 getty는 login 프로세스를 호출하여 사용자 이름과 비밀번호를 입력받고, 계정 유효성, PAM 모듈 제한 등을 확인합니다. 로그인 성공 시 사용자의 bash가 로드되며, 관련 설정 파일을 읽어 환경을 초기화합니다. 로그인 성공으로 부팅 과정이 완료됩니다.

태그: linux BIOS MBR GRUB GRUB2

6월 1일 18:46에 게시됨