Install Arch Linux on Windows 10 Hyper-V

A few months back, I upgraded my laptop to a new Microsoft Surface Book 2 that has all these nice features, like a detachable screen. My previous laptop and current desktop run Arch Linux as the main OS. My work is mostly done in the IDE Visual Studio Code or shell. VCS runs well on Windows 10, but shell, I don’t think I want to invest too much time in PowerShell and WSL is not exactly the best working environment for me.

I decided to deploy Arch Linux on a Windows Hyper-V virtual machine for my bash needs as I am not yet sure if I want to completely replace Windows as the main desktop on my Surface Book 2, since I still like the detachable screen and Windows 10 face authentication and the VR kit. Maybe, in the near future, I will deploy Arch Linux beside Windows 10.

This guide will walk you through how to install Arch Linux on Windows 10.

Requirements

Hyper-V Installation

Hyper-V has been included with Windows since Windows Server 2008 as well as Windows 8, 8.1, and 10 in the Pro versions. It can be enabled from the Control Panel at “Turn Windows features on or off” under “Programs and Features.” Activate the “Hyper-V” checkbox, apply the change, and follow the directions on the screen.

Network Configuration

First, you must configure a new virtual switch so that your virtual machine will be able to connect to the Internet. Once Hyper-V is enabled, start the Hyper-V Manager.

Configuration can be done in GUI by opening Power Shell as Administrator and running Hyper-V Manager:

mmc.exe virtmgmt.msc

Or we can use only PowerShell for the rest of the configurations.

Creating External Switch

Using PowerShell (run as Administrator)

Get-NetAdapter
New-VMSwitch -name ExternalSwitch  -NetAdapterName "Ethernet 3"  -AllowManagementOS $true

Create Virtual Machine in Hyper-V

$VMName = ‘ArchLinux’
$Switch = ‘ExternalSwitch’
$InstallMedia = ‘archlinux-2018.05.01-x86_64.iso’
$VMPath = ‘C:\Users\Public\Documents\Hyper-V\Virtual Hard Disks\’
$HOSTNAME = (Get-WmiObject -Class Win32_ComputerSystem -Property Name).Name
New-VM -Name $VMName -MemoryStartupBytes 4GB -Generation 2 -NewVHDPath “$VMPath\$VMName.vhdx” -NewVHDSizeBytes 128GB -Path “$VMPath” -SwitchName $Switch
Set-VM -Name $VMName -CheckpointType $false
Set-VMProcessor $VMName -Count 4
Set-VMMemory $VMName -DynamicMemoryEnabled $false
Set-VMFirmware $VMName -EnableSecureBoot Off
Add-VMDvdDrive -VMName $VMName -ControllerNumber 0 -ControllerLocation 1 -Path $HOME\Downloads\$InstallMedia
$DVDDrive = Get-VMDvdDrive -VMName $VMName
Set-VMFirmware -VMName $VMName -FirstBootDevice $DVDDrive
Start-VM -Name $VMName
VMConnect $HOSTNAME $VMName

Arch Linux Installation

Hyper-V does not allow clipboard COPY/PASTE; for this, we will use SSH into the VM. The latest Windows 10 Fall Creators Update includes an SSH client that can be installed following the guide from How-To Geek.

Once in Hyper-V Arch shell,

passwd
systemctl start sshd
ip a show dev eth0 | grep -w inet
ssh root@IP

Arch Installation Check and Initial Configuration

