운영체제 개발 – GRUB 부팅과정

그럼 실제로 어떻게 되는지를 보여주기 전에, GRUB이 운영체제 커널을 어떻게 부팅하는 지 좀 정리해서 적어보려고 한다. 일단 아주 간단한 과정에 대해서 정리를 해보면 다음과 같다.

  1. 바이오스가 부팅 장치를 찾고 MBR(Master Boot Record)를 읽어온다.
  2. MBR에 GRUB 스테이지 1이 있으며, GRUB 스테이지 1은 스테이지 1.5나 2를 불러온다.
  3. 스테이지 1.5는 MBR 직후 30킬로바이트 영역에 저장되며 이는 스테이지 2를 불러온다.
  4. GRUB 스테이지 2는 부트 메뉴나 명령 프롬프트를 실행하고 보여준다.
  5. 기본 값으로 지정된 커널이나 사용자가 선택한 커널을 메모리에 적재시켜서 커널 엔트리를 실행한다.

이 정보가 GRUB에 대한 위키피디아 내용을 정리한 것이다. MBR에 대한 설명을 간단하게 적으며, MBR은 저장매체의 첫 번째 섹터를 바이오스가 메모리로 읽어들인다. 그 후에 읽어들인 부트 코드로 제어권이 이양되어 코드가 실행되도록 해주는 녀석이다. 자세한 건 운영체제 이론쪽을 보면 될 것이고, 저는 일단 이렇게 간단하게 요약해서 설명합니다.

하드 디스크에는 논리적으로 여러 개의 하드 디스크(파티션이라고 한다)로 나눠서 쓸 수 있다. 최초 컴퓨터가 부팅된 후 MBR에서 부팅 가능한 논리 하드 디스크를 조회하고 부팅 가능한 논리 하드 디스크가 있을 경우에는 해당 논리 디스크의 부트 섹터를 찾아서 메모리로 읽어오고 그 부트섹터의 코드를 실행하게 된다.

이게 윈도우 운영체제인 경우에는 부트섹터는 Ntldr이라는 커널 로더를 메모리에 적재시키며 제어권을 Ntldr에 이양한다. Ntldr은 커널의 코어와 파일시스템 관련 시스템 파일을 로드해서 운영체제를 가동시키며 커널 코어와 파일 시스템은 시스템 자원을 활용하기 위해 여러 커널 모듈을 동적 또는 정적으로 로드시켜 운영체제를 실행하면서 유저 어플리케이션의 요청에 대응하게된다. (이 내용은 윈도우 시스템 관련 내용에 나와있습니다.)

Windows NT 계열의 운영체제 부트 과정을 그림으로 정리…. 이러면 쉬운데…;ㅅ;

부트로더의 존재를 통해서 커널에 어떻게 보여주는지를 정리하기 위해 윈도우를 기준으로 설명을 먼저 해봤습니다.

GRUB을 통한 리눅스를 어떻게 이용한 방식으로 이야기를 하면, GRUB은 부팅 후 Ntldr 까지의 역할을 GRUB이 실행한다고 보면 된다. 운영체제가 설치된 환경이 하드 이스크던, 시디던, USB던 상관 없다. 한편 우리가 제작할 운영체제의 커널은 GRUB 덕분에 Ntoskrnl.exe 같은 커널 프로세스에만 집중하면 된다. 즉, 커널을 메모리에 적재하는 과정을 구현하지 않아도 된단 것이다!!!! 이건 이전 글에도 작성했지만 운영체제 개발에 있어서 큰 부분을 덜어주는 것이다.

중요한 거니 두번 적습니다. \ㅇㅅㅇ/

그럼 GRUB은 어떻게 되는지를 또 그려서 보여줍니다.

바이오스는 부트 섹터에 기록된 boot.img 512바이트를 메모리에 적재한 뒤 제어권을 넘긴다. (이 과정이 스테이지 1) boot.img 파일은 스테이지 2에 해당하는 core.img를 메모리에 적재 해서 해당 코드를 실행하는데 여기서 menu.lst 파일이나 grub.cfg 설정 파일을 참고해서 커널 리스트를 가져온다. 그리고 커널을 선택해서 실행하면 GRUB은 커널을 메모리에 적재시킨 뒤 커널 엔트리 포인트에 제어권을 넘기고 자신의 일부를 종료해서 일을 끝낸다.

