-
-
Save nahidtislam/2a059c0ea1e2fa2577fdbefb51d79d5b to your computer and use it in GitHub Desktop.
install Arch Linux ARM on Parallels (Apple Silicon)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
### ReturnRei's youtube video provides a very helpful tutorial | |
### https://www.youtube.com/watch?v=dKvetujHjYQ&t=737s | |
#### PLEASE NOTE:: | |
#### I created the Arch (target) VM (from the get go) and booted that with an Ubuntu CD | |
#### I think it's easier to do it that rather than to mess around with an existing vm | |
## his useful links | |
# https://wiki.archlinux.org/title/Install_Arch_Linux_from_existing_Linux#Using_a_chroot_environment | |
# https://archlinuxarm.org/platforms/armv8/generic | |
# https://www.reddit.com/r/archlinux/comments/6kwt61/systemd_doesnt_create_machineid_during/ | |
# https://arm.endeavouros.com/endeavouros-arm-install/ | |
# | |
## I don't make/use arch install scripts | |
## however ReturnRei's way is the only way I can get | |
## Arch working on my M1 Pro MacBook lol | |
# | |
# note I changed some words/commands to suit my locale (someone from the UK) | |
## download the the thing | |
cd ~/Downloads | |
wget http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz | |
sudo add-apt-repository universe | |
sudo add-apt-repository multiverse | |
sudo apt update | |
sudo apt install libarchive-tools | |
sudo bash | |
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' | |
TGTDEV="/dev/sda" | |
# partitions the drive | |
## do not run if you already done this manually | |
prep-disk() { | |
sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' <<E_FDISK | fdisk ${TGTDEV} | |
g # clear and and make the GPT table | |
n # new partition for EFI | |
1 # partition number 1 | |
# (default) - start at beginning of disk | |
+1000M # 1GB (1000MB) boot parttion | |
t # set partition '1' type | |
1 # to "EFI System" | |
n # new partition | |
2 # partition number 2 | |
# (default) - start immediately after preceding partition | |
# (default) - extend partition to end of disk | |
w # write the partition table to disc | |
q # and we're done | |
E_FDISK | |
mkfs.ext4 ${TGTDEV}2 -L "arch" | |
mkfs.vfat ${TGTDEV}1 -n "efi arm" | |
mkdir /target | |
mount ${TGTDEV}2 /target | |
mkdir /target/boot | |
mount ${TGTDEV}1 /target/boot | |
} | |
prep-disk ## RUNNING THIS WILL ERASE THE DATA IF YOUR USING AN EXISTING VM | |
## DO NOT RUN IF YOU ALREADY PARTITIONED YOUR DRIVE | |
bsdtar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C /target | |
echo "$TGTDEV" > /target/.initial_dev.text | |
## Get into chroot | |
mount --bind /target /target && | |
cd /target && | |
rm /target/etc/resolv.conf && | |
cp /etc/resolv.conf etc && | |
mount -t proc /proc proc && | |
mount --make-rslave --rbind /sys sys && | |
mount --make-rslave --rbind /dev dev && | |
mount --make-rslave --rbind /run run | |
chroot /target /bin/bash #<<"E_CHROOT_ENV" | |
PS1='\[\033[01;31m\](chroot)\[\033[00m\] \[\033[01;34m\]\w\[\033[00m\]\$ ' | |
chmod 755 / | |
TGTDEV="$(cat /.initial_dev.text)" # remember the TGTDEV before chrooting | |
mount ${TGTDEV}1 /boot | |
## prepare the pacman keys | |
pacman-key --init | |
pacman-key --populate archlinuxarm | |
## config the install | |
pacman -Syy --noconfirm vim zsh dash | |
# you can run this if you want pacman to look cool and fast | |
sed -i '/^#\(Color\|VerbosePkgLists\|ParallelDownloads\)/s/^#//' /etc/pacman.conf | |
# sets the simultaneous downloads to 6 | |
sed -i 's/^ParallelDownloads = .*/ParallelDownloads = 6/' /etc/pacman.conf | |
# cool 8-bit pacman effect! | |
sed -i '/^#\?ParallelDownloads = /a ILoveCandy' /etc/pacman.conf | |
vim /etc/pacman.conf # do your own pacman config | |
EDITOR="vim" | |
## commands for install | |
pacman -Su --needed --noconfirm base linux linux-firmware arch-install-scripts \ | |
efibootmgr networkmanager network-manager-applet \ | |
dialog os-prober mtools dosfstools base-devel \ | |
linux-headers git go | |
## internal arch system config | |
dbus-uuidgen > /etc/machine-id ## fix for missing machine-id | |
genfstab -U / | grep -e "UUID\|${TGTDEV}" >> /etc/fstab | |
ln -sf /usr/share/zoneinfo/Europe/London /etc/localtime ## this is for if your located in Europe with London's timezone | |
hwclock --systohc | |
# edit /etc/locale.gen to select your locales | |
sed -i '/^#en_\(US\|GB\)[.]UTF-8/s/^#//' /etc/locale.gen | |
locale-gen | |
echo "LANG=en_GB.UTF-8" >> /etc/locale.conf ## assuming you want this locale | |
echo "parallels-arch-vm" >> /etc/hostname | |
groupadd sudo | |
useradd -m -G sudo -s /bin/zsh someuser | |
visudo # give yourself sudo access before rebooting | |
sed -i '/^#\s\+%sudo/s/^#\s\+//' /etc/sudoers ## scripty version | |
ln -sfT dash /usr/bin/sh # optional: makes your system bit more effcient | |
cat <<E_HOSTS > /etc/hosts | |
127.0.0.1 localhost | |
::1 localhost | |
E_HOSTS | |
systemctl enable NetworkManager | |
### setting up systemd-boot | |
bootctl --path=/boot install | |
cat <<E_BLOADER > /boot/loader/loader.conf | |
timeout 3 | |
#console-mode keep | |
default arch* | |
E_BLOADER | |
cat <<E_BENTRY > /boot/loader/entries/arch.conf | |
title arch linux | |
linux /Image | |
initrd /initramfs-linux.img | |
options root=UUID=$(findmnt / -no UUID) rw quiet loglevel=3 | |
E_BENTRY | |
# installing yay | |
su someuser | |
cd /tmp | |
git clone https://aur.archlinux.org/yay.git | |
cd yay && makepkg -si |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#################################################################### | |
#################################################################### | |
######### THIS IS THE UNINTENDED SCRIPT TO ######################## | |
########## PERFORM THE THE INSTALLATION OF ######################### | |
############## THE VIRTUAL MACHINE ############################# | |
#################################################################### | |
#################################################################### | |
### ReturnRei's youtube video provides a very helpful tutorial | |
### https://www.youtube.com/watch?v=dKvetujHjYQ&t=737s | |
#### PLEASE NOTE:: | |
#### I created the Arch (target) VM (from the get go) and booted that with an Ubuntu CD | |
#### I think it's easier to do it that rather than to mess around with an existing vm | |
# | |
## I don't make/use arch install scripts | |
## however ReturnRei's way is the only way I can get | |
## Arch working on my M1 Pro MacBook lol | |
# | |
# note I changed some words/commands to suit my locale (someone from the UK) | |
while getopts a:d:p:u: option | |
do | |
case "${option}" | |
in | |
a) ADDITIONAL_PKGS="${OPTARG//,/ }";; | |
u) FIRST_USER="$OPTARG";; | |
p) FIRST_PASSWORD="$OPTARG";; | |
d) | |
if [[ "$OPTARG" =~ ^(gnome|kde|plasma|xfce4?)$ ]]; then | |
PREFERED_DESKTOP="$OPTARG" | |
else | |
printf "%s\n" "warning: unsupported desktop env"; exit 1 | |
fi | |
;; | |
*) printf "%s\n" "warning: invalid argument(s)"; exit 1;; | |
esac | |
done | |
if [ "$FIRST_USER" ] && ! [ "$FIRST_PASSWORD" ]; then | |
printf "%s\n" "error: password is required if username is given" | |
exit 2 | |
fi | |
[ "$FIRST_USER" ] || FIRST_USER='someuser' | |
ARCH_TAR="ArchLinuxARM-aarch64-latest.tar.gz" | |
if ! [ -f "$ARCH_TAR" ]; then | |
# maybe we are not in the same pwd as the script location | |
cd "$(dirname "$0")" | |
# check again | |
if ! [ -f "$ARCH_TAR" ]; then | |
## download the the thing | |
[ -w "$PWD" ] || cd ~/Downloads | |
until wget -c http://os.archlinuxarm.org/os/ArchLinuxARM-aarch64-latest.tar.gz; do | |
printf "\n%s" "retrying download..." | |
sleep 4 | |
printf "\n\n" | |
done | |
fi | |
fi | |
unset ARCH_TAR | |
if ! which bsdtar &> /dev/null; then | |
printf "%s\n" "configuring apt repositories" | |
sudo add-apt-repository -y universe multiverse &> /dev/null | |
DEPENDANCY_INSTALL_ATTEMPT="1" | |
MAX_DEPENDANCY_ATTEMPT="5" | |
printf "%s\n" "installing libarchive-tools to use bsdtar" | |
until sudo apt install -y libarchive-tools || [ "$DEPENDANCY_INSTALL_ATTEMPT" == "$MAX_DEPENDANCY_ATTEMPT" ] &> /dev/null; do | |
printf "%s\r" "attempt $DEPENDANCY_INSTALL_ATTEMPT of $MAX_DEPENDANCY_ATTEMPT failed; retrying..." | |
done | |
if [ "$DEPENDANCY_INSTALL_ATTEMPT" -gt "$MAX_DEPENDANCY_ATTEMPT" ]; then | |
printf "%s\n" "sorry: installing libarchive-tools failed. We can't continue" | |
exit 4 | |
fi | |
fi | |
echo "$ADDITIONAL_PKGS" > /tmp/additional_packages.text | |
echo "$FIRST_USER" > /tmp/first_user.text | |
echo "$FIRST_PASSWORD" | openssl enc -aes-256-cbc -md sha512 -a -pbkdf2 -iter 100000 -salt -pass pass:'arch-Installer[ARM64]{forPARALLELS}06' > /tmp/first_password.aes | |
[ "$PREFERED_DESKTOP" ] && echo "$PREFERED_DESKTOP" > /tmp/prefered_desktop.text | |
sudo bash << 'E_ROOTSHELL' | |
PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' | |
FIRST_USER="$(cat /tmp/first_user.text)" | |
TGTDEV="" | |
select-disk() { | |
declare -a DISKS | |
SELECTED_DISK="" | |
for disk in /dev/sd*[a-z]; do | |
# printf "%s\n" "$disk" | |
DISKS+=("$disk") | |
done | |
if [ "${#DISKS[@]}" -eq 0 ]; then | |
printf "%s\n" "error: No disks found" 1>&2 | |
exit 1 | |
elif [ "${#DISKS[@]}" -eq 1 ]; then | |
SELECTED_DISK=${DISKS[0]} | |
else | |
printf "%s\n%s\n" \ | |
"there are more than one disk to select" \ | |
"select the disk." 1>&2 | |
i=0 | |
for driveMount in "${DISKS[@]}"; do | |
i=$(( i+1 )) | |
printf "%s\n" "${i}. '${driveMount}'" 1>&2 | |
done | |
unset i | |
if [ "${#DISKS[@]}" -gt 9 ]; then | |
digits=2 | |
else | |
digits=1 | |
fi | |
read -n ${digits} DRIVE_USER_SELECTION | |
printf "\n" 1>&2 | |
if ! [ "${DRIVE_USER_SELECTION}" ] || [ "${DRIVE_USER_SELECTION}" -gt ${#DISKS[@]} ]; then | |
printf "%s\n" "error: bad selection" 1>&2 | |
exit 3 | |
fi | |
SELECTED_DISK=${DISKS[$(( DRIVE_USER_SELECTION-1 ))]} | |
unset DRIVE_USER_SELECTION | |
fi | |
if ! [ "${SELECTED_DISK}" ]; then | |
printf "%s\n" "error: Unable to determine disk" 1>&2 | |
exit 4 | |
fi | |
echo "$SELECTED_DISK" | |
} | |
TGTDEV="$(select-disk)" | |
if ! [ "$TGTDEV" ]; then | |
printf "%s\n" "error: disk selection failed" | |
exit 1 | |
fi | |
# partitions the drive | |
## do not run if you already done this manually | |
prep-disk() { | |
sed -e 's/\s*\([\+0-9a-zA-Z]*\).*/\1/' <<E_FDISK | fdisk ${TGTDEV} > /dev/null | |
g # clear and and make the GPT table | |
n # new partition for EFI | |
1 # partition number 1 | |
# (default) - start at beginning of disk | |
+1000M # 1GB (1000MB) boot parttion | |
t # set partition '1' type | |
1 # to "EFI System" | |
n # new partition | |
2 # partition number 2 | |
# (default) - start immediately after preceding partition | |
# (default) - extend partition to end of disk | |
w # write the partition table to disc | |
q # and we're done | |
E_FDISK | |
mkfs.ext4 ${TGTDEV}2 -L "arch" &> /dev/null | |
mkfs.vfat ${TGTDEV}1 -n "efi arm" &> /dev/null | |
mkdir /target | |
mount ${TGTDEV}2 /target | |
mkdir /target/boot | |
mount ${TGTDEV}1 /target/boot | |
} | |
if [ "$(ls "${TGTDEV}"*[0-9] 2> /dev/null)" ]; then | |
printf "%s\n" "WARNING: THIS DISK CONTAINS PARTITIONS" | |
printf "%s\n" " PONTENTIAL DATA LOSS COULD HAPPEN" | |
printf "\n" | |
read -e -p "continue? " RISK_DATA | |
[[ "$RISK_DATA" == [Yy]* ]] || exit 1 | |
fi | |
prep-disk ## RUNNING THIS WILL ERASE THE DATA IF YOUR USING AN EXISTING VM | |
## DO NOT RUN IF YOU ALREADY PARTITIONED YOUR DRIVE | |
printf "%s\n" "success: formating $TGTDEV for install" | |
bsdtar -xpf ArchLinuxARM-aarch64-latest.tar.gz -C /target | |
echo "$TGTDEV" > /target/.initial_dev.text | |
echo "$FIRST_USER" > /target/.initial_user.text | |
cp /tmp/additional_packages.text /target/.additional_packages.text | |
cp /tmp/first_password.aes /target/.initial_password.aes | |
cp /tmp/prefered_desktop.text /target/.prefered_desktop.text | |
## Get into chroot | |
mount --bind /target /target && | |
cd /target && | |
rm /target/etc/resolv.conf && | |
cp /etc/resolv.conf etc && | |
mount -t proc /proc proc && | |
mount --make-rslave --rbind /sys sys && | |
mount --make-rslave --rbind /dev dev && | |
mount --make-rslave --rbind /run run | |
chroot /target /bin/bash << 'E_CHROOT_ENV' | |
PS1='\[\033[01;31m\](chroot)\[\033[00m\] \[\033[01;34m\]\w\[\033[00m\]\$ ' | |
pac() { | |
until pacman -S --needed --noconfirm $@; do | |
printf "\n\n%s" "install of $1 failed; retrying..." | |
sleep 4 | |
printf "\n\n\n" | |
done | |
} | |
chmod 755 / | |
ADDITIONAL_PKGS="$(cat /.additional_packages.text)" | |
TGTDEV="$(cat /.initial_dev.text)" # remember the TGTDEV before chrooting | |
FIRST_USER="$(cat /.initial_user.text)" # remember the option USER before chrooting | |
[ -f "/.prefered_desktop.text" ] && PREFERED_DESKTOP="$(cat /.prefered_desktop.text)" | |
mount ${TGTDEV}1 /boot | |
## prepare the pacman keys | |
pacman-key --init | |
pacman-key --populate archlinuxarm | |
## config the install | |
# you can run this if you want pacman to look cool and fast | |
sed -i '/^#\(Color\|VerbosePkgLists\|ParallelDownloads\)/s/^#//' /etc/pacman.conf | |
# sets the simultaneous downloads to 6 | |
sed -i 's/^ParallelDownloads = .*/ParallelDownloads = 6/' /etc/pacman.conf | |
# cool 8-bit pacman effect! | |
sed -i '/^#\?ParallelDownloads = /a ILoveCandy' /etc/pacman.conf | |
## commands for install | |
until pacman -Syyu --needed --noconfirm base linux linux-firmware arch-install-scripts \ | |
efibootmgr networkmanager network-manager-applet \ | |
dialog os-prober mtools dosfstools base-devel \ | |
linux-headers git go vim zsh dash | |
do | |
sleep 3.5 | |
done | |
pacman -D --asdeps base linux-firmware arch-install-scripts \ | |
efibootmgr networkmanager network-manager-applet \ | |
dialog os-prober mtools dosfstools go zsh dash > /dev/null | |
EDITOR="vim" | |
## internal arch system config | |
dbus-uuidgen > /etc/machine-id ## fix for missing machine-id | |
genfstab -U / | grep -e "UUID\|${TGTDEV}" >> /etc/fstab | |
ln -sf /usr/share/zoneinfo/Europe/London /etc/localtime ## this is for if your located in Europe with London's timezone | |
hwclock --systohc | |
# edit /etc/locale.gen to select your locales | |
sed -i '/^#en_\(US\|GB\)[.]UTF-8/s/^#//' /etc/locale.gen | |
locale-gen | |
echo "LANG=en_GB.UTF-8" >> /etc/locale.conf ## assuming you want this locale | |
echo "parallels-arch-vm" > /etc/hostname | |
# setting up user | |
groupadd sudo | |
useradd -m -G sudo -s /bin/zsh "$FIRST_USER" | |
if [ "$FIRST_USER" != "someuser" ]; then | |
FIRST_PASSWORD="$(cat /.initial_password.aes | openssl enc -aes-256-cbc -md sha512 -a -d -pbkdf2 -iter 100000 -salt -pass pass:'arch-Installer[ARM64]{forPARALLELS}06')" | |
echo -e "${FIRST_PASSWORD}\n${FIRST_PASSWORD}" | passwd $FIRST_USER &> /dev/null | |
else | |
echo -e "someuser\nsomeuser" | passwd someuser &> /dev/null | |
FIRST_PASSWORD="someuser" | |
fi | |
usermod -a -G wheel $FIRST_USER | |
# give yourself sudo access before rebooting | |
sed -i '/^#\s\+%sudo/s/^#\s\+//' /etc/sudoers ## scripty version | |
# to smooth out the yay package installations | |
# as running yay as root isn't available | |
echo "$FIRST_USER ALL=(ALL:ALL) NOPASSWD: ALL" > /etc/sudoers.d/yay-smoother | |
# this is to let pamac open to users in the 'sudo' group | |
cat <<E_PADMIN > /etc/polkit-1/rules.d/51-allow-sudo-group.rules | |
// | |
// this is to allow users in the sudo group to access privileged GUI apps | |
// like they do with wheel | |
// | |
// useful for apps like pamac | |
polkit.addAdminRule(function(action, subject) { | |
return ["unix-group:sudo"]; | |
}); | |
E_PADMIN | |
ln -sfT dash /usr/bin/sh # optional: makes your system bit more effcient | |
cat <<E_HOSTS > /etc/hosts | |
127.0.0.1 localhost | |
::1 localhost | |
E_HOSTS | |
echo -e "toor\ntoor" | passwd &> /dev/null | |
systemctl enable NetworkManager | |
### setting up systemd-boot | |
bootctl --path=/boot install | |
cat <<E_BLOADER > /boot/loader/loader.conf | |
timeout 1 | |
#console-mode keep | |
default arch* | |
E_BLOADER | |
cat <<E_BENTRY > /boot/loader/entries/arch.conf | |
title arch linux | |
linux /Image | |
initrd /initramfs-linux.img | |
options root=UUID=$(findmnt / -no UUID) rw quiet loglevel=3 | |
E_BENTRY | |
rm /.initial_dev.text | |
rm /.initial_user.text | |
rm /.initial_password.aes | |
# installing yay | |
su - "$FIRST_USER" <<E_YAY | |
cd /tmp | |
git clone https://aur.archlinux.org/yay.git | |
cd yay && makepkg -s | |
sudo pacman -U --noconfirm yay-*.pkg.tar.xz | |
E_YAY | |
[ "$PREFERED_DESKTOP" ] && case "$PREFERED_DESKTOP" | |
in | |
gnome) | |
#### WE NEED TO EXCLUDE SOME PACKAGES THAT MIGHT NOT WORK ON ARM64 ### | |
SKIP_GPKG=("gnome" "gnome-books" "gnome-boxes" "gnome-contacts" "gnome-music" "gnome-photos" "gnome-weather" "gnome-maps" "gnome-remote-desktop" "gnome-software" "gnome-user-docs" "cheese" "simple-scan" "qemu") | |
GNOME_PKGS="" | |
for pkg in $(pacman -Sqg gnome); do | |
[[ " ${SKIP_GPKG[*]} " =~ " $pkg " ]] || GNOME_PKGS+=" $pkg" | |
done | |
GNOME_PKGS="${GNOME_PKGS:1}" | |
printf "\n\n%s\n" "insatlling gnome ---" | |
printf " %s\n" "> pacman > $GNOME_PKGS" | |
pac $GNOME_PKGS gdm | |
pacman -D --asdeps $GNOME_PKGS > /dev/null | |
pacman -D --asexplicit gnome > /dev/null | |
systemctl enable gdm | |
unset SKIP_GPKG | |
unset GNOME_PKGS | |
;; | |
kde|plasma) | |
"\n\n%s\n" "insatlling kde ---" | |
pac plasma plasma-wayland-session xorg xorg-server sddm | |
systemctl enable sddm | |
;; | |
xfce|xfce4) | |
"\n\n%s\n" "insatlling kde ---" | |
pac xfce4-sessionxorg xorg-server lightdm lightdm-slick-greeter | |
systemctl enable lightdm | |
;; | |
*) | |
printf "%s\n" "warning: invalid desktop option - skipping";; | |
esac | |
[ "$PREFERED_DESKTOP" ] && su - "$FIRST_USER" <<E_PAMAC | |
cd /tmp | |
yay -Sy --noconfirm pamac-aur | |
E_PAMAC | |
[ "$ADDITIONAL_PKGS" ] && pac $ADDITIONAL_PKGS | |
rm "/.prefered_desktop.text" | |
rm "/.additional_packages.text" | |
rm "/etc/sudoers.d/yay-smoother" | |
OLD_alarm_USERID="$(cat /etc/passwd | grep "alarm" | cut -f3 -d':')" | |
usermod -u 818 alarm | |
find / -uid "$OLD_alarm_USERID" -exec chown alarm {} \; &> /dev/null | |
[ "$FIRST_USER" == "someuser" ] && passwd --expire someuser | |
E_CHROOT_ENV | |
E_ROOTSHELL |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment