Up and Running with Arch Linux on VirtualBox
Intro
In this tutorial, I will walk you through what is needed to get up and running
with Arch Linux on VirtualBox with EFI disabled using a BIOS/GPT partitioning scheme and GRUB as the bootloader.
If you are installing on bare metal, using an EFI motherboard (or a VM with EFI enabled), or would like to use a different partitioning scheme, these instructions won’t work 100%, although you may still get value out of the parts that are consistent with your specific setup.
I provide explanation for each command in this blog, but if you just want a list of the raw commands, you can just go to this gist to get them.
tl;dr Please bring up mistakes, typos, or thoughts in the comments. I’m putting this out there for others for the benefit of others AND my own edification. I fully expect to be wrong, but I like to be corrected so I can eventually be less wrong.
Obligatory Explanatory Section
“Why Arch Linux?” you may ask. (Or you may not, in which case just skip to the start. I promise there’s nothing technical until then.)
Well…
There comes a time in every Linuxer’s life when the taunting temptation of Arch Linux overwhelms their better judgement. A time when they convince themselves that, yes, they definitely need to spend several weekends learning about and installing a distribution which, after countless hours of toiling over system config files and failed partition attempts, will include virtually nothing they need to do anything useful with their device.
What do you get in exchange for the extra effort? Control and transparency.
Linux distributions are inherently more lightweight than their Windows or Mac counterparts. However, the more popular distributions still manage to cram in a healthy amount of bloatware — the Amazon app is a good case-in-point. At best, you don’t use it, and at worst, it consumes valuable system resources that could be going to running the software you actually want to run. Even if you manage to find a good distro that’s light on bloatware, chances are it comes with a Desktop Environment complete with all the unnecessary folders you’ll never use.
With Arch Linux, you’ll pick exactly what you want on your system. I chose to use a Tiling Window Manage in place of a Desktop Environment, which cuts my system down to the absolute bare minimum I need. Especially when running inside a Virtual Machine, it’s nice to have as small a footprint as possible.
Alright, enough explanation, let’s dive in.
Prereqs
I’m assuming you have Oracle’s VirtualBox installed, and that you’ve downloaded and verified the appropriate Arch Linux image.
These instructions were developed using VirtualBox 5.2.6 and the archlinux-2018.02.01-x86_64.iso.
Virtual Machine Prep
In VirtualBox, create a new Virtual Machine for your Arch Linux adventure. For reference, here are my specs:
- 4GB RAM
- 60 GB dynamically allocated storage on a VHD
Create Virtual Machine — RAM and Disk Selection
From the main VirtualBox window, select “New” in the upper-left to create a new virtual machine.
Adjust the RAM to your desired amount, and choose a ‘Hard disk’ option — typically you want to ‘Create a virtual hard disk now’.
4GB of RAM is overkill for Arch Linux, the minimum required is only 512MB. However, I am intending to install a Window Manager later on, and I intend to run Python applications. I also have 16GB on my host machine. This is how I arrived at 4GB, but as little as 1GB should be fine.
It is also important to note that this setting is extremely easy to update. All you need to do is shut down your VM, adjust the setting, and boot it back up.
Create Virtual Hard Disk
Select your preferences for your new Virtual Hard Disk.
I chose VMDK based on this StackExchange post.
Dynamically allocated is pretty much a given. This option will allow VirtualBox to only allocate the space that is needed for the hard disk. So if your system only takes up 5GB of space, that will be it’s footprint on your physical hard disk, even if the size is 60GB. This makes the ‘File size’ more of a ceiling.
With version 5.2.6, VirtualBox now supports adding size to Hard Disks via the “Global Tools” dialog. So, similar to RAM, getting this exactly right at first is not that important as you’ll be able to resize it later. Note that VirtualBox only allows resizing to a larger size.
System Settings
Ensure the ‘Optical’ disk is at the top of the ‘Boot Order’, and ensure the ‘Enable EFI (special OSes only)’ option is unchecked.
Insert Arch Linux .iso
From the ‘Storage’ sub-menu, insert your archlinuix-yyyy-mm-dd-x86.iso disk into the optical drive. Do this by selecting the disk under ‘Controller: IDE’ (this will say ‘Empty’ at first) and then select the disk with the arrow on the far right and browsing to your .iso on your filesystem.
Boot the VM
Go ahead and boot your VM. You should see screen like this:
Just hit enter to accept the first option and boot into Arch Linux.
Hard Disk Partitioning
We’ll be creating a simple partition table with the minimum amount of partitions required to install Linux on our VM. The partition table will look like this:
/dev/sda1, boot partition with 512M
/dev/sda2, BIOS boot (hex code EF02) with 1M
/dev/sda3, root partition with the remainder
tl;dr there are many many ways to partition your hard drive and I encourage you to learn as much about it as you can. For my first time installing Arch Linux, I wanted the simplest possible layout so I could focus on getting up and running.
If you’ve been reading other partitioning guides, which you should, you may notice I don’t have a swap partition. Yes, this is intentional. Yes, you probably should have a swap. Again, I’m going with the bare minimum. Instead of a swap, I gave myself more RAM than I should need given the minimal applications I’m installing.
Run lsblk
to list the hard disks.
root@archiso ~ # lsblk
NAME MAJ:MIN RM SIZE R0 TYPE MOUNTPOINT
loop0 7:0 0 432M 1 loop /run/archiso/airootfs
sda 8:0 0 60G 0 disk
sr0 11:0 1 539M 0 rom /run/archiso/bootmnt
Note the 60G disk. Mine is labeled sda
. This is likely what yours will be called, but it’s still a good idea to confirm using lsblk
.
Use gdisk
to create a new partition table.
Enter the command gdisk /dev/sdx
, replacing x
with the appropriate drive letter. In my case this was a
.
root@archiso ~ # gdisk /dev/sda
GPS fdisk (gdisk) version 1.0.3Patition table scan:
MBR: not present
BSD: not present
APM: not present
GPS: not presentCreating new GPT entries.Command (? for help):
Boot partition
Enter the command n
to create a new partition, then just hit enter to accept the default for the partition number and first sector.
Command (? for help): n
Partition number (1-128, default 1):
First sector (34-125829086, default = 2048) or {+-}size{KMGTP}:
For the last sector, enter +512M
to create 512 Megabyte partition.
Last sector (2048-125829086, default = 125829086) or {+-}size{KMGTP}: +512M
For Hex code or GUID, hit enter to accept the default ‘Linux filesystem’.
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):
BIOS Partition
The BIOS partition is an interesting artifact of the fact that we are installing GRUB to a GPT partition table on a non-EFI motherboard. If you want a deeper explanation, check out this page from the GRUB documentation.
Now to create the partition.
Again, enter n
and accept the default for partition number and first sector. This will set you up with your second partition and start it right after the first.
Command (? for help): n
Partition number (2-128, default 2):
First sector (34-125829086, default = 1050624) or {+-}size{KMGTP}:
For the last sector, enter +1M
to create a 1 Megabyte partition.
Last sector (1050624-125829086, default = 125829086) or {+-}size{KMGTP}: +1M
For Hex code or GUID, enter EF02
to create a BIOS partition for GRUB.
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): EF02
Changed type of partition to 'BIOS boot partition'
Root Partition
Enter n
to create a new partition. And accept all defaults to create a ‘Linux filesystem’ partition at the end of the partition table that uses the remaining available space.
Command (? for help): n
Partition number (3-128, default 3):
First sector (34-125829086, default = 1052672) or {+-}size{KMGTP}:
Last sector (1052672-125829086, default = 125829086) or {+-}size{KMGTP}:
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300):
Changed type of partition to 'Linux filesystem'
Enter p
to see the partition table, it should look something like this:
Finally, enter w
to write the results, and then q
to exit gdisk.
Format Partitions
At this point we have a hard disk with three partitions, but they have not yet been formatted. We need to format them before we can install Arch Linux. This step is fairly simple.
Enter the following to format the partitions created in the previous step:
mkfs.ext4 /dev/sda1
mkfs.ext4 /dev/sda3
mkfs
is the “make filesystem” command. The dot notation for the specific filesystem is a shortcut for the -t
or --type
flag, e.g. mkfs -t ext4 /dev/sda1
.
You’ll notice we don’t touch /dev/sda2
. More on that later.
Mount Partitions
Now to mount the partitions. It took me some time to really grasp what was going on in this step, so I’ll include a little extra explanation.
When you booted into Arch Linux in step 1, you booted into a version of Arch Linux ON the optical drive in the VM. From that drive you were able to access, partition, and format the main hard disk in the VM. Now, in order to actually install Arch Linux to that hard disk, you’ll need to make the hard disk accessible to the Arch Linux instance running on the optical drive by mounting it’s partitions.
Run the following to mount the partitions.
mount /dev/sda3 /mnt
cd /mnt
mkdir boot
mount /dev/sda1 boot
It is convention in Linux to use /mnt as the directory to mount external media, so we mount sda3 (our root partition) to the /mnt directory. Once mounted, we change directory into the newly mounted device and create a boot folder. Within this folder, we mount the boot partition.
Install Arch Linux
A Note on Mirrors
Arch Linux is distributed with a mirrorlist
file in /etc/pacman.d
. This file contains a long list of mirrors which are used to download packages for any pacman
call as well as for the below pacstrap
command used to perform the installation. The file is traversed top-to-bottom, so it is a good idea to organize the file to have the closest (lowest latency) mirrors ranked highest.
Fortunately, Arch Linux comes with a rankmirrors
command which can be used to — wouldn’t you know — rank the mirrors. To call it, first create a backup, then execute, like so:
cp /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.backup
rankmirrors -n 10 /etc/pacman.d/mirrorlist.backup > /etc/pacman.d/mirrorlist
Note that what this is doing is testing every mirror in mirrorlist
and measuring the latency, then rewriting the file to put the mirrors in the correct order. So it will take several minutes to execute. However, the improvement in download times makes it well worth the wait.
Actual Installation
Now for the actual installation of Arch Linux onto your newly partitioned hard disk. This part is actually very simple, run:
pacstrap -i /mnt base base-devel
This runs pacstrap on the /mnt directory — which is where we mounted our root partition. It installs the base
and base-devel
packages of Arch Linux.
When prompted, accept the default (all) for both packages. This part takes a while as everything is download, unpacked, and installed to your system.
Generating the fstab File
Arch Linux has been installed, but our system will not know where to find it without an fstab file. To generate, run:
genfstab -p /mnt >> /mnt/etc/fstab
You can check the output with:
more /mnt/etc/fstab
You should see something like this.
Setup and Configuration
Arch Linux prides itself on the amount of customization it provides. I won’t get into all the possibilities, but there are a few things you should take care off right off the bat to give yourself a usable system.
Before doing any of these, we need to “chroot” or “change root” from the Live CD to the actual system we just installed.
arch-chroot /mnt
From now on, you may notice we don’t need to prepend /mnt
to all out commands involving the filesystem. This is because we have changed our root to be that /mnt
directory.
System Timezone
First things first, let’s set the timezone. In Arch Linux, this is done by creating a symbolic link in /etc/localtime
that points to the correct timezone in /usr/share/zoneinfo/
. To set it to your timezone, you must find the continent/city combination that represents your specific timezone.
For me, the command ended up looking like this.
ln -sf /usr/share/zoneinfo/America/Los_Angeles /etc/localtime
Language
Next, we need to tell Arch Linux what language we prefer. To do this, we’re going to edit two files, locale.conf
and locale.gen
. Arch Linux comes with the simple text editor nano
so we’ll use that to make our edits. Enter the following to open locale.conf
in nano
.
nano /etc/locale.conf
The file will be blank at first. Add the following line to the file.
LANG="en_US.UTF-8"
Close the file using Ctrl+x
. You will be prompted whether or not to save the modified buffer, enter y
for yes, then press enter to save to locale.conf
.
Next, open locale.gen
and uncomment (remove the #
from) the lines for en_US.UTF-8 UTF-8
and en_US ISO-8859-1
.
nano /etc/locale.gen
In nano
you can search for text using Ctrl+w
which should help you find those lines.
To implement these changes, run the following
locale-gen
Hostname
Next, name your computer. This name, the hostname, is visible to other computers on your local area network. It can also be referenced to give you a cool bash shell prompt. Call it anything you want, just make sure the name has no spaces. I called mine arch-linux
.
nano /etc/hostname
Password
Run the following and follow the prompts to update the root
user’s password.
passwd
Bootloader
If you’ve tried messing around with Arch Linux unsupervised, you may have seen this message before.
FATAL: No bootable medium found! System halted.
I saw it several times before figuring out what I did wrong. Well, if we were to reboot right now, this is exactly what we would see. The message gives us a hint as to why.
MBR on a GPT System
Given the way we’ve set up our system, the first thing our VM will do when it first boots up will be to check the Master Boot Record (MBR). This is referred to as Stage 1 of the boot process. Stage 2 in our case will be to load GRUB, but we haven’t installed GRUB yet, and the MBR has not been updated to point to GRUB, so if we were to reboot at this point the system would not find a bootloader to boot into thus resulting in the above message.
Now, the MBR is actually considered legacy. It is included in GPT partition schemes for backwards compatibility. However, because we are installing on a BIOS-base system (i.e. non-EFI) we are making use of this legacy feature.
You may have noticed we did not format the second partition /dev/sda2
earlier. But we did give it a special code — EF02
. When we install GRUB, it will look for this partition to install it’s core.img.
To learn more, I highly recommend the Wikipedia page on the subject, it’s very enlightening.
GRUB Installation
Explanation aside, here’s what commands to run.
pacman -S grub
grub-install --target=i386-pc /dev/sda
grub-mkconfig -o /boot/grub/grub.cfg
This installs grub to your system via pacman, installs grub on your hard disk, and creates the grub configuration file in the boot directory. I’ve accepted all the defaults, which works just fine for this basic installation.
Unmount and Reboot
We’re almost done.
Exit back out to the Live CD and unmount the partitions.
exit
umount /mnt/boot
cd ..
umount /mnt
Shutdown the machine so you can remove the Arch Linux Live CD.
shutdown now
Remove the virtual CD and start the VM again. If everything worked, you should be presented with a prompt that looks something like the screen below, your login will be root
and the password will be whatever you set it to at the end of step 6.
And that’s it. If you got to the screen above, congrats! You’ve successfully installed Arch Linux. It doesn’t do much at this point, but this is where the real fun starts.
Next steps
Stay tuned for my follow-up post where I’ll go through making the system truly usable as a development machine, including.
- Enabling internet
- VirtualBox Guest Additions
- Creating a non-root user
- Enabling auto-login
- Installing a minimal window manager
Credits
The development of this tutorial would not have been possible were it not for the many other guides out there that I was able to partially follow to piece this together. Specifically, I’d like to reference:
- A Guide to Installing Arch in VirtualBox — Josh Braun
- arch linux for dummies — Jiéverson
- Arch Linux Quick Installation with GPT in BIOS — m157q
- Arch Linux EFI Install Guide — GloriousEggroll
In particular, Josh Braun’s guide was extremely helpful. The explanations he provided for many of the commands were as thorough as they were accurate.