Skip to main content

Installing Arch Linux on USB External Hard Drive and Reserving Storage Space for Windows Devices

· 5 min read
Muel - Nova
Anime Would PWN This WORLD into 2D

Frustrated with syncing data across multiple platforms for years, I suddenly remembered that I still have a SanDisk 256G Gen3.1 USB flash drive I can use, so I decided to research how to install Arch Linux on a USB drive.

Preparation:

  • VMWare Workstation
  • Arch Linux image
  • A fast and large capacity USB drive (recommended USB 3.0+, with a size of 50GB or more)

Environment Setup

Virtual Machine

Add the Arch Linux image to a virtual machine with default settings. After starting the virtual machine, connect the USB.

image-20240328154735717

Partitioning

Use the following command to view device partition information

fdisk -l

You can see that /dev/sdb corresponds to my USB drive, so you can use the following command to perform partitioning operations.

fdisk /dev/sdb

You can use m to view the meaning of each command. For brevity, details of each command are not explained here.

First, create a new GPT partition table by using g. Then, create new partitions for EFI, /, and reserved_for_usbdisk as follows:

# Create GPT partition table
Command (m for help): g

# EFI partition
Command (m for help): n # Create new partition
# Partition number, default
# Starting sector, default
+300M # Size, 300MB for EFI partition

# Root partition
Command (m for help): n # Create new partition
# Partition number
# Starting sector, default
+160G # Size

# USB reserved partition
Command (m for help): n # Create new partition
# Partition number
# Starting sector, default
# Size, use default to fill the disk

Next, set the partition types, which can be viewed using t and L.

# EFI
Command (m for help): t # Change partition type
1 # Partition number
1 # MBR

# Root
Command (m for help): t # Change partition type
2 # Partition number
23 # Linux Root

# USBDisk
Command (m for help): t # Change partition type
3 # Partition number
11 # Microsoft base data

Use p to print the partition table, it should look like this:

image-20240328155834271

Save and exit with w.

Set Partition File System Type

mkfs.ext4 -O "^has_journal" /dev/sdb2  # root
mkfs.fat -F32 /dev/sdb1 # EFI
mkfs.fat -F32 /dev/sdb4 # USBDisk, we use FAT32 due to transferring between Windows devices.

Installation

Mount the root directory to /mnt

mount /dev/sdb2 /mnt
mount /dev/sdb1 /mnt/boot/efi --mkdir

Install the necessary kernel and software packages

pacstrap /mnt base linux linux-firmware base-devel vim dhcpcd iwd intel-ucode amd-ucode

Configuration

Generate fstab file

genfstab -U /mnt >> /mnt/etc/fstab

Check if the file content is correct.

image-20240328160656125

Continue with password setup and new user configuration following other tutorials.

Configure Secure Boot

Difficult to configure. Cannot use sbctl for signing as we are using a removable device; hence we must use shim for signing.

First, install dependencies

pacman -Sy git sbsigntools
(sudoer)$ git clone https://aur.archlinux.org/shim-signed && cd shim-signed && makepkg -si

Change BOOTX64.EFI to grubx64.efi

mv /boot/efi/EFI/BOOT/{BOOTX64.EFI,grubx64.efi}

Copy from shim-singed EFI files

cp /usr/share/shim-signed/shimx64.efi /boot/efi/EFI/BOOT/BOOTX64.EFI
cp /usr/share/shim-signed/mmx64.efi /boot/efi/EFI/BOOT/

Generate Mok key and sign

cd /boot/efi
openssl req -newkey rsa:4096 -nodes -keyout MOK.key -new -x509 -sha256 -subj "/CN=Machine Owner Key/" -out MOK.crt
openssl x509 -outform DER -in MOK.crt -out MOK.c

Sign both kernel and grub

sbsign --key MOK.key --cert MOK.crt --output /boot/vmlinuz-linux /boot/vmlinuz-linux
sbsign --key MOK.key --cert MOK.crt --output /boot/efi/EFI/BOOT/grubx64.efi /boot/efi/EFI/BOOT/grubx64.efi
cp ./MOK.cer /boot/efi

Configure Boot Loader

Install grub and efibootmgr

pacman -Sy grub efibootmgr

Setup grub

grub-install --target=x86_64-efi --efi-directory=/boot --removable --modules="normal test efi_gop efi_uga search echo linux all_video gfxmenu gfxterm_background gfxterm_menu gfxterm loadenv configfile tpm" --sbat /usr/share/grub/sbat.csv

Generate grub configuration

grub-mkconfig -o /boot/grub/grub.cfg

mkinitcpio post hook

vim /etc/initcpio/post/kernel-sbsign
#!/usr/bin/env bash

kernel="$1"
[[ -n "$kernel" ]] || exit 0

keypairs=(/boot/efi/MOK.key /boot/efi/MOK.crt)

for (( i=0; i<${#keypairs[@]}; i+=2 )); do
key="${keypairs[$i]}" cert="${keypairs[(( i + 1 ))]}"
if ! sbverify --cert "$cert" "$kernel" &>/dev/null; then
sbsign --key "$key" --cert "$cert" --output "$kernel" "$kernel"
fi
done
chmod +x /etc/initcpio/post/kernel-sbsign

Modify Locale Settings

Switch to /mnt for these operations (unless otherwise specified, the following steps take place in the file system after arch-chroot /mnt).

Set the timezone

ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime

Edit locale settings by uncommenting en_SG.UTF-8

vim /etc/locale.gen
# Uncomment the lines and save
locale-gen

Set local.conf to en_SG.UTF-8

echo "LANG=en_SG.UTF-8" > /etc/locale.conf

Set Hostname

echo "MuelNova-Arch" > etc/hostname

Set hosts

Add localhost mappings in hosts file

vim /etc/hosts

# Add the following two lines and save
# 127.0.0.1 localhost
# ::1 localhost

Configure initramfs

The default initramfs may have issues with different block devices and keyboard support.

To address this, move block and keyboard hooks before autodetect to ensure they are always loaded.

vim /etc/mkinitcpio.conf

# Modify HOOKS to the following, then save.
# HOOKS=(base udev block keyboard autodetect modconf filesystems fsck)

mkinitcpio -P # Regenerate initramfs

References

https://carbonateds.com/36.html

Arch Linux USB (Installation Article) | Zephyr's Blog (zephyrheather.github.io)

info

This Content is generated by ChatGPT and might be wrong / incomplete, refer to Chinese version if you find something wrong.

Loading Comments...