LoginSignup
11
7

More than 5 years have passed since last update.

GRUB2から自作OSを起動する

Last updated at Posted at 2017-02-07

はじめに

ひさしぶりに30日でできる! OS自作入門を読み返しだした.
本ではフロッピーからOSを起動しているが,後々にUSBからOSを起動したいので,GRUBから自作OSの起動方法を調べてみた.

該当しそうな記事がいくつか見つかったので,参考に自分でも試してみた.

手元にある環境で試したので,開発環境は少し複雑で,自作OS開発はvagrant上のcentos 7で,自作OS(ISOファイル)の実行はホスト側(windows 10)のVirtual Boxで実施している.

作成手順

1. 自作OSのソースコードを作成する

GRUBから自作OSを起動するには,Multiboot Specificationの決まりに従って作成するとよいらしい.

1.1 multiboot.hをダウンロードする

https://www.gnu.org/software/grub/manual/multiboot/html_node/multiboot_002eh.html
作業フォルダのinclude/以下に保存する.

1.2 C言語を開始するためのアセンブラ部分を作成

load.S
#define ASM_FILE 1
#include "multiboot.h"
#define EXT_C(func) func
#define STACK_SIZE 0x4000
#define MULTIBOOT_HEADER_FLAGS 0x00000003

.text
.global start, _start

start:
_start:
        jmp     multiboot_entry
        .align  4

multiboot_header:
        .long   MULTIBOOT_HEADER_MAGIC
        .long   MULTIBOOT_HEADER_FLAGS
        .long   -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS)

multiboot_entry:
        movl    $(stack + STACK_SIZE), %esp
        pushl   $0
        popf
        pushl   %ebx
        pushl   %eax

        call    EXT_C(cstart)

loop:   hlt
        jmp     loop

        .comm   stack, STACK_SIZE

1.3 C言語の記述

boot.c
#include "multiboot.h"

void cstart(unsigned long magic, unsigned long addr)
{
        unsigned short *screen = (unsigned short *)0xb8000;
        char *msg = "Starting MyOS!";
        char ch;
        char attr = 0x0f;

        while (ch = *msg++) {
                *screen++ = ((attr) << 8) | ch;
        }
        return;
}

(このあたりは,ほぼLinuxをはじめよう!:1から創る自作OS 0x20のまま)

2. コンパイルするためのMakefileを作成する

Makefile
TARGET = myos.elf

CC = gcc
LN_S = ln -s
RANLIB = ranlib
INCLUDES = -I./include
FLAGS = -m32 -ffreestanding -fno-common -fno-builtin -fomit-frame-pointer -O2 -c
LD = ld  -melf_i386  -Ttext=0x100000 --oformat elf32-i386 -o

.S.o:
        ${CC} ${INCLUDES} ${FLAGS} $<
.c.o:
        ${CC} ${INCLUDES} ${FLAGS} $<

BOOT_S = load.S
BOOT_C = boot.c

BOOT_OBJ=${BOOT_S:.S=.o} ${BOOT_C:.c=.o}

all:    myos

myos:   ${BOOT_OBJ}
        ${LD} ${TARGET} ${BOOT_OBJ}

${BOOT_OBJ}:    ${BOOT_SRC}
clean::
        -${RM}  -f *~ *.lo *.o

(MakefileもほぼLinuxをはじめよう!:1から創る自作OS 0x30のまま)

$ makeを実行しelfファイルを作成する

3. 仮想マシンで動作確認をするためISOファイルを作成する

3.1 grub.cfgを作成する

grub.cfg
set timeout=0
set default=0

menuentry "MyOS" {
    multiboot /boot/myos.elf
    boot
}

multibootではなく,multiboot2 /boot/myos.elfだと実行時にerror: no multiboot header foundエラーがでた.

3.2 ISOファイルを作成する

$ mkdir -p isofiles/boot/grub
$ cp grub.cfg isofiles/boot/grub/
$ cp myos.elf isofiles/boot/
$ grub2-mkrescue -o os.iso isofiles/

grub2-mkrescue時に以下のエラーが発生した.
Your xorriso doesn't support '--grub2-mkrescue'. Some features are disabled. Please use xorriso 1.2.9 or later.
そこで,以下よりxorrisoをrpmでインストールした.
https://centos.pkgs.org/7/repoforge-x86_64/xorriso-1.3.6-1.el7.rf.x86_64.rpm.html

xorrisoのrpm -Uvh時に/usr/bin/wish is neededといったパッケージの依存関係エラーがでた.
以下を参考にyumでtk/tclをインストールすると解消できた.
(参考)http://www.realgeek.com/forums/usr-bin-wish-339946.html

4. VirtualBoxからGRUBを起動し動作を確認する

VirtualBoxから作成したISOファイル(os.iso)を読み込み開く.
(参考)http://softwaretechnique.jp/OS_Development/Grub/grub02.html

GRUB起動後,MyOSを選択し,Starting MyOS!が表示されるのを確認した.

11
7
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
11
7