crossorigin="anonymous">
외과전담간호사의 조용한 복습시간

리눅스

리눅스 시스템 부팅 과정과 GRUB 이해하기

bluefrog 2025. 4. 26. 08:52

리눅스를 서버에 설치하고 쓸 때는 잘 못 느끼지만, 어느 날 갑자기 부팅이 안 되거나 GRUB 화면에서 멈췄을 때 진짜 당황하게 된다. 나도 예전에 커널 업데이트 후에 리부팅했더니 갑자기 검은 화면에 GRUB rescue 모드로 떨어져서 진짜 멘붕이 왔었다. 처음엔 ‘이거 하드디스크 나간 건가...?’ 싶었는데, 알고 보니 리눅스의 부팅 구조 자체를 제대로 몰라서 더 어렵게 느껴졌던 거였다. 그래서 오늘은 리눅스 시스템이 부팅될 때 어떤 순서로 진행되는지, 그리고 GRUB이 그 과정에서 어떤 역할을 하는지를 정리해보려고 한다.

리눅스 시스템의 부팅 과정은 생각보다 체계적이다. 처음엔 그냥 전원 켜면 OS가 알아서 올라오는 줄 알았는데, 실제론 여러 단계를 거쳐야 최종적으로 쉘 프롬프트나 GUI 화면까지 도달하게 된다. 그 흐름을 크게 나누면 아래 순서다.

1. BIOS/UEFI → 2. MBR 또는 EFI 파티션 → 3. 부트로더(GRUB) → 4. 커널 로딩 → 5. init(systemd)

하나씩 풀어보면 이렇다.
먼저 컴퓨터의 전원이 켜지면 제일 먼저 실행되는 건 BIOS 또는 UEFI다. 이건 하드웨어를 초기화하는 역할을 하고, 부팅 가능한 장치를 찾는다. 예를 들어 USB, SSD, 네트워크 같은 장치 중에서 우선순위에 따라 부트 가능한 영역을 찾는 거다.

그 다음 넘어오는 게 MBR(Master Boot Record) 혹은 EFI 시스템 파티션이다. 여기엔 부트로더가 들어있는데, 리눅스에서 가장 많이 쓰는 부트로더가 바로 GRUB다. 정확히 말하면 GRUB2가 최신이고, 대부분의 리눅스 배포판은 기본 부트로더로 GRUB2를 사용한다.

GRUB은 Boot Loader, 즉 커널을 메모리에 로드해주는 프로그램이다. 우리가 부팅할 때 가끔 보는 "GNU GRUB"이라는 화면이 바로 얘다. 거기서 커널 버전 선택하거나 리눅스 복구 모드 들어가는 것도 다 GRUB의 역할이다. GRUB은 /boot/grub/grub.cfg 같은 설정 파일을 읽어서, 어떤 커널을 부팅할지, 기본값은 뭔지, 타임아웃은 몇 초인지 등을 제어한다.

예를 들어 서버에서 커널을 여러 개 설치해놨을 때, GRUB 화면에서 "Ubuntu, with Linux 6.5.0" 같은 항목이 여러 개 나오는 것도 그런 설정 덕분이다. 타이밍 놓치면 자동으로 default 항목이 부팅되는데, 그건 설정 파일에서 정해진 값이다.
내가 예전에 부팅이 안 됐던 이유도 이 GRUB 설정이 꼬였기 때문이었다. /boot 파티션이 꽉 차서 최신 커널 설치가 제대로 안 됐고, GRUB이 잘못된 커널을 로딩하려다 실패했던 거다.

GRUB이 커널을 선택하고 메모리에 올리면, 그때부터 리눅스 커널이 실행된다. 이 시점부터는 본격적인 OS 영역이다. 커널은 하드웨어를 초기화하고, 디스크 마운트, 메모리 관리, 네트워크 등 시스템의 기반이 되는 역할을 한다.

그리고 마지막 단계가 init 또는 systemd다. 요즘은 대부분 systemd 기반으로 되어 있어서 /lib/systemd/systemd가 PID 1번 프로세스로 실행된다. 여기서 서비스들, 유닛들, 로그 시스템, 타겟(target) 등을 불러오면서 우리가 아는 리눅스 환경이 구성된다. nginx나 sshd, docker 같은 서비스들도 이 단계에서 실행된다. 그 후에야 로그인 화면이 뜨거나, GUI 환경이 켜지는 거다.

여기까지가 정상적인 부팅 시나리오인데, 문제는 GRUB에서 뭔가 꼬이면 리눅스까지 진입조차 못하는 상황이 생긴다는 거다. 이럴 때 화면에 grub rescue> 같은 프롬프트가 뜨는데, 이건 GRUB이 설정 파일을 찾지 못하거나, 커널 이미지가 없는 상태에서 나타나는 비상 모드다.

이 상황을 만나면 일단 현재 디스크 상태를 확인하는 게 우선이다. rescue 모드에서도 ls 명령어는 사용할 수 있어서, ls 치면 (hd0), (hd0,msdos1), (hd0,gpt1) 같은 파티션 리스트가 보인다. 그 중에서 루트 파일 시스템이 있는 파티션을 찾고, 거기에 /boot/grub 디렉토리가 있으면 거기가 우리가 원하는 대상이다.

간단하게 복구하려면 live USB로 부팅해서 chroot 환경을 만들고, GRUB을 다시 설치하는 게 일반적이다. 아래는 아주 많이 쓰이는 명령어 시퀀스다:

bash
복사편집
sudo mount /dev/sda1 /mnt sudo mount --bind /dev /mnt/dev sudo mount --bind /proc /mnt/proc sudo mount --bind /sys /mnt/sys sudo chroot /mnt grub-install /dev/sda update-grub

이걸로 부트로더를 다시 설치하고 grub 설정 파일을 갱신하면 대부분의 GRUB 문제는 해결된다. 나는 이걸 몇 번 하다 보니까 그냥 습관처럼 USB에 리눅스 복구 이미지 하나 꼭 들고 다니게 되더라.

그리고 하나 팁을 주자면, GRUB 설정 파일을 직접 건드릴 일이 생겼다면 /etc/default/grub을 수정하고, 항상 update-grub 명령어를 실행해야 실제로 /boot/grub/grub.cfg에 반영된다. 이거 까먹으면 아무리 설정 바꿔도 부팅에 반영 안 된다.

또 커널 여러 개 설치되어 있을 때, 특정 커널을 기본 부팅으로 고정하고 싶다면 /etc/default/grub에서 GRUB_DEFAULT=0을 바꾸면 된다. 숫자는 grub 메뉴에서 0부터 시작하는 인덱스다. 또는 GRUB_DEFAULT=saved 설정하고 grub-set-default 'Ubuntu, with Linux 6.5.0-10-generic' 같은 식으로 설정해도 가능하다.


정리하자면, 리눅스 부팅은 하드웨어 초기화 → 부트로더(GRUB) → 커널 로딩 → systemd 실행 순으로 이뤄지고, 그 중심엔 GRUB이 있다. 부팅이 꼬이면 대부분 GRUB 설정, 커널 이미지, /boot 파티션 문제인 경우가 많고, live USB + chroot + grub-install 조합으로 복구가 가능하다.

처음엔 복잡하게 느껴질 수 있지만, 한두 번 겪어보면 의외로 구조가 명확하다. 지금이라도 부팅 과정 한 번 정리해두고, 실수로 grub rescue 빠졌을 때 명령어 몇 개만 외워두면, 서버 하나쯤은 스스로 살릴 수 있다. 리눅스를 진짜 이해하려면, 부팅부터 보는 것도 중요한 포인트다.