Вернуться назад

Установка Arch

1. vconsole

# Файлы с раскладками:
/usr/share/kbd/keymaps/i386/qwerty/

# Файлы со шрифтами:
/usr/share/kbd/consolefonts/

# Посмотреть список раскладок:
localectl list-keymaps
# или:
ls /usr/share/kbd/keymaps/i386/qwerty/

# Загрузить русскую раскладку
loadkeys ru
   # эта раскладка переключается сочетанием клавиш Ctrl+Shift

# Загрузить обратно английскую раскладку:
loadkeys us

# Дефолтная раскладка:
loadkeys defkeymap

# Установить шрифт с поддержкой  русского языка:
setfont cyr-sun16

setfont LatArCyrHeb-16
setfont LatArCyrHeb-16+
setfont LatArCyrHeb-19
setfont latarcyrheb-sun16
setfont latarcyrheb-sun32

Посмотреть, какой файл раскладки загружается

# Вывести первые 10 записей:
sudo loadkeys -v en 2>&1 | head -n 10
   # Загружается /usr/share/kbd/keymaps/pine/en.map.gz
   # переключение на linux-keys-bare
   # предполагается iso-8859-15 euro
   # код клавиши 1, таблица 0 = 27
   # ...

   # аргумент -v выводит инфу в std:err, поэтому нам надо перенаправить его в std:out

Пример конфигурационного файла:

# /etc/vconsole.conf:

KEYMAP=ru
FONT=cyr-sun16

Или вот русская раскладка, которая переключается через ALT+SHIFT:

# /etc/vconsole.conf:

KEYMAP=ruwin_alt_sh-UTF-8
FONT=cyr-sun16

Если мы хотим, чтобы конфигурационный файл применился, надо либо перезагрузить систему, либо выполнить:

sudo systemctl restart systemd-vconsole-setup.service

Когда мы выполняем команду loadkeys ru, это подгружает файл /usr/share/kbd/keymaps/i386/qwerty/ru.map.gz

loadkeys us подгружает /usr/share/kbd/keymaps/i386/qwerty/us.map.gz.

loadkeys ruwin_alt_sh-UTF-8 подгружает /usr/share/kbd/keymaps/i386/qwerty/ruwin_alt_sh-UTF-8

А вот loadkeys en подгружает файл /usr/share/kbd/keymaps/pine/en.map.gz.

2. Локаль

Все работающие в данный момент локали находятся внутри бинарного файла /usr/lib/locale/locale-archive. Если я хочу посмотреть список этих локалей, то могу это сделать вот так:

locale -a
  # C
  # C.utf8
  # POSIX

Если я хочу добавить в систему ещё какие-нибудь локали, то мне нужно сгенерировать их из шаблонов, которые находятся в папке /usr/share/i18n/. То есть добавить их из этих шаблонов внутрь файла /usr/lib/locale/locale-archive. Как это сделать? С помощью locale-gen.

Список доступных для генерации локалей я могу посмотреть в файле /usr/share/i18n/SUPPORTED:

cat /usr/share/i18n/SUPPORTED | grep less

Я хочу добавить себе две локали:

Я их так и записываю в файл /etc/locale.gen. То есть, в этом файле я указываю, какие локали хочу сгенерировать.

# /etc/locale.gen

en_US.UTF-8 UTF-8
ru_RU.UTF-8 UTF-8

И далее я запускаю команду:

locale-gen

Эта команда смотрит в файл /etc/locale.gen и видит, что я хочу сгенерировать две новые локали. Она находит их исходники в папке /usr/share/i18n/ и на их основе создаёт две новые локали и дабавляет их внуть файла /usr/lib/locale/locale-archive.

Теперь я снова проверяю список работающих в системе локалей и вижу, что там появились две новые: en_US.utf8 и ru_RU.utf8:

locale -a
  # C
  # C.utf8
  # en_US.utf8
  # POSIX
  # ru_RU.utf8

Так как у меня теперь несколько локалей, неплохо бы указать системе, какую из них я хочу использовать по умолчанию. Это делается в файле /etc/locale.conf:

# /etc/locale.conf

LANG=ru_RU.UTF-8

Либо можно запустить команду, которая прописывает локаль в файл /etc/locale.conf:

sudo localectl set-locale LANG=ru_RU.UTF-8

Всё. Готово. Я сгенерировал две локали: en_US.UTF-8 и ru_RU.UTF-8 и добавил вторую из них как системную по умолчанию.

Посмотреть список переменных локали:

locale

Локали в /usr/share/i18n/ поставляются вместе с библиотекой glibc. При установке glibc он создаёт структуру каталогов, где лежат исходные данные для генерации локалей:

А glibc ставится в систему автоматически при установке метапакета base.

3. EFI или MBR

Проверим режим загрузки, чтобы узнать у нас стоит BIOS или UEFI:

cat /sys/firmware/efi/fw_platform_size
# Если исп. режим BIOS, то никакой инфы не вылезет. А если исп. UEFI, то получим либо 64, либо 32

4. Разметка жёсткого диска

Посмотреть типы таблицы существующих разделов (Partition Table Type):

# Здесь столбец PTTYPE покажет тип:
lsblk -o NAME,SIZE,TYPE,PTTYPE /dev/sda

# Или вот так:
sudo fdisk -l /dev/sda
    # ...
    # Тип метки диска: gpt  // Disklabel type: dos

# Или:
sudo parted /dev/sda print
    # ...
    # Таблица разделов: gpt // Partition Table: gpt

# Или:
sudo blkid /dev/sda
    # /dev/sda: PTUUID="e3398c6a-9208-40eb-b2db-c4cbb82a8df7" PTTYPE="gpt"

# То же самое, но развёрнуто:
sudo blkid -s PTUUID -s PTTYPE /dev/sda
    # /dev/sda: PTUUID="e3398c6a-9208-40eb-b2db-c4cbb82a8df7" PTTYPE="gpt"

# Вывести только значение:
sudo blkid -s PTTYPE -o value /dev/sda
    # gpt

У меня SSD на 512 GB. Я хочу разбить его на 4 рездела:

fdisk


fdisk /dev/sda
 → p – посмотреть список существующих разделов
# Создаём метку gpt для таблицы разделов:
  → g
# Создаём 4 рездела:
  → n → +512M
  → n → +16G
  → n → +80G
  → n → Enter
# Тип раздела:
  → t → 1 → 1  (EFI System)
  → t → 2 → 19 (Linux Swap)
  → t → 3 → 20 (Linux System)
  → t → 4 → 20 (Linux System)

# Ещё раз выводим разделы, чтобы убедиться, что всё в порядке:
  → p
# Применяем изменения:
  → w

Готово. Разделы созданы. Убедимся в этом:

lsblk /dev/sda

# более подробный вывод:
lsblk -f /dev/sda

parted

Каждому GPT-разделу можно присвоить имя для удобства. Или его ещё называют GPT-метка. В программе fdisk этого сделать нельзя. Но это можно сделать через parted.


parted /dev/sda
  name → номер_раздела → имя_раздела

# Создадим имена для наших разделов:
  name → 1 → UEFIPart
  name → 2 → SwapPart
  name → 3 → RootPart
  name → 4 → HomePart

# Посмотреть список разделов:
  print
    # у каждого раздела появилось имя

# В отличие от fdisk, тут не нужно сохранять изменения перед выходом из программы.
# Изменения применяются сразу во время работы с parted.

# Выйти из parted:
  quit

Посмотреть список разделов и их имена одной командой:

parted /dev/sda print

Можно посмотреть всю информацию о том, что мы сейчас сделали, через lsblk.

# Здесь мы явно указываем имена столбцов:

lsblk -o NAME,PTTYPE,FSTYPE,LABEL,PARTLABEL,UUID /dev/sda
  # NAME – имя устройства
  # PTTYPE – тип таблицы разделов (gpt/dos)
  # FSTYPE – файловая система
  # LABEL – метка файловой системы
  # PARTLABEL – имя GPT-раздела
  # UUID – имя/идентификатор GPT-раздела

5. Форматирование разделов


# Форматирование разделов:
mkfs.fat -F 32 /dev/sda1    # Форматируем в FAT32
   # mkfs.vfat /dev/sda1    # То же самое
mkswap /dev/sda2            # Создаём swap-раздел
mkfs.ext4 /dev/sda3         # Форматируем в ext4
mkfs.ext4 /dev/sda4         # Форматируем в ext4

# Форматирование и создание метки одновременно:
mkfs.fat -F 32 -n EFILABEL /dev/sda1    # Форматируем в FAT32
   # mkfs.vfat -n EFILABEL /dev/sda1    # То же самое
mkswap -L SwapLabel /dev/sda2           # Создаём swap-раздел
mkfs.ext4 -L RootLabel /dev/sda3        # Форматируем раздел в ext4
mkfs.ext4 -L HomeLabel /dev/sda4        # Форматируем раздел в ext4

# Создать метку для уже отформатированных разделов:
fatlabel /dev/sda1 NEWLABEL     # для FAT32
tune2fs -L NewLabel /dev/sda3   # для ext4
e2label /dev/sda4 NewLabel      # для ext4
mkswap -L NewLabel /dev/sda2    # для swap-раздела