ls -la /sys/firmware/efi
Server = http://mirror.nus.edu.sg/archlinux/$repo/os/$arch
Server = https://mirror.0x.sg/archlinux/$repo/os/$arch
Server = https://download.nus.edu.sg/mirror/arch/$repo/os/$arch
Server = https://sgp.mirror.pkgbuild.com/$repo/os/$arch
Server = http://download.nus.edu.sg/mirror/arch/$repo/os/$arch
Server = http://mirror.0x.sg/archlinux/$repo/os/$arch
mv /etc/pacman.d/mirrorlist /etc/pacman.d/mirrorlist.bk
nano /etc/pacman.d/mirrorlist
sed -i ‘s/^#Server/Server/’ /etc/pacman.d/mirrorlist.bkrankmirrors -n 6 /etc/pacman.d/mirrorlist.bk > /etc/pacman.d/mirrorlist
Server = http://mirror.0x.sg/archlinux/$repo/os/$arch
Server = http://download.nus.edu.sg/mirror/arch/$repo/os/$arch
Server = http://mirror.nus.edu.sg/archlinux/$repo/os/$arch
Server = http://mirrors.evowise.com/archlinux/$repo/os/$arch
Server = http://f.archlinuxvn.org/archlinux/$repo/os/$arch
Server = http://mirror2.totbb.net/archlinux/$repo/os/$arch

Partitioning

dmesg | grep sdalsblk
gdisk /dev/sda
Command (? for help): o
This option deletes all partitions and creates a new protective MBR.
Proceed? (Y/N): Y
Command (? for help): n
Partition number (1–128, default 1):
First sector (34–268435422, default = 2048) or {+-}size{KMGTP}:
Last sector (2048–268435422, default = 268435422) or {+-}size{KMGTP}: +512M
Current type is ‘Linux filesystem’
Hex code or GUID (L to show codes, Enter = 8300): EF00
Changed type of partition to ‘EFI System’
Command (? for help): n
Partition number (2–128, default 2):
First sector (34–268435422, default = 1050624) or {+-}size{KMGTP}:
Last sector (1050624–268435422, default = 268435422) 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’
Command (? for help): p
Disk /dev/sda: 268435456 sectors, 128.0 GiB
Model: Virtual Disk
Sector size (logical/physical): 512/4096 bytes
Disk identifier (GUID): 7A0873FE-EA25–4CC1–8543–1559F4861C2B
Partition table holds up to 128 entries
Main partition table begins at sector 2 and ends at sector 33
First usable sector is 34, last usable sector is 268435422
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)

Number Start (sector) End (sector) Size       Code  Name
1      2048           1050623      512.0 MiB  EF00  EFI System
2      1050624        268435422    127.5 GiB  8300  Linux filesystem
Command (? for help): w
Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!
Do you want to proceed? (Y/N): Y
OK; writing new GUID partition table (GPT) to /dev/sda.
The operation has completed successfully.

Format Partitions

mkfs.fat -F32 /dev/sda1
mkfs.ext4 /dev/sda2

Mount Partition

mount /dev/sda2 /mntmkdir /mnt/bootmount /dev/sda1 /mnt/boot

Start Installation

timedatectl set-ntp true
pacstrap /mnt base base-devel openssh
genfstab -U /mnt >> /mnt/etc/fstab
arch-chroot /mnt
bootctl install

Configure bootctl Loader

nano /boot/loader/loader.conf

default arch
timeout 3
editor 0
blkid -s PARTUUID -o value /dev/sda2

Note down PARTUUID nr Ex. 55523bad-38db-4e00–8cdb-d498e47f0b05

cp /usr/share/systemd/bootctl/arch.conf /boot/loader/entries/


nano /boot/loader/entries/arch.conf

title Arch Linux
linux /vmlinux-linux
initrd /initramfs-linux.img
options root=PARTUUID=8444d6ba-32af-415b-b148-cf4f20a04ac9 rw
echo “options root=PARTUUID=$(blkid -s PARTUUID -o value /dev/sda2) rw” >> /boot/loader/entries/arch.conf
bootctl update
bootctl

Arch Linux Post-Installation Configuration

nano /etc/locale.gen

en_US.UTF-8 UTF-8
locale-gen
locale -a
localedef — list-archive
localectl list-locales
nano /etc/locale.conf

LANG=en_US.UTF-8
localectl set-locale LANG=en_US.UTF-8
ls -la /usr/share/zoneinfo/
ln -sf /usr/share/zoneinfo/Asia/Singapore /etc/localtime
hwclock — systohc
hostnamectl set-hostname Arch
nano /etc/ssh/sshd_config

