處理器製造商會發布對處理器微碼的穩定性和安全性更新。這些更新提供了對系統穩定性至關重要的錯誤修復。如果沒有這些更新,則可能會遇到不明原因的崩潰或難以跟蹤的意外停機。
使用 AMD 或 Intel CPU 的用戶都應該安裝微碼更新以確保系統穩定性。在虛擬機或容器中,微碼更新應在主機上實施,而不是在客戶機系統中。
安裝
要獲取更新的微碼,根據處理器類型,安裝以下其中一個軟體包:
- amd-ucode包 用於 AMD 處理器,
- intel-ucode包 用於 Intel 處理器。
mkinitcpio 和 dracut 默認會生成組合的 initramfs 文件。微碼將在啟動時自動加載。Booster 不支持生成組合的 initramfs,請參閱#微碼在單獨的initramfs文件中 中所需的引導加載程序配置。
加載微碼
微碼更新通常與主板的固件一起發布,並在固件初始化期間應用。由於OEM可能不會及時發布固件更新,且舊系統根本不會獲得新的固件更新,Linux內核增加了在啟動期間應用CPU微碼更新的功能。Linux微碼加載器支持三種加載方法:
- 內置微碼可以編譯到內核中,然後由早期加載器應用。
- 早期加載在啟動的非常早期階段(在initramfs階段之前)更新微碼,比晚期加載更受推薦。這對於具有嚴重硬體錯誤的CPU(如Intel Haswell和Broadwell處理器系列)是強制性的。
- 晚期加載(可能是危險的)在啟動後更新微碼,這可能為時已晚,因為CPU可能已經嘗試使用有缺陷的指令。即使已經使用早期加載,晚期加載仍然可以用於應用更新的微碼更新,而無需重新啟動。
早期加載
內核的早期加載器期望在未壓縮的CPIO存檔(initramfs鏡像)中的/kernel/x86/microcode/GenuineIntel.bin
或/kernel/x86/microcode/AuthenticAMD.bin
中找到微碼更新文件。
早期initramfs鏡像可以與主initramfs鏡像合併為一個文件,並作為單個initramfs傳遞給內核(通過引導加載程序的initrd=
內核命令行選項或在打包為統一內核鏡像時),或者它可以作為單獨的文件存在,在這種情況下需要使用多個initrd=
內核命令行選項。在這兩種情況下,包含微碼的未壓縮CPIO存檔必須放在主initramfs之前。
請注意,由於用戶早期啟動配置的廣泛多樣性,微碼更新可能不會由Arch的默認配置自動觸發。
自定義構建的內核
為了使早期加載在自定義內核中工作,需要將「CPU微碼加載支持」編譯到內核中,而不是編譯為模塊。這將啟用「早期加載微碼」提示,應將其設置為Y
。
CONFIG_BLK_DEV_INITRD=Y CONFIG_MICROCODE=y CONFIG_MICROCODE_INTEL=Y CONFIG_MICROCODE_AMD=y
微碼initramfs與主initramfs打包在一個文件中
未壓縮的微碼CPIO可以預置到initramfs中並用作單個initramfs文件。此方法優於#Microcode in a separate initramfs file,因為不需要額外的引導參數配置。
mkinitcpio
為了使mkinitcpio生成包含微碼的initramfs文件,請確保microcode
在/etc/mkinitcpio.conf
中的HOOKS
數組中。
如果autodetect
鉤子位於microcode
之前,則僅包含當前CPU的微碼。要包含系統上可以找到的所有CPU微碼文件,請將microcode
鉤子移動到autodetect
之前或完全刪除autodetect
鉤子。
生成initramfs時,mkinitcpio將顯示:
-> Early uncompressed CPIO image generation successful
您可以使用lsinitcpio(1)驗證initramfs是否包含微碼更新文件。例如:
# lsinitcpio --early /boot/initramfs-linux.img | grep microcode
kernel/x86/microcode/ kernel/x86/microcode/AuthenticAMD.bin
dracut
對於dracut,請參見dracut.conf(5) § DESCRIPTION。
微碼在單獨的initramfs文件中
早期微碼更新必須通過在引導加載程序配置文件中添加/boot/amd-ucode.img
或/boot/intel-ucode.img
作為第一個initrd來啟用。這是在正常initrd文件之前。請參閱以下常見引導加載程序的說明。
在以下部分中,將cpu_manufacturer
替換為您的CPU製造商,即amd
或intel
。
GRUB
grub-mkconfig將自動檢測微碼更新並適當配置GRUB。安裝微碼包後,通過運行以下命令重新生成GRUB配置以激活加載微碼更新:
# grub-mkconfig -o /boot/grub/grub.cfg
或者,手動管理GRUB配置文件的用戶可以添加/boot/cpu_manufacturer-ucode.img
(或/cpu_manufacturer-ucode.img
如果/boot
是單獨的分區)如下:
/boot/grub/grub.cfg
... echo 'Loading initial ramdisk' initrd /boot/cpu_manufacturer-ucode.img /boot/initramfs-linux.img ...
為每個菜單項重複此操作。
systemd-boot
使用initrd
選項加載微碼,在初始ramdisk之前,如下所示:
/boot/loader/entries/entry.conf
title Arch Linux linux /vmlinuz-linux initrd /cpu_manufacturer-ucode.img initrd /initramfs-linux.img ...
最新的微碼cpu_manufacturer-ucode.img
必須在引導時在您的EFI系統分區(ESP)中可用。ESP必須掛載為/boot
,以便在每次更新amd-ucode包或intel-ucode包時更新微碼。否則,請在每次更新微碼包時將/boot/cpu_manufacturer-ucode.img
複製到您的ESP。
EFISTUB
附加兩個initrd=
選項:
initrd=\cpu_manufacturer-ucode.img initrd=\initramfs-linux.img
rEFInd
編輯/boot/refind_linux.conf
中的引導選項,並添加一個initrd=
選項作為傳遞的第一個initrd
參數。使用initrd=boot\cpu_manufacturer-ucode.img
或initrd=cpu_manufacturer-ucode.img
,具體取決於/boot
中的文件是否在單獨分區的根目錄中。
微碼需要是引導選項列表中聲明的第一個initramfs。例如:
"Boot using default options" "root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw add_efi_memmap initrd=boot\cpu_manufacturer-ucode.img initrd=boot\initramfs-%v.img"
手動引導節
在esp/EFI/refind/refind.conf
中使用手動節定義內核的用戶應添加initrd=
參數,並在引導分區內指定正確的路徑。此參數是選項行的一部分,而不是節的主要部分。例如:
options "root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw add_efi_memmap initrd=boot\cpu_manufacturer-ucode.img"
Syslinux
cpu_manufacturer-ucode.img
和initramfs-linux.img
initrd文件之間不能有空格。INITRD
行必須完全如下所示。多個initrd可以在/boot/syslinux/syslinux.cfg
中用逗號分隔:
LABEL arch MENU LABEL Arch Linux LINUX ../vmlinuz-linux INITRD ../cpu_manufacturer-ucode.img,../initramfs-linux.img ...
LILO
LILO和可能其他舊的引導加載程序不支持多個initrd鏡像。請改用#Microcode initramfs packed together with the main initramfs in one file方法。
Limine
對於Limine,您只需通過MODULE_PATH
選項在您的limine.conf文件中添加微碼的路徑。以下是一個示例:
limine.conf
default_entry: 1 timeout: 3 /Arch comment: Arch Linux protocol: linux kernel_path: boot():/vmlinuz-linux kernel_cmdline: root=UUID=c0748521-eca9-4f38-989c-43811b6e39a1 rw loglevel=3 module_path: boot():/cpu_manufacturer-ucode.img module_path: boot():/initramfs-linux.img
晚期加載
晚期加載微碼更新發生在系統啟動後。它使用/usr/lib/firmware/amd-ucode/
和/usr/lib/firmware/intel-ucode/
中的文件。微碼更新文件分別由amd-ucode包和intel-ucode包提供。
晚期加載需要內核構建時啟用CONFIG_MICROCODE_LATE_LOADING=y
,目前Arch 官方支持的內核並未啟用此選項。[2]
晚期加載微碼更新
要手動重新加載微碼,例如在更新/usr/lib/firmware/amd-ucode/
或/usr/lib/firmware/intel-ucode/
中的微碼文件後,運行:
# echo 1 > /sys/devices/system/cpu/microcode/reload
這允許在不重新啟動系統的情況下應用更新的微碼更新。
驗證微碼在啟動時是否已更新
使用 journalctl 檢查內核消息,查看微碼是否已更新:
# journalctl -k --grep='microcode:'
每次啟動時應該看到類似以下內容,表明微碼在早期就已更新:
kernel: microcode: Current revision: 0x00000012 kernel: microcode: Updated early from: 0x0000000e
特別是對於較新的硬體,可能沒有適用於 CPU 的微碼更新。
在 AMD 系統上使用延遲加載時,輸出將顯示重新加載微碼前的舊微碼版本以及重新加載後的新版本。
參見
- 更新微碼 – 社區經驗
- 關於 Intel 微碼更新的筆記 – Ben Hawkes
- 內核微碼加載器 – 內核文檔
- Haswell/Broadwell 中的勘誤 – AnandTech
- iucode-tool GitLab 項目
哪些 CPU 接受微碼更新
用戶可以查閱 Intel 的倉庫或 Gentoo 的 AMD 維基,以查看特定型號是否受支持:
檢測可用的微碼更新
對於 Intel,可以使用 iucode_tool(8) 來檢查 /usr/lib/firmware/intel-ucode/
是否包含運行中 CPU 的微碼。
- 安裝 intel-ucode包 和 iucode-tool包
- 加載
cpuid
內核模塊:# modprobe cpuid
- 搜索您的 cpuid:
$ iucode_tool -lS /usr/lib/firmware/intel-ucode/
- 如果有可用的更新,它應該會顯示在「selected microcodes」下面
- 微碼可能已經在您的供應商 BIOS 中,並且不會在 dmesg 中顯示加載。與當前運行的微碼進行比較
grep microcode /proc/cpuinfo
對於 AMD,可以手動完成。
- 找出 CPU 的系列、型號和步進。例如,通過運行以下命令:
# journalctl -k --grep='CPU0:'
查看輸出部分,如(family: 0x15, model: 0x10, stepping: 0x1)
。 - 根據 amd-ucode README 中的列表匹配相應的值。
- 如果匹配,將 當前運行的微碼版本 與列出的
Patch
值進行比較。
/proc/cpuinfo
輸出來獲取系列、型號和步進。但您需要將值轉換為十六進制。參見
- 更新微碼 – 社區經驗
- 關於 Intel 微碼更新的筆記 – Ben Hawkes
- 內核微碼加載器 – 內核文檔
- Haswell/Broadwell 中的勘誤 – AnandTech
- iucode-tool GitLab 項目
禁用微碼加載器
如果更新的 CPU 微碼導致問題,您可能希望暫時禁用微碼加載器以允許成功啟動並降級軟體包。要禁用內核的微碼加載器,請指定 dis_ucode_ldr
內核參數。