wipefs

# Сначала удаляет сигнатуры на всех разделах
wipefs -a /dev/sda1
wipefs -a /dev/sda2
wipefs -a /dev/sda3
wipefs -a /dev/sda4

# А затем на всём диске:
wipefs -a /dev/sda

Стереть данные

Если вдруг нужно полностью стереть данные с раздела, или со всего диска, то:

dd if=/dev/zero of=/dev/sda3 bs=1M status=progress
sync

Или (работает только для SSD и NVMe):

blkdiscard /dev/sda3

6. Монтирование файловой системы


mount /dev/sda3 /mnt            # монтируем корень системы
mkdir -p /mnt/boot/efi          # создаём папку под EFI-раздел
mount /dev/sda1 /mnt/boot/efi   # монтируем EFI-раздел
mkdir -p /mnt/home              # создаём папку для раздела home
mount /dev/sda4 /mnt/home       # монтируем home
swapon /dev/sda2                # включаем раздел подкачки
mkdir -pv /mnt/{proc,dev,sys,run}

mount -t proc /proc /mnt/proc
mount --rbind /dev /mnt/dev
mount --rbind /sys /mnt/sys
mount --rbind /run /mnt/run   # я устанавливал и не монтируя этот раздел

mount --make-rslave /mnt/dev   # не обязательно
mount --make-rslave /mnt/sys   # не обязательно
mount --make-rslave /mnt/run   # не обязательно

Посмотреть что и куда примонтировано можно так:

# показать всё дерево примонтированных устройств:
findmnt

# показать только одну ветку:
findmnt -R /run

Что ещё нужно перед установкой базовых пакетов


# Этот каталог нужен pacman'у:
mkdir -p /mnt/var/lib/pacman
   # Если мы его не создадим, то pacman не будет ставить пакеты в новую систему –
   # он будет ругаться на отсутствие этой папки.

# Ещё нам обязательно понадобится файл (хотя бы пустой):
/etc/vconsole.conf
   # Без него initramfs не соберётся,
   # pacman просто выдаст ошибку во время установки

Перед тем, как устанавливать базовые пакеты, нужно иметь понятие о том, куда они будут скачиваться во время установки. Это важно, потому что если мы загрузились с флэшки, на которой мало места, то по умолчанию pacman будет скачивать пакеты на неё, но из-за нехватики места пакеты не скачаются и не установятся. Чтобы проверить, куда они скачиваются во время установки, можно ввести команду:

pacman -v

# Root      : /
# Conf File : /etc/pacman.conf
# DB Path   : /var/lib/pacman/
# Cache Dirs: /var/cache/pacman/pkg/  
# Hook Dirs : /usr/share/libalpm/hooks/  /etc/pacman.d/hooks/  
# Lock File : /var/lib/pacman/db.lck
# Log File  : /var/log/pacman.log
# GPG Dir   : /etc/pacman.d/gnupg/
# Targets   : Нет

Cache Dirs – это и есть папка, куда скачиваются пакеты из репозитория Arch перед установкой. То есть они будут скачиваться на флэшку, с которой мы загрузились. Но нам надо указать папку на SSD, в которую мы устанавливаем Arch, т.е. /mnt/var/cache/pacman/pkg. Укажем этот каталог во время установки базовых пакетов:

Установка базовых пакетов

pacman -r /mnt --cachedir=/mnt/var/cache/pacman/pkg -Sy base linux linux-firmware

Создаём файл fstab:

genfstab -L /mnt >> /mnt/etc/fstab

7. chroot

chroot /mnt /bin/bash
source /etc/profile
export PS1="(arch-chroot) \u:\w\$ "

pacman, репозитории, ключи

У нас должна была сохраниться рабочая сеть от системы хоста.

Чтобы pacman мог скачивать пакеты из репозиториев, нужно ему указать зеркала с доступными репозиториями в файле /etc/pacman.d/mirrorlist. Во время установки пакета base этот файл должен был сгенерироваться автоматически, но все строки в нём закомментированы. Нам надо раскомментировать ближайшие к нам репозитории. Содержание файла должно быть примерно таким:

# /etc/pacman.d/mirrorlist

Server = https://at.arch.niranjan.co/$repo/os/$arch
Server = https://de.arch.niranjan.co/$repo/os/$arch
Server = https://berlin.mirror.pkgbuild.com/$repo/os/$arch
Server = https://al.arch.niranjan.co/$repo/os/$arch
Server = https://ro.arch.niranjan.co/$repo/os/$arch
Server = https://mirror.5i.fi/archlinux/$repo/os/$arch
...

