Making an ISO
Now that we have our kernel.bin
, the next step is to make an ISO. Remember
compact discs? Well, by making an ISO file, we can both test our Hello World
kernel in QEMU, as well as running it on actual hardware!
To do this, we’re going to use a GRUB tool called grub-mkrescue
. We have to
create a certain structure of files on disk, run the tool, and we’ll get an
os.iso
file at the end.
Doing so is not very much work, but we need to make the files in the right places. First, we need to make three directories:
$ mkdir -p isofiles/boot/grub
The -p
flag to mkdir
will make the directory we specify, as well as any
‘parent’ directories, hence the p
. In other words, this will make an
isofiles
directory, with a boot
directory inside, and a grub
directory
inside of that.
Next, create a grub.cfg
file inside of that isofiles/boot/grub
directory,
and put this in it:
set timeout=0
set default=0
menuentry "intermezzOS" {
multiboot2 /boot/kernel.bin
boot
}
This file configures GRUB. Let’s talk about the menuentry
block first.
GRUB lets us load up multiple different operating systems, and it usually does
this by displaying a menu of OS choices to the user when the machine boots. Each
menuentry
section corresponds to one of these. We give it a name, in this
case, intermezzOS
, and then a little script to tell it what to do. First,
we use the multiboot2
command to point at our kernel file. In this case,
that location is /boot/kernel.bin
. Remember how we made a boot
directory
inside of isofiles
? Since we’re making the ISO out of the isofiles
directory,
everything inside of it is at the root of our ISO. Hence /boot
.
Let’s copy our kernel.bin
file there now:
$ cp kernel.bin isofiles/boot/
Finally, the boot
command says “that’s all the configuration we need to do,
boot it up.“
But what about those timeout
and default
settings? Well, the default
setting
controls which menuentry
we want to be the default. The numbers start at zero,
and since we only have that one, we set it as the default. When GRUB starts, it
will wait for timeout
seconds, and then choose the default
option if the user
didn’t pick a different one. Since we only have one option here, we just set it to
zero, so it will start up right away.
The final layout should look like this:
isofiles/
└── boot
├── grub
│ └── grub.cfg
└── kernel.bin
Using grub-mkrescue
is easy. We run this command:
$ grub-mkrescue -o os.iso isofiles
The -o
flag controls the output filename, which we choose to be os.iso
.
And then we pass it the directory to make the ISO out of, which is the
isofiles
directory we just set up.
After this, you have an os.iso
file with our teeny kernel on it. You could
burn this to a USB stick or CD and run it on an actual computer if you wanted
to! But doing so would be really annoying during development. So in the next
section, we’ll use an emulator, QEMU, to run the ISO file on our development
machine.