NAME

boot - 유닉스 시스템 V 릴리스 4 기반의 시스템 부팅 과정

DESCRIPTION

부팅 과정(또는 "부트 절차")의 세부 내용은 시스템마다 다르지만 대략적으로 다음 요소들이 통제하는 단계들로 나눌 수 있다.

  1. 하드웨어
  2. 운영 체제(OS) 로더
  3. 커널
  4. 루트 사용자 공간 프로세스 (initinittab)
  5. 부트 스크립트

각각을 아래에서 자세히 설명한다.

하드웨어

전원을 켜거나 하드 리셋을 한 후에는 읽기 전용 메모리(보통 PROM)에 저장된 프로그램으로 제어권이 간다. 개인용 컴퓨터와 관련된 역사적 이유로 이 프로그램을 종종 "바이오스(BIOS)"라고 한다.

보통 이 프로그램은 머신에 대한 기본적인 자가 검사를 수행하고 비휘발성 메모리에 접근하여 추가 매개변수를 읽는다. PC에서 이 메모리는 배터리로 동작하는 CMOS 메모리이며, 그래서 많은 사람들이 그걸 "CMOS"라고 부른다. PC 세계 밖에서는 일반적으로 "NVRAM"(비휘발성 RAM)이라고 한다.

NVRAM에 저장되는 매개변수는 시스템마다 다르지만 최소한 어떤 장치가 OS 로더를 제공할 수 있는지를, 아니면 적어도 어떤 장치에서 OS 로더를 찾아볼 수 있는지를 명시해야 한다. 그런 장치를 "부트 장치(boot device)"라고 한다. 하드웨어 부트 단계에서는 부트 장치의 고정된 위치로부터 OS 로더를 적재하고 그리로 제어권을 넘긴다.

참고: OS 로더를 읽어들일 장치가 네트워크를 통해 붙어 있을 수도 있다. 이런 경우 부팅의 세부 사항을 DHCP, TFTP, PXE, Etherboot 등과 같은 프로토콜들이 명시한다.

OS 로더

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" 한 다음) 그 변수 값들을 사용한다.

FILES

/etc/init.d/, /etc/rc[S0-6].d/, /etc/sysconfig/

SEE ALSO

init(1), systemd(1), inittab(5), bootparam(7), bootup(7), runlevel(8), shutdown(8)


2015-03-11