Следующее, что нам нужно сделать, это обновить ключи, ведь иначе pacman не будет ничего устанавливать. У нас в новой системе отсутствует папка с ключами /etc/pacman.d/gnupg. Можно было скопировать её из системы-хоста, а можно просто скачать новые:

# Ставим самую актуальную версию archlinux-keyring:
pacman -Sy archlinux-keyring

# Создаём локальнюу GnuPG-базу pacman (/etc/pacman.d/gnupg/) ...
# ... и переносим в неё ключи из archlinux-keyring:
pacman-key --init
pacman-key --populate archlinux

# И теперь можно сделать безопасное обновление системы:
pacman -Syu

Теперь у pacman есть всё необходимое, чтобы он мог устанавливать пакеты в новую систему.

# в новой системе нам понадобится текстовый редактор и интернет – базовый минимум:
pacman -Syu nano dhcpcd

8. GRUB

# скачиваем пакеты grub и efibootmgr:
pacman -S grub efibootmgr

# ставим grub в систему:
grub-install \
   --target=x86_64-efi \
   --efi-directory=/boot/efi \
   --bootloader-id=Arch

# После этого появляется файл:
   # /boot/efi/EFI/Arch/grubx64.efi
# А также папка:
   # /boot/grub/ ...
   #     fonts
   #     grubenv
   #     locale
   #     themes
   #     x86_64-efi

# А также запись в NVRAM с помощью efibootmgr – что-то типа:
   # Boot0003*   Arch    HD(1,GPT,c78dfcd4-7bae-...)/\EFI\Arch\grubx64.efi

То есть после установки появляется файл /boot/efi/EFI/Arch/grubx64.efi, а также папка /boot/grub/.

grubx64.efi – это основной загрузчик для UEFI. То есть, это исполняемый файл, который запускает прошивка UEFI.

/boot/grub/ – это рабочая директория GRUB с его «второй стадей». Отсюда GRUB загружает модули, здесь читает конфигурационный файл grub.cfg.

Всё это вынесено в разные места, потому что ESP – это специальный FAT-раздел, который должна распознать прошивка UEFI. А /boot/grub/ – это обычная часть файловой системы Linux (ext4, например), где удобней хранить тяжёлые файлы GRUB.

Посмотреть запись в NVRAM, которую создал grub-install:

efibootmgr

И создаём конфигурационный файл:

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

Установить fallback-загрузчик

Может такое случиться, что после перезагрузки компьютера, UEFI не видит загрузчик, который мы установили чуть раньше, и Arch не может загрузиться. Такое бывает, когда прошивка UEFI при перезагрузке системы затирает запись в NVRAM. Некоторые производители встраивают в прошивку вот такое поведение: затирать кастомные записи на неизвестные загрузчики. А в этой записи у нас как раз содержится ссылка на загрузчик, который мы установили, т.е. на /boot/efi/EFI/Arch/grubx64.efi. Запись затёрлась и UEFI не знает, где искать наш grubx64.efi.

Чтобы точно убедиться, что проблема именно в этом, загружаемся опять с LiveCD и с помощью efibootmgr проверяем осталась наша запись в NVRAM, или исчезла. Если исчезла, значит прошивка на нашей материнской плате вот так вот гадко себя ведёт – проблема именно в этом.

Если такое произошло, то бороться с этим можно следующим образом. Существует стандартный путь к файлу с дефолтным загрузчиком: EFI/BOOT/BOOTX64.EFI. Такой загрузчик называется Fallback-загрузчиком. Любая прошивка UEFI, если не смогла найти вообще никакого загрузчика, проверяет именно этот путь в EFI-разделе: EFI/BOOT/BOOTX64.EFI. И если такой файл существует, то UEFI его запускает. Поэтому всё, что нам нужно сделать – это перенести/скопировать файл /boot/efi/EFI/Arch/grubx64.efi в /boot/efi/EFI/BOOT/BOOTX64.EFI. Либо вручную, либо это делает автоматически grub-install, если ему передать аргумент --removable.

grub-install \
   --target=x86_64-efi \
   --efi-directory=/boot/efi \
   --removable      ## создать fallback-загрузчик

# Эта команда не создаёт запись в NVRAM
# Она создаёт файл /boot/efi/EFI/BOOT/BOOTX64.EFI
# ... и ставит остальную часть GRUB в /boot/grub/

# Если мы дополнительно передадим флаг "--bootloader-id=Arch", то он проигнорируется:
# ... "--removable" несовместим с "--bootloader-id" – второй просто игнорируется.