GRUB 같은 경우에는 버전이 1.0과 2.0이 있는데, 1.0대 버전에는 위의 설명과 같이 menu.lst 파일을 사용한다. 근데 2.0에서는 그냥 grub.cfg에서 다 처리한다. 근데 일단 그런 버전 차이에 상관없이 적고 싶어서 하다보니 위에처럼 정리가 되더라….

어려워…ㅠㅠ

이렇게 해서 GRUB을 통한 부팅 과정에 대한 설명을 정리했다. 커널 부팅에 대해서 오래된 자료들에 메모리의 어디 주소 영역을 찍어서 부팅하고 뭐하고 하는 그런 거 없어서 편하게 설명할 수 있었지만 이것도 제대로 다 보면 진짜 산더미만한 내용을 보게 될 것이다. 근데 규링이 만들 운영체제에서는 범용으로 부팅되는 과정에 대한 이해만 하고 제대로 넘기면 되니….ㅇㅂㅇ

이제 자세한 걸 만들어가면서 보여주려고 하는데…. 만들어봐야 할 것들이 있어서 그러니 좀 걸릴 것이다. ;ㅅ;

운영체제 개발 – GRUB

GRUB은 GNU 프로젝트의 부트로더이다. 대부분의 운영체제 커널을 불러올 수 있으며 우리가 제작한 커널 또한 호환되게 개발만 하면 호출할 수 있다. 뭐 이름과 유래에 대해서 내용이 있긴 한데 간단하게 그냥 GRUB도 우리가 운영체제를 부팅할 때 하드 디스크, 플로피, USB 등에 구애받지 않고 부팅 가능하도록 도와준다는 것이 제일 중요한 것이다.

GRUB 화면

이걸 제일 많이 볼 때가 있다면… 윈도우랑 리눅스 멀티부팅 해서 쓰는 분들이 제일 많이 볼 듯 하다. 아니면 여러 운영체제를 선택적으로 설치하거나 부팅해서 쓰기 위해서 자작으로 제작할 때에도 이용하기도 한다.

GRUB은 상용적으로 사용되는 운영ㅇ체제를 로드할 수 있을 뿐 아니라 개인이 자체 제작한 운영체제 커널도 규격에 맞추면 로드할 수 있는 능력을 가지고 있다. 그 능력에 대해서 살펴보면

  • 파일 시스템 직접 접근 기능
  • 다양한 실행 파일 형식 지원 기능
  • 비 멀티부팅 운영체제에 대한 지원
  • 메뉴 인터페이스 지원(부팅 화면)
    • 그래픽 메뉴 및 배경 그림도 사용 가능
    • 콘솔 인터페이스 지원
  • 다양한 파일 시스템 지원

이 정도가 된다. 우리가 순간적으로 그냥 보는 기능 안에 이렇게 많은 기능들이 들어있는 것이다. ㅇㅂㅇ

고마운 녀석입니다. ㅇㅅㅇ

직접 자작한 운영체제를 GRUB이랑 연동하였다면, GRUB은 직접 제작한 커널 파일이 유효한 커널인지 확인한 후 커널을 메모리로 적재한다. 또한 하드웨어 제반사항을 초기화한 후 커널 엔트리를 호출해서 제어권을 커널 코드로 이양할 것이다. 이 과정에서 GRUB은 커널에 하드웨어 초기화 정보를 넘겨준다. 이 과정을 아래와 같이 보면 이해가 쉬울 것이다. 조직도와 화살표 방향에 주목해서 글을 읽어보면 된다.

자바 가상 머신과 유사한 느낌으로 그려봤다. 근데 이렇게 보면 관계도 이해가 좀 더 쉽게 될 것이다.

그리고 당연한 이야기지만 GRUB을 통해서 커널을 메모리에 적재시켜서 실행시키고 싶다면 GRUB에서 요구하는 규격대로 만들어 줘야 한다. 이 내용을 작성하기 전에 GRUB 부팅에 대한 자세한 내용을 다음 글에서 작성하도록 하겠다.