사이트 내 전체검색
[linux] 막강한 부트로더 GRUB
로빈아빠
https://cmd.kr/server/230 URL이 복사되었습니다.

본문

막강한 부트로더 GRUB

필자 : 이호석 (alee@debian-kr.org)

1. GRUB 소개
부트로더란 간단히 말해서 컴퓨터를 켰을 때 가장 먼저 실행되는 프로그램이다. 부트로더는 OS의 커널을 로드하고 몇몇 커널 파라메터를 커널에 넘겨주는 일을 한다. GNU GRUB은 원래 처음에는 GNU Hurd를 위해 개발되었지만 그 막강한 기능 때문에 리눅스에서도 점차 LILO 대신 GRUB을 사용하는 사람들이 늘고 있다. GRUB은 현재 리눅스를 비롯하여 많은 공개 운영체제와 chain-loading을 사용하는 상용 운영체제를 로드할 수 있다.

GRUB의 가장 큰 특징은 파일시스템과 커널 포맷을 이해한다는 점이다. 따라서 디스크상에서 커널의 물리적인 위치를 알 필요 없이 단지 파일명과 커널이 위치하고 있는 파티션만 알고 있으면 커널을 로드할 수 있다. LILO의 경우 부트로더가 커널의 하드디스크상의 물리적인 위치를 알고 있어야 한다. 따라서 커널을 다시 설치할 때마다 ‘lilo’를 실행해 부트로더를 다시 심어 주어야 하지만, GRUB의 경우 파일명만 알면 되기 때문에 파일명이 바뀌지 않는 한 다시 실행해 줄 필요가 없다.

현재 GRUB은 다음과 같은 기능들을 제공한다.

1. a.out 포맷과 ELF 포맷의 커널을 읽어들일 수 있다.
2. Linux, FreeBSD, NetBSD, OpenBSD등 비-멀티부트 커널을 지원한다.
3. 멀티플 모듈을 로드할 수 있다.
4. 텍스트 형식의 설정 파일을 제공한다.
5. 메뉴 인터페이스를 제공한다.
6. 유연한 커맨드라인 인터페이스를 제공한다.
7. BSD FFS, FAT16, FAT32, Minix, ext2 그리고 ReiserFS 파일시스템을 지원한다.
8. gzip으로 압축된 파일을 다룰 수 있다.
9. BIOS에서 인식되는 모든 장치에 엑세스할 수  있다.

2. GRUB 설치
GRUB은 다음 위치에서 다운받을 수 있다.

ftp://alpha.gnu.org/gnu/grub/

현재 최신 버전은 0.5.96이다. ftp 프로그램을 이용하여 grub-0.5.96.tar.gz 파일을 다운받아 압축을 풀고 컴파일하여 설치한다. 의존하는 라이브러리가 별로 없으니 대부분의 경우 쉽게 컴파일될 것이다.

$ wget ftp://alpha.gnu.org/gnu/grub/grub-0.5.96.tar.gz #한 줄임
$ tar -xvzf grub-0.5.96.tar.gz
$ cd grub-0.5.96
$ ./configure
$ make
# make install

데비안의 경우 이미 패키지로 제공되기 때문에 간단히 그냥 다음과 같이 입력하면 바로 다운받아 설치된다.

# apt-get install grub

3. 부트로더 설치
먼저 “/boot/grub”이라는 디렉토리를 만들고 “/usr/local/share/grub/i386-pc” 디렉토리에서 “stage1”, “stage2” 파일과 자신의 파일시스템에 맞는 “파일시스템_stage1_5” 파일을 복사해온다.
리눅스 커널이 위치하고 있는 파티션이 ext2라면 “e2fs_stage1_5” 파일은 반드시 복사해와야 한다. 여러가지 파일시스템을 사용하고 있다면 모두 다 복사해와도 상관없다. 데비안 패키지로 설치했을 경우에는 “/usr/share/grub/i386-pc” 디렉토리의 파일들을 복사해오면 된다.

# mkdir /boot/grub
# cp /usr/local/share/grub/i386-pc/*/boot/grub/

그리고나서 소스 디렉토리 안에 있는 “docs” 라는 디렉토리에서 “menu.lst” 라는 파일을 “/boot/grub” 디렉토리로 복사한다. 데비안 패키지로 설치했을 경우 “menu.lst” 파일은 “/usr/share/doc/grub” 디렉토리에 있다.

# cp doc/menu.lst /boot/grub

이제 복사해 온 “menu.lst” 파일을 자신의 시스템에 맞게 수정할 차례이다. 그 전에, 먼저 알아 두어야 할 것이 있다.