Теперь можно ещё раз перезагружаться. На этот раз UEFI точно должен найти загрузчик и запустить его.

mkinitcpio

mkinitcpio -P

Эта команда нужна только если я ставил ядро НЕ через pacman. Она нужна для генерации initramfs.

Если во время установки ядра /boot не был смонтирован, или был смонтирован некорректно, то тогда тоже надо будет пересобирать initramfs.

Если я обновлял /etc/mkinitcpio.conf, то тогда тоже нужно будет пересобрать initramfs.

efibootmgr

# Изменить порядок загрузки:
sudo efibootmgr -o 0001,0000,0002

# Удалить запись:
sudo  efibootmgr -b 0003 -B

# Добавить запись:
sudo efibootmgr -c -d /dev/sda1 1 1 -L "Arch" -l "\EFI\Arch\grubx64.efi"

9. Завершение

Теперь выходим из chroot:

exit

Размонтируем нашу систему (желательно в обратном порядке):

# Отключаем swap:
swapoff /dev/sda2

# Размонтируем --bind-монтирования:
umount -R /mnt/run
umount -R /mnt/sys
umount -R /mnt/dev
umount -R /mnt/proc

# Размонтируем обычные файловые системы:
umount /mnt/boot/efi
umount /mnt/home
umount /mnt

Можно сделать это одним махом:

umount -R /mnt

Если что-то занято, можно посмотреть, что держит точку монтирования:

fuser -vm /mnt

Разорвать процессы, использующие /mnt:

fuser -km /mnt

Принудительный lazy-unmount:

umount -Rl /mnt
# или:
umount --recursive --lazy /mnt

10. После установки

Пользователи

# Создаём пользователя:
useradd -m -G wheel -s /bin/bash mark
# или:
useradd --create-home --groups wheel --shell /bin/bash mark
   # -m = --create-home – создаёт домашнюю директорию в /home/
   # -G wheel – добавляет пользователя в группу wheel
   # -s /bin/bash – устанавливает оболочку входа, в данном случае – /bin/bash
      # По умолчанию может быть: /bin/sh, /usr/bin/zsh, /bin/nologin

# Задаём пароль для созданного пользователя:
passwd mark

sudo


pacman -S sudo
   # создался файл /etc/sudoers
# Открыть файл sudoers с помощью vi (по умолчанию):
visudo

# Открыть /etc/sudoers с помощью nano:
EDITOR=nano visudo

# Раскомментируем следующую строку:
%wheel ALL=(ALL:ALL) ALL
# Это разрешает всем пользователям в группе wheel использовать sudo

# Авторизуемся как mark:
su - mark

# И теперь мы можем пользоваться командой sudo:
sudo ls /

Часовой пояс



# Создаём часовой пояс:
sudo ln -sf /usr/share/zoneinfo/Europe/Moscow /etc/localtime

# Или:
timedatectl set-timezone Europe/Moscow

# Генерируем файл /etc/adjtime
hwclock --systohc
   # Эта команда предполагает, что аппаратные часы по умолчанию используют UTC.
   # А мы здесь копируем системное время (UTC+3) в аппаратные часы (System -> RTC)
   # Это делается, потому что при перезагрузке BIOS/UEFI может отдать системе аппаратное время (особенно, если отключён интернет)

# Системное время можно узнать с помощью:
date

/etc/adjtime – это текстовый файл, который хранит служебные данные. Аппаратные часы никогда не идут идеально точно. Они могут спешить/отставать на одну-две секунды в сутки. hwclock следит за этим и записывает корректировку в этот файл.

Файл /etc/adjtime появляется после первого запуска одной из следующих команд:

hwclock --systohc
hwclock --hctosys
hwclock --adjust

Примечание про UTC и Local

Строка "UTC" или "LOCAL" в файле /etc/adjtime определяет в каком формате хранятся аппаратные часы. Linux обычно использует UTC. Windows использует LOCAL. Если файл покажет LOCAL, система считает, что RTC хранит локальное время.

репозитории


# В файле /etc/pacman.conf раскомментируем блок:
[multilib]
include = /etc/pacman.d/mirrorlist

# А далее:
sudo pacman -Sy

hostname

# /etc/hostname

Govnuter

hosts

# /etc/hosts

127.0.0.1   localhost  my.localhost
::1         localhost  my.localhost

DNS

# /etc/resolv.conf

# Generated by dhcpcd from enp2s0.dhcp, enp2s0.ra
# /etc/resolv.conf.head can replace this line
nameserver 192.168.1.1
nameserver fe80::1%enp2s0
# /etc/resolv.conf.tail can replace this line