PermitRootLogin yes
systemctl enable sshd.service
passwd
fallocate -l 1G /swapfile 
chmod 600 /swapfile
mkswap /swapfile
echo ‘/swapfile none swap sw 0 0’ | tee -a /etc/fstab
swapon -s
ip a show
ip route show
systemctl start dhcpcd
systemctl enable dhcpcd
nano /etc/systemd/network/20-wired.network

[Match]
Name=eth0
[Network]
DHCP=ipv4

systemctl enable systemd-networkd
nano /etc/systemd/network/20-wired.network

[Match]
Name=eth0
[Network]
Address=192.168.1.21/24
Gateway=192.168.1.1
DNS=1.1.1.1
DNS=1.0.0.1

systemctl enable systemd-networkd
systemctl enable systemd-resolved
cat /etc/resolv.conf
cat /run/systemd/resolve/resolv.conf
timedatectl set-ntp true 
timedatectl status
exit
shutdown now

Post Install VM Cleanup

In PowerShell as (Administrator):

$getb2 = Get-VMFirmware $VMName
$gen2.BootOrder
$gen2file = $gen2.BootOrder[0]
echo $gen2file
Set-VMFirmware -VMName $VMName -FirstBootDevice $gen2file
Get-VMFirmware $VMName
Get-VMDvdDrive -VMName $VMName -ControllerNumber 0 | Remove-VMDvdDrive
Get-VMScsiController -VMName $VMName -ControllerNumber 1 | Remove-VMScsiController

Final Touches for Arch Linux

Let’s start our new Arch Linux and install some useful tools:

$VMName = ‘ArchLinux’Start-VM -Name $VMName
VMConnect $HOSTNAME $VMName

SSH into Arch VM:

ln -sf /run/systemd/resolve/resolv.conf /etc/resolv.conf
nano /etc/hosts

127.0.0.1 localhost.localdomain localhost
::1 localhost.localdomain localhost
127.0.0.1 arch.localdomain arch
pacman -Syyu
pacman -S p7zip unzip pygmentize docker vim htop git jq rsync tmux bash-completion keychain mlocate
systemctl enable docker 
systemctl start docker
useradd -m -g users -G wheel,storage,power,docker -s /bin/bash your_user
passwd your_user
visudo
%wheel ALL=(ALL) NOPASSWD: ALL
nano /etc/pacman.conf

[archlinuxfr]
SigLevel = Never
Server = http://repo.archlinux.fr/$arch

pacman -Sy
pacman -S yaourt
su - your_user
yaourt -Syyua
gpg - recv-key 1EB2638FF56C0C53 
yaourt -S pacaur 
pacaur -Syyua

Remove the root SSH

sed -i ‘s/^PermitRootLogin yes/#PermitRootLogin yes/’ /etc/ssh/sshd_config

Share folders and files between VM and host OS

pacman -S cifs-utils smbclient
mkdir /etc/samba /mnt/Hyper-V
touch /etc/samba/smb.conf
ping -c 3 $(nmblookup YOUR_PC_NAME | head -n 1 | cut -d ‘ ‘ -f 1)
vim ~/.credentials
username=your_windows_login
password=windows_password
chmod 600 ~/.credentials
mount -t cifs //YOUR_PC_NAME/Hyper-V-Share /mnt/Hyper-V -o credentials=~/.credentials,ip=”$(nmblookup YOUR_PC_NAME | head -n 1 | cut -d ‘ ‘ -f 1)”

In some cases, when you use Windows Ethernet and WiFi, your VM needs to be aware.

In PowerShell as (Administrator):

$Switch = ‘ExternalSwitch’
Get-VMSwitch -SwitchType External
Get-NetAdapter
Set-VMSwitch $Switch -NetAdapterName “Wi-Fi”
Set-VMSwitch $Switch -NetAdapterName “Ethernet 3”

For the final setup, I use custom configured .files like .bashrc, vimrc, and .tmux.conf. You can find them on GitHub.

 

 

 

 

Top