GRUB에서 사용하는 디스크 이름은 리눅스에서와는 조금 다르다. 예를 들어 리눅스의 “hda1”은 GRUB에서는 “(hd0,0)” 이다. GRUB에서 첫 번째 플로피 디스크 드라이브는 (fd0), 두 번째 플로피 디스크 드라이브는 (fd1)이다. 또, 하드디스크는 순서대로 (hd0), (hd1), (hd2)... 이고, 첫 번째 하드디스크의 첫 번째 파티션은 (hd0,0), 두 번째 파티션은 (hd0,1), 세 번째 파티션은 (hd0,2)... 이런 식으로 이름이 붙여진다.

GRUB은 IDE 하드디스크와 SCSI 하드디스크를 구별하지 않는다. 따라서 SCSI건 IDE건 첫 번째 하드디스크는 무조건 (hd0)이다. 이 때 번호가 “0”번부터 시작한다는 것에 유의해야 한다. 즉, 리눅스의 “hda2”는 GRUB에서는 (hd0,2)가 아니라 (hd0,1)이다. 리눅스에서와 비슷하게 GRUB에서 확장(Extended) 파티션은 4번부터 번호가 매겨진다. 예를 들어, 첫 번째 하드디스크의 첫 번째 확장 파티션(리눅스의 hda5)은 (hd0,4)이다.

또, 파일시스템에 있는 어떤 파일을 나타낼 때에는 “(hd0,0)/boot/vmlinuz”와 같이 파티션 뒤에 곧바로 이어서 파일의 절대 경로를 적어준다. 만약 파티션을 생략하고 그냥 “/boot/vmlinuz”로 적어주면 현재 GRUB의 루트 파티션으로 설정되어 있는 파일시스템 안에 있는 “/boot/vmlinuz” 파일을 가리키게 된다.

자, 이제 “menu.lst” 파일의 내용을 살펴보기로 하자. 쉘 스크립트에서처럼 “#”으로 시작하는 줄은 주석처리된 줄이다.
-----------------------------------------------------------------------
# Boot automatically after 30 secs.
timeout 30

# By default, boot the first entry.
default 0

# Fallback to the second entry.
fallback 1

위의 내용은 이미 짐작하고 있겠지만, 30초 동안 입력이 없으면 첫 번째 방법, 즉 파일에서 맨 앞 쪽에 기술되어 있는 방법으로 부팅하라는 뜻이다. 맨 아래 줄은 만약 첫 번째 방법으로 부팅하다가 실패했을 경우 두 번째 방법으로 부팅하라는 뜻이다.

아래로 조금 내려가다 보면 다음과 비슷한 내용이 있을 것이다.

# For booting Linux
title  GNU/Linux
root (hd1,0)
kernel /vmlinuz root=/dev/hdb1

“title”로 시작하는 줄은 말 그대로 제목이다. 이 곳에 적어 둔 내용이 부팅시에 메뉴에서 나타나게 된다.

root (hd1,0)

리눅스 커널이 위치하고 있는 파티션으로, “root”는 해당 파티션을 현재 GRUB의 루트 디바이스로 지정하는 명령어이다. 루트 디바이스로 지정된 파티션은 GRUB에 의해 마운트되서 해당 파티션에 있는 파일들을 읽어들일 수 있게 된다. 대부분의 경우 리눅스 루트 파티션이 이에 해당할 것이다. 필자의 경우 hda1을 리눅스 루트파티션으로 사용하고 있으므로 (hd0,0)라고 적어주었다.

kernel /vmlinuz root=/dev/hdb1

해당 파티션상의 커널의 위치이다. 예를 들어 커널이 “/boot/vmlinuz-2.4.3” 이라는 파일이라면 “kernel /boot/vmlinuz-2.4.3” 이라고 적어줘야 한다. 또, 필요한 커널 옵션이 있다면 그 뒤에 덧붙여 적어주면 된다. 만약 “/boot” 파티션을 따로 잡아서 사용하고 있다면 약간 주의해야 하는데, 그럴 경우 해당 파티션 상에서의 위치를 지정해 주는 것이므로 커널의 위치는 “/boot/vmlinuz-2.4.3”이 아니라 “/vmlinuz-2.4.3”로 적어줘야 한다.

많은 사람들이 윈도우와 리눅스의 멀티부팅을 원할 것이다. 좀더 아래로 내려가 보면 다음과 같은 내용이 있을 것이다.
# For booting Windows NT or Windows95
title Windows NT / Windows 95 boot menu
rootnoverify (hd0,0)
makeactive
chainloader  +1
# For loading DOS if Windows NT is installed
# chainload /bootsect.dos

