OS

[ Linux ] Boot Process

jogaknabi_1023 2024. 9. 25. 11:41

 Linux Boot Process

BIOS/UEFI -> Bootloader (Stage1 / MBR -> Stage2) -> Hardware (Kernel initramfs -> udev) -> systemd (systemctl default [/etc/systemd/system/default.target] -> [/usr/lib/systemd/system/*.target]-> Default Target [/usr/lib/systemd/system/getty@.service]->virtual terminals)

 

 

1. UEFI (Unified Extensible Firmwale Interface)

- 펌웨어 인터페이스로 기존의 BIOS 대체하여 더 많은 기능과 보안성 제공하고 있음.

- 시스템 하드웨어와 제공되는 펌웨어, 시스템의 모든 하드웨어 구성요소, 운영 체제 간의 인터페이스

- 가장 중요한 보안 부팅(secure booting)을 제공한다.

- CSM (Compatibility Support Module)

- BIOS는 MBR 사용하지만 UEFI 는 GPT 사용한다.

 

Secure Boot

- 신뢰 체인을 구축하는 것을 의미. 플랫폼은 이 신뢰 사슬의 루트이며 메인보드와 온보드 펌웨어는 플랫폼으로 간주될 수 있다.

즉 하드웨어 공급업체이며, 하드웨어 공급업체에서 구성 요소 제조업체, OS 공급업체 등으로 흐른다.

- 신뢰는 공개 키 암호화를 통해 표현된다. 하드웨어 공급업체는 신뢰의 루트를 나타내는 소위 플랫폼 키(PK)를 펌웨어에 넣는다. 운영 체제 공급업체 및 기타 공급업체와의 신뢰 관계는 플랫폼 키로 키에 서명하여 문서화한다. PK: Platform Key

- 마지막으로 펌웨어가 신뢰할 수 있는 키 중 하나로 서명되지 않은 코드는 실행되지 않도록 한다.

- 보안 부팅을 사용하려면 펌웨어에서 신뢰하는 키로 OS 로더에 서명해야하며 OS 로더가 로드하는 커널을 신뢰할 수 있는지 확인해야한다.

- Key Exchange Key (KEK)를 UEFI 키 데이터베이스에 추가할 수 있다. 이렇게 하면 PK의 비공개 부분으로 서명된 다른 인증서를 사용할 수 있다.

 

(1) UEFI 보안 부팅 지원하려면 펌웨어가 신뢰할 수 있는 키로 인식하는 디지털 서명이 있는 부트로더가 필요하다. 이 키는 수동개입 없이도 펌웨어에서 사전에 신뢰한다. 이 방법에는 두가지가 있다. 한 가지는 하드웨어 공급업체와 협력하여 SUSE 키를 보증하도록 한 다음 SUSE에서 부트로더에 서명하는 것. 다른 방법은 Microsoft의 윈도우 로고 인증 프로그램을 거쳐 부트로더를 인증하고 Microsoft에서 SUSE 서명 키를 인식하도록 하는 것.(즉 KEK로 서명.)

(2) 구현계층에서는 Shim loader를 사용한다. 그 역할은 GRUB2와 같은 부트로더를 로드하고 확인하는 것. 이 부트 로더는 SUSE 키로 서명된 커널만 로드한다.

 

신뢰할 수 있는 사용자는 두가지 유형

1. 키를 보유한 사용자. 플랫폼키(PK)는 거의 모든 것을 허용한다. KEK는 PK 변경을 제외한 모든 PK 허용한다.

2. 시스템에 물리적으로 액세스할 수 있는 모든 사람. 물리적으로 액세스할 수 있는 사용자는 시스템을 재부팅하고 UEFI를 구성할 수 있다.

 

UEFI 사용자 요구 충족하기 위해 두 가지 유형 변수 제공

2-1. 인증된 변수.

부팅 프로세스와 실행 중인 OS 모두에서 업데이트할 수 있다. 이는 변수의 새 값이 변수의 이전 값과 동일한 키로 서명된 경우에만 수행할 수 있다. 그리고 더 높은 일련 번호가 있는 값에 추가하거나 변경할 수 있다.

2-2. 부팅서비스 전용변수.

이러한 변수는 부팅 프로세스 중에 실행되는 모든 코드에서 액세스할 수 있다. 부팅 프로세스가 끝나고 OS가 시작되기 전에 부트 로더는 ExitBootServices 호출을 호출해야 한다. 그 후에는 이러한 변수에 더 이상 액세스할 수 없으며 OS가 이를 건드릴 수 없다.

 

(+) SUSE는 SUSE와 Microsoft에서 서명한 작고 간단한 EFI 부트 로더인 shim으로 시작한다. 이를 통해 shim이 로드하고 실행할 수 있다.
shim은 로드하려는 부트 로더가 신뢰할 수 있는지 확인한다. 기본 상황에서 shim은 본문에 포함된 독립적인 SUSE 인증서를 사용한다. 또한 shim은 기본 SUSE 키를 재정의하여 추가 키를 등록할 수 있다. 이하에서 우리는 이것을 "Machine Owner Keys" 또는 줄여서 MOK라고 부른다. 그 다음 부트로더는 커널을 검증한 다음 부팅하고, 커널은 모듈에서 동일한 작업을 수행한다.

 

출처ㅣ https://blog.naver.com/frogx/130081903987

2. MBR 

- Master Boot Record 의 약자로 하드디스크의 첫 번째 파티션을 생성할 때 만들어진다.

- 항상 디스크의 첫 번째 섹터에 위치하며 디스크의 파티션 테이블과 부팅에 필요한 작은 실행 파일을 저장하게 된다.

- 앞쪽 446 바이트는 실행파일이고 바로 뒤 64 바이트가 파티션 테이블, 마지막 2 바이트가 시그니처로 항상 (0x55AA) 값을 가진다.

  그래서 한 섹터는 총 512 바이트를 가진다.

- 바이러스나 기타 이유로 446 바이트가 삭제되거나 변경되면 부팅할 때 아무 메시지 없이 그냥 멈춰있게 되는데 그 경우라고 하더라도 파티션 테이블만 살아있다면 디스크만 분리해서 다른 컴퓨터에 연결하면 파티션 정보는 그대로 사용할 수 있다.

 - 가장 심각한 문제는 파티션 테이블이 망가지는건데 이 경우는 쉽게 해결할 수 없고 하드 복구 전문 업체에 의뢰하거나 전용 소프트웨어 사용해서 복구를 시도해야한다.

- 만약 마지막 2 바이트 값이 0x55AA 아니고 다른 값일 경우 부팅 시 Operating System not Found 같은 에러가 발생한다.

- 망가진 mbr을 복구하는 방법으로는 먼저 fdisk를 사용할 수 있다. (파티션 테이블이 살아있을 경우)

  A:\> fdisk /mbr
  fdisk는 디스크 영역을 만드는 방법 중 하나이고 fdisk /mbr 은 mbr 영역까지 모두 날려버리는 명령어

- MBR은 메모리에 적재될 운영체제가 저장되어 있는 파티션의 부트 섹터 레코드를 읽을 수 있는 프로그램을 포함하고 있는데, 부트 섹터 레코드에는 다시 운영체제의 나머지 부분들을 메모리에 적재시키는 프로그램을 담고 있다.

 

<MBR 역할>

1. 부트 파티션(active partition)을 파티션 테이블에서 찾는다.

2. 부트 파티션의 시작 섹터를 찾는다.

3. 부트 파티션 내의 부트 섹터 레코드를 메모리로 로드시킨다.

4. 부트섹터의 실행코드 전송을 중간에서 컨트롤한다.

만약 MBR이 위의 기능들을 완전히 끝내지 못하면 다음 중 하나의 메시지를 화면에 표시하고 시스템이 정지하게 된다.

- invalid partition table

- Error loading operating system

- Missing operating system

 

3. GRUB : GRand Unified Bootloader

GRUB Legacy와 GRUB 2의 주요 차이점
- 구성은 다른 파일에 저장
- 더 많은 파일 시스템이 지원됩니다(예: Btrfs).

- LVM 또는 RAID 장치에 저장된 파일을 직접 읽을 수 있습니다.

- 사용자 인터페이스는 테마로 변환 및 변경할 수 있습니다.
- 파일 시스템 등과 같은 추가 기능을 지원하기 위해 모듈을 로드하는 메커니즘이 포함되어 있습니다.
- Windows와 같은 다른 커널 및 운영 체제에 대한 부팅 항목을 자동으로 검색하여 생성합니다.
- 최소한의 Bash와 유사한 콘솔이 포함되어 있습니다.

 

https://en.wikipedia.org/wiki/GNU_GRUB

 

< stage 1 -> stage 1.5 -> stage 2 >

- GRUB 부트로더는 현재 GRUB2 으로 버전업되어 사용되고 있다. 두 버전의 큰 차이점은 설정 파일에서 셸 스크립트를 지원한다는 점이다. (설정파일 : /boot/grub2/grub.cfg)
=> 하지만 설정 파일을 직접 변경하는 것은 권장되지 않는다. 그래서 부트로더의 설정을 변경하고 싶다면 /etc/default/grub 파일과 /etc/grub.d 디렉터리에 있는 파일들을 수정하면 된다. 이후 grub2-mkconfig -o <적용시킬 파일> 로 적용시키면 된다.

=> 만약 파일 설정을 잘못하여 부팅이 안될 때 e 키 를 사용하여 해당 메뉴를 편집할 수 있다.

- GRUB 부트로더는 MBR에 위치하고 있다. 하지만 여기에는 전체 GRUB이 아니라 부트로더의 모든 기능을 불러 낼 수 있는 최소한의 기능만을 담은 이미지(stage1)를 담고 있다.

- stage1 이미지는 512 byte의 MBR에 들어갈 수 있는 작은 크기로 다음 단계의 부트로더 이미지를 읽기 위한 작업 만을 처리하게 된다. 다음 단계에 해당하는 stage2 이미지는 GRUB의 코어 이미지로 스스로 부팅 할 수 있는 기능을 제외한 모든 기능을 담고 있다. 요즘에는 다양한 파일시스템과 볼륨 구조위에 stage2 이미지가 존재하기 때문에 stage1에서 모든 파일시스템을 다룰 수 없어서 중간 단계에 해당하는 stage1.5 이미지를 먼저 불러들인다.

- stage1.5 파일들의 이름을 유심히 보면 파일시스템 이름으로 시작하는데 이 파일들을 통해서 각각의 파일시스템을 이해하고 stage2 이미지를 불러들일 수 있는 것이다.

- stage 2가 로딩되면서 GRUB은 사용할 수 있는 kernel 리스트를 살핀다.

- stage 2 부트 로더가 메모리에 있는 상태에서 파일 시스템이 참조되고, 디폴트 커널 이미지와 initrd 이미지가 메모리로 로딩된다. 이미지가 준비되면 stage 2 부트 로더는 커널 이미지를 호출한다.

 

 

<구성 파일들>
1. /boot/grub2/grub.cfg
이 파일에는 GRUB 2 메뉴 항목의 구성이 포함되어 있다. GRUB Legacy에서 사용되는 menu.lst를 대체한다. grub.cfg는 편집하면 안된다. 
2. /boot/grub2/custom.cfg
이 선택적 파일은 부팅 시 grub.cfg에서 직접 소스화되며 부팅 메뉴에 사용자 정의 항목을 추가하는 데 사용할 수 있다.

(+) SUSE Linux Enterprise Server 12 SP2부터 grub-once를 사용할 때 이러한 항목도 구문 분석됩니다.
3. /etc/default/grub
GRUB 2의 보다 일반적인 옵션은 이 파일에 속한다. 예를 들어 메뉴가 표시되는 시간이나 부팅할 기본 OS 등이 있다.

OS 옵션과 UI 옵션이 있다.

4. /etc/grub.d/*
이 디렉토리의 스크립트는 grub2-mkconfig -o /boot/grub2/grub.cfg 명령을 실행하는 동안 읽힌다. 해당 지침은 주 구성 파일 /boot/grub/grub.cfg에 통합되어 있다.
5. /etc/sysconfig/bootloader
이 구성 파일은 부트 로더 유형 및 UEFI 보안 부팅 지원을 활성화할지 여부와 같은 특정 기본 설정을 보관한다.
6. /boot/grub2/x86_64-efi, /boot/grub2/power-ieee1275, /boot/grub2/s390x
이러한 구성 파일에는 아키텍처별 옵션이 포함되어 있다.

 

 

GRUB2 General Options

https://documentation.suse.com/sles/12-SP5/html/SLES-all/cha-grub2.html

 

Administration Guide

Maintain, monitor and customize SLES

documentation.suse.com

 

 

GRUB2 Commands

grub2-mkconfig

grub-2-mkrescue

grub2-script-check

grub2-once

 

4.  리눅스 커널 동작

1) 리눅스 커널 로드: GRUB 부트로더는 설정된 값에 따라 커널 이미지(vmlinuz)를 메모리에 로드한다. 이는 /var/log/dmesg 파일에 기록된다.

2) initramfs 동작: 커널 이미지의 일부로 부팅 초기 단계에서 사용되는 임시 파일 시스템

- 커널이 실행되면서 initramfs를 이용해 메모리 상에서 임시 파일 시스템을 구성한다. 이 단계에서 필요한 장치 드라이버나 루트 파일 시스템을 마운트하는 데 필요한 스크립트들이 실행된다.

- initramfs의 작업이 완료되면, 실제 루트 파일 시스템(/)이 마운트 된다.

- 루트 파일 시스템이 성공적으로 마운트되면, initramfs는 메모리에서 해제되고 루트 파일 시스템이 활성화된다.

=> 위의 과정들을 통해 커널은 디스크에 있는 루트 파일 시스템을 접근할 수 있게 된다.

3) swapper 프로세스 호출: PID 0는 커널이 사용할 각 장치 드라이브들을 초기화 하고 init process(PID 1)이 실행된다.

 

initramfs (Init Ram Filesystem)

- 리눅스 커널이 부팅될 때 메모리에 로드되는 초기 파일 시스템. cpio archive

- 디스크의 실제 루트 파일 시스템을 마운트하기 전에 최소한의 환경을 제공한다.

- 임시 루트 파일 시스템으로 부팅과정에서 커널이 필요한 모듈들을 로드하고 하드웨어 장치를 초기화하며, 디스크 상의 루트 파일 시스템을 마운트할 수 있게 하기 위해 udev 실행한다.

- udev는 장치 관지자로, 커널에 인식된 하드웨어 장치들을 관리하고 그에 맞는 디바이스 파일을 생성하는 역할을 한다. udev는 커널이 인식한 장치들을 기반으로 /dev 디렉토리에 장치 파일을 생성한다.

 

5. init 프로세스 실행

/sbin/init 프로세스가 실행되면서 /etc/inittab 파일을 읽어들여서 그 내용들을 차례대로 실행한다.

 

 

참고자료:

https://lunatine.net/2015/12/18/linux-booting/

https://blog.naver.com/innogrid/221896913110

https://blog.naver.com/acelee369/221451310821