[시스템] 리눅스의 부팅에서 종료(shutdown)까지
멀티부팅으로 구성되어 있는 컴퓨터 ( 일반적으로 윈도우와 리눅스 )가 전
원을 ON 시킴부터 리눅스의 login 메세지가 나올 때 까지 많은 일들이 컴
퓨터에서 일어난다. 윈도우의 경우에는 그 과정을 사용자가 알아 낼 방법
이 없지만 리눅스의 경우는 오픈소스라는 강점으로 사용자가 그 전과정을
모두 인지하여( 물론 몇몇 과정을 이해하기 위해서는 어느정도의 고급 지
식을 요구하긴 하지만 ) 시스템을 운영하는데 많은 도움을 받을 수 있다.
부팅과정의 이해는 리눅스 시스템을 이해하는데 기초적이고도 광범위한 지
식을 제공한다. 좀 늦은 감이 있지만 부팅과정에 대해 지금까지 공부해온
것을 여기 정리하였다. 몇몇 부분은 아직 이해의 수준을 넘어서는 부분이
있어서 자세한 설명을 못 하였다.
PC 전원 ON
PC의 전원이 들어오면 우선 ROM (Read Only Memory)에 들어가 있는 BIOS
(Basic Input Output System)가 작동하여 그래픽카드, 메모리, CPU, 하드
디스크 드라이브, 플로피 디스크 드라이브 등을 테스트 한다. 예전의 경우
에 보면 이 과정에서 화면상에 이유없이 컴퓨터가 다운되거나 하는 경우
가 있는데 많은 경우에 플로피 디스크 드라이브나 하드 디스크 드라이브와
의 통신과정에서 각 장치의 에러로 다운되는 경우가 많다.
어쨌거나 모든 설정을 다 테스트 한 후에 BIOS는 부팅디스크 (혹은 하드디
스크)의 선두 (실린더 0, 섹타1)부터 MBR(Master Boor Record)를 읽는다.
∴참고로 MBR 에 대한 reset 은 윈도우 상에서는 fdisk/mbr 명령을 사용하
여 실시할 수 없다. 윈도우와 리눅스를 멀티부팅으로 설치한 후 혹시라도
차후에 리눅스를 제거 하였는데 계속 lilo 메세지가 뜰 경우 이 명령으로
완전히 제거할 수 있다.
lilo 를 읽음
통상 리눅스의 lilo(Linux Loader)는 MBR에 설치되어 제일 처음 실행된
다.
lilo 의 설정은 : /etc/lilo.conf
boot=/dev/hda
map=/boot/map
install=/boot/boot.b
prompt
timeout=50
default=linux
image=/boot/vmlinuz-2.2.12-20kr
label=linux
initrd=/boot/initrd-2.2.12-20kr.img
read-only
root=/dev/hda1
위의 내용은 리눅스만 설치되어 있는 system의 lilo.conf 의 내용이다. 멀
티부팅의 경우는 윈도우의 부팅부분이 추가가 된다.
통상 lilo는 운영체제의 선택과 모드이 선택, ethernet의 설정등을 같이
행할 수 있으나 일반적으로는 두 개 이상의 OS로 멀티부팅을 설정할 경우
선택적으로 부팅가능하고 linux system 복구나 root 파티션의 파일시스템
을 체크할 경우 linux s, linux 1, linux single 등의 옵션을 사용하여
single user mode 로 부팅할 수도 있다.
Kernel의 실행
lilo에서 linux를 선택하여 부팅을 하면 압축된 커널 이미지 (위의 lilo
의 image 부분, /boot/vmlinuz-2.2.12-20kr)가 메모리로 로드되어 자기전
개 된다.
1에서 3까지의 과정을 도식화 하면
BIOS가 MBR을 읽음
↓
MBR가 부트파티션의 부트블록을 읽어낸다.
↓
부트록을 읽는다.
↓
커널 이미지를 읽어낸다.
↓
시스템파라미터를 취득하여, 커널을 초기화한다.
↓
압축 이미지를 전개한다.
커널의 main.c 함수를 실행하기 전에 커널은 프로텍트 모드로의 전이, CPU
의 레지스터의 설정등 c 프로그램을 실행할 수 있는 환경을 정비한다.
main.c 의 실행
operating system의 가장 기본적인 초기화의 실시과정이다. 메모리의 초기
화 (메모리 상한선의 취득), 페이지테이블의 초기화, 하드웨어 인터럽트
체크 ( 이더넷조사, 키보드, 마우스연결 체크등)후 프로그램 모듈을 로드
한다. main.c의 내용은 /usr/src/linux-2.2.12/init/main.c 에서 살펴볼
수 있다.
main.c 로 제어가 옮겨진 후의 실행 메시지를 보려면
#dmesg > boot.message 등의 명령으로 부트메시지를 화일로 보내어 편집기
등으로 열어서 보면 된다.
main.c 의 제어는 dmesg에서 보면 리눅스 기동시 최초의 프로세서인 init
의 실행전까지 이다.
init process의 기동
init process는 리눅스 기동시 실행되는 최초의 프로세스이다. 프로그램
의 위치는 디스트리뷰션에 따라 다를수 있으나 알짜 리눅스의 경우 /sbin
디렉토리에 위치한다. 또한 init는 /etc/initab 의 설정사항에 따라 리눅
스체제를 구축한다.
∴참고 : 리눅스의 모든 프로세스는 최초의 프로세스인 init 의 자기복제
의 과정을 통해 생성된다. 즉 init 프로세스로 부터 fork(복제)와 exec(실
행) 의 2개의 system call을 사용하여 새로운 프로세스를 창조한다. 이러
한 내용은 pstree 명령으로 확인할 수 있다.
/etc/inittab 의 내용 #
# inittab This file describes how the INIT process should set up
# the system in a certain run-level.
#
# Author: Miquel van Smoorenburg, <miquels at
drinkel.nl.mugnet.org>
# Modified for RHS Linux by Marc Ewing and Donnie Barnes
#
# Default runlevel. The runlevels used by RHS are:
# 0 – halt (Do NOT set initdefault to this)
# 1 – Single user mode
# 2 – Multiuser, without NFS (The same as 3, if you do not have
networking)
# 3 – Full multiuser mode
# 4 – unused
# 5 – X11
# 6 – reboot (Do NOT set initdefault to this)
#
id:3:initdefault:
# System initialization.
si::sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
# Things to run in every runlevel.
ud::once:/sbin/update
# Trap CTRL-ALT-DELETE
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
# When our UPS tells us power has failed, assume we have a few
minutes
# of power left. Schedule a shutdown for 2 minutes from now.
# This does, of course, assume you have powerd installed and your
# UPS connected and working correctly.
pf::powerfail:/sbin/shutdown -f -h +2 “Power Failure; System
Shutting Down”
# If power was restored before the shutdown kicked in, cancel it.
pr:12345:powerokwait:/sbin/shutdown -c “Power Restored; Shutdown
Cancelled”
#if UPS batteries are getting low, do an immediate shutdown.
pn::powerfailnow:/sbin/halt -p
# Run gettys in standard runlevels
1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
# Run xdm in runlevel 5
# xdm is now a separate service
x:5:respawn:/etc/X11/prefdm -nodaemon
sysinit 의 기동
init 가 기동되면 우선 최초로 싱글유저 모드에서 sysinit 액션의 프로세
스가 실행된다.(/etc/rc.d/rc.sysinit)
위 inittab 의 # System initialization.부분.
si::sysinit:/etc/rc.d/rc.sysinit
편집기로 /etc/rc.d/rc.sysinit 를 살펴보면 bash 로 작성된 셀 스크립트
이다. sysinit 는 fsck에 의해 디스크정합성 check가 이루어지고 필요한
커널모듈이 로드된다. 또한 swap을 개시하고 fstab 에 의해 디스크등의 외
부 장치가 mount 된다.
∴참고 : root 파티션에 대한 fsck의 실행은 싱글유저 모드에서 실행되어
야 한다. 이러한 이유로 인해서 리눅스 모드가 3인 멀티유저 모드로 선택
되어 있어도 우선 싱글유저 모드에서 root 파티션에 대한 정합성 check
를 하게 된다.
/etc/fstab 의 내용 /dev/hda1 / ext2 defaults 1 1
/dev/cdrom /mnt/cdrom iso9660 noauto,owner,ro 0 0
/dev/cdrom1 /mnt/cdrom1 iso9660 noauto,owner,ro 0 0
/dev/hda5 swap swap defaults 0 0
/dev/fd0 /mnt/floppy ext2 noauto,owner 0 0
none /proc proc defaults 0 0
none /dev/pts devpts gid=5,mode=620 0 0
rc 파일의 실행
디폴트 런레벨 (/etc/inittab 의 initdefault 부분) 에 따라서 각 rc의 실
행이 이루어 진다. 예를 들어 멀티유저 모드를 디폴트로 구성했다
면 /etc/rc.d/rc 3 가 기동된다. 이 디렉토리 안에는 각종 deamon 이나 멀
티유저 모드에서 필요한 스크립트 들어있다.
getty의 기동
모뎀이 접속된 회선이나 콘솔을 감시해서 액세스 해온 디바이스에 로그인
prompt를 보내고, 보내온 유저 이름을 로그인 prompt를 기동해서 getty 프
로그램으로 보낸다. login 프로그램은 password prompt 를 표시하여, 패스
워드가 건네지면 /etc/passwd 파일의 내용과 대조하여 잘못이 있으면 다
시 login prompt 를 표시하고 인정되면 그 유저의 로그인 쉘을 실행한다.
각 계정의 실행은 계정이 생성될때 동시에 생성되는 숨겨진 파일
인 .bashrc, bash_profile 등의 스크립트를 참조하여 login 된다.
∴참고 : 리눅스 파일 시스템에서 파일의 이름앞에 .이 붙은면 숨김 속성
을 갖는다. 이런 모든 파일을 보기위해서는 ls -a 옵션을 사용해야 한다.
또한 파일의 속성을 알아보려면 file [파일이름] 을 사용하면 알 수 있
다.
getty는 system에 따라 mgetty, agetty, mingetty 로 나타나는데, agetty
나 mgetty는 serial 회선을 감시하고 mingetty는 가상 콘솔로서의 구성을
감시한다. 위의 /etc/inittab 의 run getty 부분을 보면 여섯개의
mingetty가 실행됨으로써 리눅스에서 여섯개의 가상콘솔을 운영할 수 있
게 된다.
이상에서 리눅스의 부팅과정을 간단히 살펴보았는데 실제로 많은 부분이
생략되어 있다. 리눅스에서는 모든 소스코드가 첨부되어 있기 때문에
init 등의 프로그램 소스를 찾아보면 보통 c언어로 작성되어 있음을 알
수 있다. 가능하면 소스코드까지 분석을 해보고 싶지만 아직은 C언어에 대
한 지식이 부족하여서 보기가 어려웠고 차후에 기회가 닿는다면 리눅스커
널 분석에 도전하고 싶은 생각이 있다.