“title”로 시작하는 줄은 앞에서 설명했듯이 제목을 나타내는 줄이다.

rootnoverify (hd0,0)

“rootnoverify”는 “root”와 비슷하지만 해당 파티션을 마운트하지 않는다. NTFS 파티션처럼 GRUB이 인식할 수 없는 파티션을 루트 디바이스로 지정할 때 사용된다.

makeactive

GRUB의 루트 디바이스를 부팅 가능한 파티션으로 지정한다. “makeactive” 명령어는 첫 번째 하드디스크의 프라이머리(Primary) 파티션에서만 사용할 수 있다.

chainloader  +1

“chainloader +1”은 “makeactive” 명령으로 부팅 가능하도록 지정된 파티션의 첫 번째 섹터부터 읽어들이기 시작해 부팅을 시작하도록 하라는 뜻이다. “makeactive” 명령이나 “chainloader +1” 명령의 경우 특별한 일이 없다면 편집할 필요가 없을 것이다. 윈도우로 부팅하는 메뉴를 만들고 싶다면 위에서 단지 “rootnoverify (hd0,0)” 부분을 윈도우가 설치되어 있는 파티션으로 변경해 주며 된다.

마지막으로 “menu.lst” 파일의 맨 아래쪽을 보면 다음과 같은 내용이 있을 것이다.
# For installing GRUB into the hard disk
title Install GRUB into the hard disk
root    (hd0,0)
setup  (hd0)

# Change the colors.
title Change the colors
color light-green/brown blink-red/blue

GRUB을 하드디스크의 마스터 부트 레코드에 인스톨하기 위한 메뉴와 색깔을 바꾸어 주는 메뉴이다. 여기서는 잠시 후에 “grub-install” 이라는 명령어를 사용하여 인스톨 할 것이므로 위쪽의 내용은 필요하지 않다. 또, 색깔을 바꾸는 메뉴를 만들 경우 처음부터 해당하는 색깔이 적용되는 것이 아니라 메뉴를 선택해야 색깔이 바뀐다. 대부분의 사람들은 이렇게 하는 것 보다는 처음부터 원하는 색깔로 나오도록 하고 싶어할 것이다. 처음부터 원하는 색깔로 나오게 하려면 파일의 앞 부분에 다음과 같이 적어주면 된다.

color [글자색]/[배경색] [선택된글자색]/[선택된배경색]

글자 색과 배경색에 모두 사용 가능한 색깔은 black, blue, green, cyan, red, magenta, brown, light-gray 이고, dark-gray, light-blue, light-green, light-cyan, light-red, light-magenta, yellow, white는 글자 색에만 사용할 수 있다.

