Archive/독학기록
4단계 리눅스 시스템 부팅과정
YonKim
2021. 12. 15. 17:36
728x90
반응형
🐧욘로그(Yon-Log)
네트워크, 리눅스, AWS, 트러블슈팅 로그 by Yon
yonlog.tistory.com
시스템 부팅이란
시스템 부팅 프로세스의 목적은 커널을 메모리에 올리고 실행하는 것이다. 리눅스 시스템의 부팅 과정을 4단계로 나누어 가시화하고 이해하기 위해 이 포스팅을 작성했다. 디테일한 부팅 프로세스를 알아보기 전, 아래와 같은 의문이 선행될 수 있다.
- Q1. 부팅 전, 커널은 어디에 있지?
- Q2. 부팅 전, 메모리에는 뭐가 있지?
- Q3. 부팅 후 첫 번째로 실행되는 것은 뭐지?
리눅스 시스템 부팅 프로세스
리눅스 시스템의 부팅 프로세스는 아래 4단계의 순서로 진행된다.
1단계: 하드웨어 단계
2단계: 부트로더 단계
3단계: 커널로드 단계
4단계: INIT 단계(SysV / Systemd)
1단계: 하드웨어 단계
1-1. Power On
- 파워버튼을 통해 전원이 공급되면 메인보드는 리셋 벡터(Reset Vector)를 통해 CPU가 BIOS 코드를 호출하도록 한다.
- 모든 Intel CPU들은 전원 공급 직후 초기 부팅 때 real mode로 동작하는데, 이 시점에서는 전체 메모리의 1MB 영역까지만 접근할 수 있다. 이 영역의 주소는 0xFFFFFFFF로, 1978년도의 Intel CPU 8086도, 최신 CPU도 같은 방식으로 동작한다.
- 초기부팅 직후 CPU가 처음으로 하게 될 일은 EIP(Extend Instruction Pointer-CPU가 할 일들, 즉 메모리에 등록되어 있는 Code의 주소를 가리키는 포인터)에 숨겨진 0xFFFFFFF0 주소로 점프하는 것이다. 이 주소는 펌웨어(BIOS, EFI)의 엔트리 포인트로 매핑되는 영역으로 리셋 벡터(Reset Vector)라고 한다. 이 영역은 전원을 켰을 때 항상 같은 자리에 있지만 real mode(초기 부팅 때 전체 메모리의 1MB 영역까지만 접근 가능하지 못함)에서는 접근할 수 없도록 숨겨져 있다.
- 즉, 부팅 직후 CPU는 리셋 벡터를 통해 펌웨어(BIOS, EFI)로 접근하고, 이곳에서 펌웨어 코드(BIOS Code)를 실행한다.
- 특히 BIOS는 레거시 바이오스라고 불리며, 하드디스크의 첫 섹터를 읽어서 첫 섹터에 지시된 주소에 있는 코드를 실행하도록 하는 부팅 절차를 따른다.
- 펌웨어는 시스템의 하드웨어 구성을 저장한다.
1-2. POST, BOOT SECTOR(MBR/VBR/EBR)
- Power-on-self-test (POST): "삐~" CPU, RAM, 제어장치, BIOS 코드 자체, 주변장치 등에 대한 검사 진행
- OS외 기존 가상화 확장, 보안 등에 대한 구성 확인
- MBR(Master Boot Record)
POST 과정이 완료되면, BIOS는 부팅 디바이스(하드디스크 등)를 검색하고, 해당 디바이스의 파티션 테이블을 검색한다. 파티션 되지 않은 장치의 시동 섹터는 VBR이 된다. 파티션 테이블을 찾은 경우, 해당 파티션의 첫 번째 블록(섹터 0) 512 bytes의 MBR(Master Boot Record-시동섹터)에서 부트로더 코드(Boot Loader Code=OS Loader)를 검색한다. 부트로더 코드를 찾으면 메모리에 로드시킨다.
ㅡ파티션 테이블(Partition Table): 4개 Primary partition 정보(시작~끝 블록, 크기 등) (64bytes)
ㅡ부트 시그니처(Boot Signature): 부트로더 코드의 고유값(0x55AA) (2 bytes)
- VBR(Volume Boot Record)
- 각 Primary partition의 첫 번째 블록(부트로더 코드와 부트시그니처를 포함할 수 있다)
- 파티션되지 않은 장치의 시동 섹터는 VBR이다.
- EBR(Extended Boot Record)
- 각 Logical partition(하나의 파티션을 sub-divide 한 파티션 단위)의 첫 번째 블록(파티션 테이블, VBR 부트시그니처 포함)
- EBR의 파티션 테이블에는 모든 Logical partition이 링크되어 있다.
2단계: 부트로더 단계
2-1. GRUB(GRand Unified Bootloader): Linux Loader
- GRUB은 GRUB Stage1 > 1.5 > 2 의 세 단계를 거치는 부트로더로 현재는 GRUB2가 가장 보편적으로 많이 사용된다.
- GRUB Stage 1.
MBR 또는 VBR에 저장되어 있는 부트 이미지가 메모리에 로드되고 실행됨(core.img의 첫 번쩨 섹터 로드)
- GRUB Stage 1.5
MBR과 첫번째 파티션 사이에 있는 블록(a.k.a MBR gap)에 저장된 core.img가 메모리에 로드되고 실행됨. core.img의 configuration 파일과 파일시스템을 위한 드라이버를 로드한다. - GRUB Stage 2
/boot/grub 파일 시스템에 직접 접근하여 커널(vmlinuz)의 압축을 풀어 메모리에 로드하고, 커널이 필요로 하는 모든 드라이버와 모듈, 파일시스템(ext2, ext3, ext4...)등이 담긴 RAM 디스크 파일(initrd.img)를 메모리에 로드한다.
* 커널은 로드되기 이전 /boot 아래 압축된 파일 형태인 vmlinux 로 존재 > GRUB Stage 2에서 압축 풀고 로드
* 커널 컴파일(Kernel Compile)을 통해 GRUB을 통해 로드할 커널 버전을 고를 수 있음
- GRUB Stage 1.
- GRUB은 파일시스템과 함께 동작할 수 있음 (ext2, ext3, ext4... 등등)
- UEFI 버전도 ㅇㅋ(grub.efi)
- grub> 이라는 고유의 작은 셸을 사용할 수 있음(이 셸의 프롬프트를 통해 부팅 파라미터 및 부팅OS 등을 정의할 수 있음)
3단계: 커널 단계(Loading the Kernel)
부팅 2단계까지 지나며 현재 부트로더는 커널파일과 RAM디스크 파일을 메모리에 로드해놓은 상태이다
ㅡ vmlinux-2.6.26-2-686
ㅡ initrd.img-2.6.26-2-686
로드된 커널파일 실행
- 로드된 커널파일 실행, 콘솔에 관련 정보 띄워줌
- PCI bus 점검 및 감지된 주변장치(Peripheral) 확인 후 /var/log/dmesg 파일에 기록
- 커널은 swapper 프로세스(PID 0)를 호출, swapper(PID 0)는 커널이 사용할 각 장치드라이브들을 초기화
- Root file system (" / ")을 읽기 전용으로 마운트ㅡ이 과정에서 마운트 실패시 "커널 패닉" 메시지 출력
- 문제없이 커널이 실행되고 나면 언마운트 후 Root File System을 읽기+쓰기 모드로 리마운트
- 이후 Init 프로세스(PID 1)를 호출
4단계 INIT(sysV)
init 시스템은 SysV 및 Systemd로 구분된다
SysVinit 1. Configuration. the file /etc/inittab
- /etc/inittab의 초기 시스템 구성 파일을 읽어옴(Operation mode, 런레벨, 콘솔 등)
SysVinit 2. Initialization. the file /etc/init.d/rc
- /etc/init.d/rc.S(debian) 명령 실행
- (시스템 초기화-스왑영역 로드, 필요없는 파일 제거, 파일시스템 점검 및 마운트, 네트워크 활성화 등)
SysVinit 3. Services. /etc/init.d 및 /etc/rcN.d 디렉토리들
- 지정된 런레벨에 해당하는 스크립트 및 서비스 실행
- /etc/init.d 의 실행 가능한 서비스들 모두 실행(cron, ssh, lpd 등등)
- 각 런레벨별로 실행할 서비스들은 /etc/rcN.d 에서 정의할 수 있음 (S01: 런레벨 1에서 활성화, K01:런레벨 1에서 비활성화)
4단계 INIT(systemd: BSD init)
systemd는 대표적으로 Ubuntu Linux의 Init System이다.
Sysvinit에 비해 시작속도가 빠르고, 리눅스 시스템을 보조하는 풀타임 프로세스로 상주한다
Target 유닛을 사용하여 부팅, 서비스관리, 동기화 프로세스를 진행한다
System Unit : Any resource that system can operate/manage (ex. .service, .target, .device, .mount, .swap...)
Systemd Boot process
- systemd용 GRUB2 구성(GRUB_CMDLINE_LINUX="init=/lib/systemd/systemd" (이후 update-grub 실행)
- 첫 번째 .target 유닛 실행 (보통 graphical.target의 심볼릭 링크임)
#첫 번째 .target 유닛
[Unit]
Description=yon boot target
Requires=multi-user.target
Wants=yonbar.service
After=multi-user.target rescue.service rescue.target
- Requires = hard dependencies
- Wants = soft dependencies (시작이 필요하지 않은)
- After = 여기서 정의된 서비스들 실행 이후에 부팅할 것
reference
1) https://itragdoll.tistory.com/3
2) 쉽게 배우는 운영체제 (조성훈 지음)
3) Wasabi Session
4) https://ocw.unican.es/
5) https://manybutfinite.com/post/how-computers-boot-up/
728x90