-
Notifications
You must be signed in to change notification settings - Fork 7
boot(7)
boot - 유닉스 시스템 V 릴리스 4 기반의 시스템 부팅 과정
부팅 과정(또는 "부트 절차")의 세부 내용은 시스템마다 다르지만 대략적으로 다음 요소들이 각각 통제하는 단계들로 나눌 수 있다.
- 하드웨어
- 운영 체제(OS) 로더
- 커널
- 루트 사용자 공간 프로세스 (
init
및inittab
) - 부트 스크립트
이 단계들 각각을 아래에서 자세히 설명한다.
전원을 켜거나 하드 리셋을 한 후에는 읽기 전용 메모리(보통 PROM)에 저장된 프로그램으로 제어권이 간다. 개인용 컴퓨터와 관련된 역사적인 이유 때문에 이 프로그램을 종종 "바이오스(BIOS)"라고 한다.
보통 이 프로그램은 머신에 대한 기본적인 자가 검사를 수행하고 비휘발성 메모리에 접근하여 추가 매개변수들을 읽는다. PC에서 이 메모리는 배터리로 동작하는 CMOS 메모리이며, 그래서 많은 사람들이 그걸 "CMOS"라고 부른다. PC 세계 밖에서는 일반적으로 "NVRAM"(비휘발성 RAM)이라고 한다.
MVRAM에 저장되는 매개변수는 시스템마다 다르지만 최소한 어떤 장치가 OS 로더를 제공할 수 있는지를, 아니면 적어도 어떤 장치에서 OS 로더를 찾아볼 수 있는지를 명시해야 한다. 그런 장치를 "부트 장치(boot device)"라고 한다. 하드웨어 부트 단계에서는 부트 장치의 고정된 위치로부터 OS 로더를 적재하고 그리로 제어권을 넘긴다.
참고: OS 로더를 읽어들일 장치가 네트워크를 통해 붙어있을 수도 있다. 이런 경우 부팅의 세부 사항을 DHCP, TFTP, PXE, Etherboot 등과 같은 프로토콜들이 명세한다.
OS 로더의 주된 역할은 어떤 장치에서 커널이 있는 위치를 알아내서 적재한 다음 실행하는 것이다. 많은 OS 로더들에서는 대화형 사용 방식을 통해 (아마도 마지막 컴파일 한 커널이 동작하지 않을 때의 대비책으로) 다른 커널을 지정하거나 커널에 선택적인 매개변수를 전달할 수 있다.
전통적 PC에서 OS 로더는 부트 장치의 최초 512바이트 블록에 위치한다. 이 블록을 "MBR"(Master Boot Record; 마스터 부트 레코드)라고 한다.
여러 시스템에서 OS 로더는 다양한 제약들 때문에 아주 제한되어 있다. PC 아닌 시스템들에서도 이 로더의 크기와 복잡도에 어떤 제약이 있지만 PC MBR의 크기 제약(512바이트. 파티션 테이블 포함)은 거기에 많은 기능을 집어넣는 걸 거의 불가능하게 한다.
그래서 여러 시스템에서는 OS를 적재하는 역할을 1차 OS 로더와 2차 OS 로더로 나눈다. 이 2차 OS 로더는 디스크 파티션 같은 영속 저장소의 더 큰 부분 안에 있을 수 있다.
리눅스에서 OS 로더는 많은 경우 lilo(8)
아니면 grub(8)
이다.
커널은 올라가면서 컴퓨터와 운영 체제의 다양한 구성 요소들을 초기화 한다. 일반적으로 그런 일을 책임지는 소프트웨어의 각 부분을 해당 구성 요소의 "드라이버(driver)"라고 본다. 커널은 가상 메모리 스와퍼(요즘 리눅스 커널에서는 "kswapd"라는 커널 프로세스)를 시작하고 루트 경로 /
에 어떤 파일 시스템을 마운트 한다.
커널에 전달할 수 있는 매개변수들 중 일부가 이 동작들과 관련되어 있다. (예를 들어 기본 루트 파일 시스템을 변경할 수 있다.) 리눅스 커널 매개변수에 대한 자세한 내용은 bootparam(7)을 읽어 보라.
여기까지 하고 나서야 커널이 최초의 사용자 공간 프로세스를 생성한다. 그 프로세스에는 PID(프로세스 ID)로 1번을 준다. 전통적으로 이 프로세스는 프로그램 /sbin/init
을 실행하는데, 커널이 처리하지 못한 매개변수들이 그리 전달된다.
참고: 다음 설명은 유닉스 시스템 V 릴리스 4를 기반으로 하는 OS에 적용된다. 하지만 널리 쓰이는 여러 시스템들에서는 관련은 있지만 근본적으로 다른 systemd(1)
라는 방식을 채택했다. 그와 연계된 bootup(7)에서 거기서의 부팅 과정을 상술한다.
/sbin/init
은 시작하면서 /etc/inittab
을 읽어서 추가 지시를 받는다. 이 파일에서는 /sbin/init
프로그램이 특정 런레벨(run-level)로 진입하라는 지식를 받을 때 무엇을 실행해야 하는지를 규정한다. 그래서 관리자가 어떤 용도를 위한 환경을 손쉽게 수립할 수 있게 해 준다. 각 런레벨은 일군의 서비스들과 연계되어 있다. (예를 들어 런레벨 S
는 단일 사용자(single-user) 모드이며 런레벨 2
에는 상당수의 네트워크 서비스 실행이 수반된다.)
관리자가 init(1)
을 통해 현재 런레벨을 바꿀 수 있고 runlevel(8)
을 통해 현재 런레벨을 질의할 수 있다.
하지만 이 파일을 편집해서 개별 서비스들을 관리하는 것은 불편하므로 /etc/inittab
에서는 개별 서비스들을 실제로 시작/정지하는 일군의 스크립트들을 실행하기만 한다.
참고: 다음 설명은 유닉스 시스템 V 릴리스 4를 기반으로 하는 OS에 적용된다. 하지만 널리 쓰이는 여러 시스템들(슬랙웨어 리눅스, FreeBSD, OpenBSD)에는 다소 다른 부트 스크립트 체계가 있다.
관리하는 서비스(메일, nfs 서버, cron 등)마다 특정 디렉터리(대다수 리눅스 버전들에서는 /etc/init.d
)에 개시 스크립트가 한 개씩 있다. 이 스크립트 각각은 (서비스를 시작하게 만드는) "start"나 (서비스를 정지하게 만드는) "stop"을 유일한 인자로 받는다. 선택적으로 다른 "편의용" 매개변수를 받을 수 있다. (가령, 정지하고 시작하는 "restart", 서비스 상태를 표시하는 "status" 등.) 매개변수 없이 스크립트를 실행하면 가능한 인자들을 표시해 준다.
특정 런레벨에서 정해진 순서로 특정 스크립트들이 시작/정지하게 하기 위해 순서 지정 디렉터리가 있다. 보통 /etc/rc[0-6S].d
형태이다. 이 디렉터리 각각에 /etc/init.d
디렉터리의 스크립트에 대한 (일반적으로 심볼릭) 링크들이 있다.
inittab(5)
으로부터 주 스크립트(일반적으로 /etc/rc
)가 호출된다. 이 주 스크립트에서 해당하는 순서 지정 디렉터리의 링크를 통해 각 서비스의 스크립트를 호출한다. 이름이 'S'로 시작하는 링크는 "start" 인자로 호출한다 (서비스 시작). 이름이 'K'로 시작하는 링크는 "stop" 인자로 호출한다 (서비스 정지).
동일 런레벨 내에서 시작 순서나 정지 순서를 규정하도록 링크 이름에 순서 번호가 있다. 그리고 명확성을 위해 일반적으로 링크 이름이 참조하는 서비스의 이름으로 끝난다. 예를 들어 /etc/rc2.d/S80sendmail
링크는 런레벨 2에서 sendmail 서비스를 시작한다. 그리고 /etc/rc2.d/S12syslog
를 시작한 후이면서 /etc/rc2.d/S90xfs
를 시작하기 전에 그렇게 한다.
이 링크들을 관리하는 것은 부트 순서와 런레벨을 관리하는 것이다. 여러 시스템에는 이 작업을 도와 주는 도구들(가령 chkconfig(8)
)이 있다.
서비스를 제공하는 프로그램을 종종 "데몬(daemon)"이라고 한다. 일반적으로 데몬은 다양한 명령행 옵션과 매개변수들을 받을 수 있다. 시스템 관리자가 전체 부트 스크립트를 편집하지 않고도 이 입력을 바꿀 수 있게 하기 위해 어떤 별도 설정 파일을 사용하며 그 파일은 연계된 부트 스크립트에서 찾을 수 있는 특정 디렉터리(구식 레드햇 시스템에서는 /etc/sysconfig
)에 있다.
구식 유닉스 시스템들에서는 그런 파일에 데몬을 위한 실제 명령행 옵션들이 들어 있었다. 하지만 요즘의 리눅스 시스템들에서는 (또 HP-UX에서는) 셸 변수들만 담고 있다. /etc/init.d
내의 부트 스크립트가 설정 파일을 읽어서 포함한 다음 (즉 설정 파일을 "source
" 한 다음) 그 변수 값들을 사용한다.
/etc/init.d/
, /etc/rc[S0-6].d/
, /etc/sysconfig/
init(1)
, systemd(1)
, inittab(5)
, bootparam(7), bootup(7), runlevel(8)
, shutdown(8)
2015-03-11