앞에서 설명한 부분 이외의 부분은 대부분의 사람들에게는 필요하지 않을 것이다. 그냥 삭제해 버리거나 주석 처리해 버리도록 한다. 이제 파일을 저장하고 편집기를 빠져 나와 “grub-install /dev/hda”를 실행한다. 다음 비슷한 메시지가 나온다면 GRUB이 성공적으로 첫 번째 하드디스크의 마스터 부트 레코드(MBR)에 설치된 것이다.
# grub-install /dev/hda
/usr/sbin/grub-install: -e: command not found
/usr/sbin/grub-install: -e: command not found
/usr/sbin/grub-install: -e: command not found
/usr/sbin/grub-install: -e: command not found
Installation finished. No error reported.
This is the contents of the device map /boot/grub/device.map.
Check if this is correct or not. If any of the lines is incorrect,
fix it and re-run the script `grub-install’.

(fd0)  /dev/fd0
(hd0)  /dev/hda
(hd1)  /dev/hdb
#

자 부트로더의 설치가 끝났다. 이제 시스템을 재부팅 시켜보자.

4. 메뉴 인터페이스
다음과 같은 화면이 나온다면 성공이다.
  GRUB  version 0.5.96.1  (639K lower / 129984K upper memory)

┌─────────────────────┐
│        Debian GNU/Linux 2.2                      │
│        Windows NT 4.0 Server                    │
│                                                              │
│                                                              │
│                                                              │
└─────────────────────┘
Use the ↑ and ↓ keys to select which entry is highlighted.
Press enter to boot the selected OS, ‘e’ to edit the commands before booting, or ‘c’ for command-line.
The highlighted entry will be booted automatically in 15 seconds.

자, 이제 화살표 키를 이용해 메뉴를 선택하면 부팅 될 것이다. 아무것도 선택하지 않을 경우 화면 맨 아래의 숫자가 0이 되면 자동으로 지정해둔 운영체제로 부팅이 될 것이다. 또, 메뉴에서 ‘e’를 누르면 직접 그 메뉴를 편집할 수 있다. 어떤 한 가지 항목을 선택하고 그 상태에서 ‘e’를 눌러보자. 화면에 “menu.lst” 파일에 적어두었던 내용이 그대로 나올 것이다. 화살표 키를 이용해 편집하고 싶은 줄로 이동한 후 다시 ‘e’를 누르면 다음과 같이 편집할 수 있는 화면이 나타날 것이다.

grub edit> kernel /boot/vmlinuz-2.4.3 root=/dev/hda1
언제든지 ‘Esc’를 누르면 편집 내용이 취소된다. 원하는대로 편집한 후 엔터키를 누르면 편집한 내용이 적용될 것이다. 또, ‘o’ 키를 이용해 줄을 하나 더 추가하거나 ‘d’를 이용해 선택된 줄 전체를 삭제할 수 있다. 편집이 끝난 후 ‘b’ 키를 누르면 편집한 내용대로 부팅이 된다. 이 기능은 싱글 모드로 부팅할 때처럼 커널 옵션을 추가해야 할 경우 편리하게 사용할 수 있다.

5. 커맨드라인 인터페이스
지금까지 설명한 내용만으로도 GRUB을 사용하여 리눅스로 부팅하는 것에는 아무 문제가 없을 것이다. 그러나 GRUB의 커맨드라인 인터페이스를 이용해 보지 않고는 그 막강함을 느낄 수 없다. 메뉴에서 ‘c’를 누르면 다음과 같이 GRUB의 프롬프트가 나타날 것이다.
  GRUB  version 0.5.96.1  (640K lower / 3072K upper memory)

[ Minimal BASH-like line editing is supported. For the first word, TAB lists possible command completions.  Anywhere else TAB lists the possible completions of a device/filename.  ESC at any time exits. ]

grub>

GRUB의 커맨드라인 인터페이스는 bash처럼 ‘Tab’ 키를 이용한 자동완성 기능을 지원하고, 키 바인딩 또한 비슷하다. ‘Tab’ 키를 누르면 다음과 같이 현재 사용가능한 명령어가 나타날 것이다. 또, 메뉴로 돌아가고 싶을 때에는 ‘Esc’ 키를 누르면 된다.

grub> 
Possible commands are: blocklist boot cat chainloader cmp color configfile debug displaymem embed find fstest geometry halt help hide impsprobe initrd install ioprobe kernel lock makeactive map module modulenounzip partnew parttype pause read reboot root rootnoverify savedefault serial setkey setup terminal testload unhide uppermem

grub>

또, ‘help’ 명령어를 이용하여 특정 명령어의 사용법을 알아볼 수 있다.
  grub> help makeactive
makeactive: makeactive
Set the active partition on the root disk to GRUB’s root device.
This command is limited to _primary_ PC partitions on a hard disk.

grub>


재미있는 명령어가 몇 가지 있는데, 그 중 하나가 ‘cat’ 이다. 다음과 같이 입력해 보자.

grub> root (hd0,0)
Filesystem type is reiserfs, partition type 0x83

grub> cat /etc/shadow

패스워드 파일이 그대로 화면에 출력될 것이다. 즉, ‘root’와 ‘cat’ 명령어를 적당히 이용하면 어떤 파일이라도 내용을 볼 수 있다. 그러면 보안에 문제가 있지 않을까? LILO처럼 GRUB에서도 패스워드를 걸어 둘 수 있다. “menu.lst” 파일의 적당한 위치에 다음과 같은 줄을 추가하고 ‘grub-install’을 다시 실행하면 부팅시 ‘p’를 누르고 패스워드를 입력해야 메뉴를 편집하거나 커맨드라인 인터페이스를 이용할 수 있다.

password [패스워드]

또, 명령어들을 적당히 이용하면 하드디스크 상의 어떤 커널이라도 이용해서 부팅할 수 있다. 앞에서 “menu.lst” 파일에 적어주었던 내용들도 사실은 GRUB의 명령어들이다. 커널을 다시 설치한 후 부팅에 실패했을 때, lilo의 경우 대책을 세워놓지 않았다면 복구하기 위해 머리를 좀 굴려야 하지만 GRUB의 경우 예전 커널이 하드디스크 어딘가에 들어있기만 하다면 다음과 같이 입력해서 그 커널로 간단히 부팅할 수 있다.

grub> root (hd0,0)
Filesystem type is reiserfs, partition type 0x83

grub> kernel /boot/vmlinuz-2.4.3
[Linux-bzImage, setup=0xa00, size=0xb20b7]

grub> boot
Uncompressing Linux... Ok, booting the kernel.
...

다른 여러가지 명령어들의 용도와 사용 방법은 ‘help’를 이용하여 알아볼 수 있으므로 여기까지만 설명하고 넘어가도록 하겠다.

6. 응급 부팅디스크 만들기
만약 GRUB이 인스톨된 플로피 디스크가 한 장 있다면 새 커널을 컴파일하거나 파일시스템을 변경할 때 훨씬 마음이 든든할 것이다. 이제 GRUB 응급부팅디스크를 한 장 만들어 보기로 하자.

우선 비어있는 디스켓 한 장을 준비해 ext2 파일시스템으로 포맷한다.

# mke2fs /dev/fd0

그리고 나서 마운트하고 “boot”라는 디렉토리를 만들어 그곳에 커널을 복사한다.

# mount -t ext2 /dev/fd0 /floppy
# mkdir /floppy/boot
# cp /boot/vmlinuz-2.4.3 /floppy/vmlinuz

마지막으로 “boot” 라는 디렉토리 안에 “grub” 디렉토리를 만들고 그 안에 앞에서 “/boot/grub” 디렉토리에 복사했던 파일들을 그대로 복사한다.

# mkdir /floppy/boot/grub
# cp /boot/grub/* /floppy/boot/grub

이제 플로피디스크로 복사한 “menu.lst” 파일을 좀더 쓰기 편하도록 편집해야 한다. 필자의 경우 다음과 같이 편집했다.

# GRUB 응급부팅디스크

color black/cyan white/blue
timeout 30
default 1
fallback 0

# 플로피에 있는 커널로 리눅스 부팅하기

title Boot Debian GNU/Linux from Floppy Disk
root (hd0,0)
kernel (fd0)/boot/vmlinuz-2.4.2

# 하드에 있는 커널로 리눅스 부팅하기

title Boot Debian GNU/Linux from Hard Disk
root (hd0,0)
kernel (hd0,0)/boot/vmlinuz-2.4.2

# 하드의 첫번째 파티션으로 부팅하기

title Boot from the First Partition of Hard Disk
rootnoverify (hd0,0)
makeactive
chainloader +1

# 하드의 두번째 파티션으로 부팅하기

title Boot from the Second Partition of Hard Disk
rootnoverify (hd0,1)
makeactive
chainloader +1
# 하드의 세번째 파티션으로 부팅하기

title Boot from the Third Partition of Hard Disk
rootnoverify (hd0,2)
makeactive
chainloader +1

# 하드의 네번째 파티션으로 부팅하기

title Boot from the Fourth Partition of Hard Disk
rootnoverify (hd0,3)
makeactive
chainloader +1

편집이 끝난 후 파일을 저장한 후 쉘 프롬프트에서 “grub”을 입력하면 GRUB의 커맨드라인 인터페이스에서와 비슷한 프롬프트가 나타날 것이다. 다음과 같이 입력해 플로피디스크에 GRUB을 설치한다.

# grub
grub> root (fd0)
grub> setup (fd0)
grub> quit
#

이제 만들어진 디스켓을 이용해 부팅 해 본다. 제대로 부팅이 된다면 이제 디스켓을 안전한 곳에 보관하면 된다.

7. 맺음말

막강한 부트로더인 GRUB의 사용 방법을 알아보았다. 모든 것이 그렇듯이 GRUB에도 장점만 있는 것은 아니다. 먼저, 윈도우 등 “chainloader”를 사용해야 하는 운영체제가 첫 번째 하드디스크 외의 다른 하드디스크, 예를 들어 “hdb”에 설치되어 있을 경우 GRUB을 사용해서는 이 운영체제로 부팅할 수 없다. 다음으로, 플로피 디스크나 CD-ROM 부팅을 지원하지 않는다. 마지막으로 다른 부트로더에 비해 덩치가 상당히 크다. 특히 GRUB 플로피디스크를 이용하여 부팅할 때에는 stage2가 로드되는 동안 GRUB 자체를 부팅하는 듯한 느낌이 들 정도다.

그러나 몇 가지 단점에도 불구하고 GRUB의 막강한 기능 때문에 필자는 이제 LILO를 버리고 GRUB만을 사용한다. 여러분들도 막강한 부트로더 GRUB을 한번 사용해 볼 것을 추천한다.

댓글목록

등록된 댓글이 없습니다.

1,139 (14/23P)

Search

Copyright © Cmd 명령어 18.220.200.197