Difference between revisions of "Microcode (简体中文)"

From ArchWiki
Jump to navigation Jump to search
(Update translation.)
Tag: wiki-scripts
 
(8 intermediate revisions by 2 users not shown)
Line 1: Line 1:
 
[[Category:CPU (简体中文)]]
 
[[Category:CPU (简体中文)]]
 +
[[Category:Security (简体中文)]]
 
[[de:Microcode]]
 
[[de:Microcode]]
 
[[en:Microcode]]
 
[[en:Microcode]]
Line 5: Line 6:
 
[[ja:マイクロコード]]
 
[[ja:マイクロコード]]
 
[[ru:Microcode]]
 
[[ru:Microcode]]
{{TranslationStatus (简体中文)|Microcode|2019-06-21|438585}}
+
{{TranslationStatus (简体中文)|Microcode|2019-06-19|575923}}
 +
 
 
处理器制造商发布对处理器[[Wikipedia:Microcode|微码]]的稳定性和安全性更新。虽然微码可以通过BIOS进行更新,但Linux内核也可以在引导期间应用这些更新。这些更新提供了对系统稳定性至关重要的错误修复。如果没有这些更新,您可能会遇到虚假崩溃或难以跟踪的意外系统暂停。
 
处理器制造商发布对处理器[[Wikipedia:Microcode|微码]]的稳定性和安全性更新。虽然微码可以通过BIOS进行更新,但Linux内核也可以在引导期间应用这些更新。这些更新提供了对系统稳定性至关重要的错误修复。如果没有这些更新,您可能会遇到虚假崩溃或难以跟踪的意外系统暂停。
  
属于Intel Haswell和Broadwell处理器系列的CP US用户必须安装这些微代码更新,以确保系统稳定性。当然,所有用户都应该安装这些更新。
+
CPU 属于 Intel Haswell 和 Broadwell 处理器系列的用户必须安装这些微代码更新,以确保系统稳定性。当然,所有用户都应该安装这些更新。
  
 
== 安装 ==
 
== 安装 ==
Line 20: Line 22:
 
== 启用早期微码更新 ==
 
== 启用早期微码更新 ==
  
微码必须被[[boot loader]]加载,由于用户的早期引导配置具有很大的可变性,因此Arch的默认配置可能不会自动触发微码更新。在这方面,许多aur内核都遵循了Arch官方的[[kernels]]路径。
+
微码必须被 [[boot loader]] 加载。由于用户的早期引导配置具有很大的可变性,因此Arch的默认配置是:不会自动触发微码更新。[[AUR]] 里很多内核都遵循这个设定。
  
These updates must be enabled by adding {{ic|/boot/amd-ucode.img}} or {{ic|/boot/intel-ucode.img}} as the '''first initrd in the bootloader config file'''. This is in addition to the normal initrd file. See below for instructions for common bootloaders.
+
这些 updates 必须通过把 {{ic|/boot/amd-ucode.img}} 或者 {{ic|/boot/intel-ucode.img}} 作为'''第一个''' initrd 添加到 bootloader 的配置文件里来启用。下面的章节有对于常见的 bootloader 的配置指导。
  
{{Note|In the following sections replace {{ic|''cpu_manufacturer''}} with your CPU manufacturer, i.e. {{ic|amd}} or {{ic|intel}}.}}
+
{{注意|在下面的章节里,把 {{ic|''cpu_manufacturer''}} 换成你的CPU的制造商, 即{{ic|amd}} 或者 {{ic|intel}}}}
  
{{Tip|For [[Installing Arch Linux on a USB key|Arch Linux on a removable drive]] add both microcode files as {{ic|initrd}} to the boot loader configuration. Their order does not matter as long as they both are specified before the real initramfs image.}}
+
{{提示|对于 [[Installing Arch Linux on a USB key|安装在可移动设备的Arch Linux]],两个厂商的微码文件都要加到配置文件里,顺序没有关系。}}
  
 
=== Grub ===
 
=== Grub ===
Line 64: Line 66:
  
 
添加两个 {{ic|1=initrd=}} 选项:
 
添加两个 {{ic|1=initrd=}} 选项:
 
 
 
  '''initrd=/''cpu_manufacturer''-ucode.img''' initrd=/initramfs-linux.img
 
  '''initrd=/''cpu_manufacturer''-ucode.img''' initrd=/initramfs-linux.img
  
{{Accuracy|What does this do, why isn't the above enough and why/how is it specific to this particular section?}}
+
{{Accuracy|这一部分做了什么?为什么上面的配置还不足以实现需求?为什么这个内容属于这个章节?}}
  
对于要创建包含全部initrd和命令行的内核,首先集成两个镜像:
+
如果要创建包含全部initrd、内核参数和内核本身的[[systemd-boot#Preparing kernels for /EFI/Linux|单文件内核]],首先集成两个镜像:
  
 
{{bc|1=
 
{{bc|1=
cat /boot/''cpu_manufacturer''-ucode.img /boot/initramfs-linux.img >  
+
# cat /boot/''cpu_manufacturer''-ucode.img /boot/initramfs-linux.img > my_new_initrd
objcopy ... --add-section .initrd=my_new_initrd  
+
# objcopy ... --add-section .initrd=my_new_initrd  
 
}}
 
}}
  
 
=== rEFInd ===
 
=== rEFInd ===
如上述每个 EFI boot stub 一样编辑 {{ic|/boot/refind_linux.conf}} 中的引导选项,例如:
+
 
 +
如上述 EFI boot stub 一样编辑 {{ic|/boot/refind_linux.conf}} 中的引导选项,例如:
  
 
  "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"
 
  "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"
  
如果在 {{ic|/boot/refind.conf}} 中使用 [[rEFInd#Manual_boot_stanzas|手动配置]] 定义所要引导的内核,那么简单地依需求添加 initrd=/intel-ucode.img /boot/intel-ucode.img 到选项行,并不需要修改节的主干部分。
+
如果在 {{ic|''esp''/EFI/refind/refind.conf}} 中使用 [[rEFInd#Manual_boot_stanzas|手动配置]] 定义所要引导的内核,那么添加 {{ic|1=initrd=/boot/''cpu_manufacturer''-ucode.img}} (如果 {{ic|/boot}} 独立分区则添加{{ic|1=initrd=/''cpu_manufacturer''-ucode.img}}) 到选项行。并不需要修改配置的主干部分。
  
 
  options  "root=PARTUUID=''XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'' rw add_efi_memmap '''initrd=/boot/''cpu_manufacturer''-ucode.img'''"
 
  options  "root=PARTUUID=''XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX'' rw add_efi_memmap '''initrd=/boot/''cpu_manufacturer''-ucode.img'''"
Line 102: Line 103:
 
LILO和其他的老版本启动引导器可能不支持多个initrd镜像,所以{{ic|intel-ucode}} 和 {{ic|initramfs-linux}} 需要被合并成一个镜像。
 
LILO和其他的老版本启动引导器可能不支持多个initrd镜像,所以{{ic|intel-ucode}} 和 {{ic|initramfs-linux}} 需要被合并成一个镜像。
 
{{警告|每次更新内核后都要重新合并!}}
 
{{警告|每次更新内核后都要重新合并!}}
{{注意|多出的镜像,{{ic|intel-ucode}},不能被压缩,否则内核会提示有多余的无用数据并不能启动。}}
 
{{ic|intel-ucode.img}} 应是一个cpio存档。建议每次微码更新后检查存档是否被压缩,因为不能保证以后它会不会被压缩。检查是否被压缩:
 
$ file /boot/intel-ucode.img
 
/boot/intel-ucode.img: ASCII cpio archive (SVR4 with no CRC)
 
 
{{注意|顺序很重要。原来的 {{ic|initramfs-linux}} 必须在 {{ic|intel-ucode}}'''之后'''。}}
 
{{注意|顺序很重要。原来的 {{ic|initramfs-linux}} 必须在 {{ic|intel-ucode}}'''之后'''。}}
 
合并两个镜像并生成 {{ic|initramfs-merged.img}}:
 
合并两个镜像并生成 {{ic|initramfs-merged.img}}:
Line 121: Line 118:
 
  # lilo
 
  # lilo
  
== Late microcode updates ==
+
== 微码更新的后期加载(Late microcode updates) ==
  
Late loading of microcode updates happens after the system has booted. It uses files in {{ic|/usr/lib/firmware/amd-ucode/}} and {{ic|/usr/lib/firmware/intel-ucode/}}.
+
微码更新的后期加载,是指在系统启动之后的加载。它使用了 {{ic|/usr/lib/firmware/amd-ucode/}} {{ic|/usr/lib/firmware/intel-ucode/}} 文件夹里的文件。
  
For AMD processors the microcode update files are provided by {{Pkg|linux-firmware}}.
+
对于 AMD 处理器来说,微码更新的文件由 {{Pkg|linux-firmware}} 软件包提供。
  
For Intel processors no package provides the microcode update files ({{Bug|59841}}). To use late loading you need to manually extract {{ic|intel-ucode/}} from Intel's provided archive.
+
对于 Intel 的处理器,没有任何软件包提供微码更新文件 ({{Bug|59841}})。要使用后期加载,你可能需要从英特尔提供的压缩包里手动解压出 {{ic|intel-ucode/}} 文件夹。
  
=== Enabling late microcode updates ===
+
=== 启用微码更新后期加载 ===
  
Unlike early loading, late loading of microcode updates on Arch Linux are enabled by default using {{ic|/usr/lib/tmpfiles.d/linux-firmware.conf}}. After boot the file gets parsed by {{man|8|systemd-tmpfiles-setup.service}} and CPU microcode gets updated.
+
后期加载是默认启用的,由 {{ic|/usr/lib/tmpfiles.d/linux-firmware.conf}} 实现。在启动过程完成之后,微码更新文件由 {{man|8|systemd-tmpfiles-setup.service}} 解析,实现 CPU 微码更新。
  
To manually update the microcode on a running system run:
+
如果要手动触发微码更新:
  
 
  # echo 1 > /sys/devices/system/cpu/microcode/reload
 
  # echo 1 > /sys/devices/system/cpu/microcode/reload
  
This allows to apply microcode updates after {{Pkg|linux-firmware}} has updated without rebooting the system. You can even automate it with a [[pacman hook]], e.g.:
+
在更新了 {{Pkg|linux-firmware}} 之后想马上应用微码更新,而不想重启系统的时候,这个命令比较有用。如果想自动化这个过程,可以创建一个 [[pacman hook]]
  
 
{{hc|/etc/pacman.d/hooks/microcode_reload.hook|2=
 
{{hc|/etc/pacman.d/hooks/microcode_reload.hook|2=
Line 154: Line 151:
 
}}
 
}}
  
=== Disabling late microcode updates ===
+
=== 禁用微码更新的后期加载 ===
  
For AMD systems the CPU microcode will get updated even if {{Pkg|amd-ucode}} is not installed since the files are provided by {{Pkg|linux-firmware}} ({{Bug|59840}}). To disable late loading you must override the [[tmpfile]] {{ic|/usr/lib/tmpfiles.d/linux-firmware.conf}}. It can be done by creating a file with the same filename in {{ic|/etc/tmpfiles.d/}}:
+
对于 AMD 的处理器来说,即使不安装 {{Pkg|amd-ucode}},CPU 的微码仍然会被更新,因为所需的文件是由 {{Pkg|linux-firmware}} 提供的({{Bug|59840}})。如果一定要禁用,你需要覆盖 {{ic|/usr/lib/tmpfiles.d/linux-firmware.conf}} 这个 [[tmpfile]],通过在 {{ic|/etc/tmpfiles.d/}} 创建一个名字也是 {{ic|linux-firmware.conf}} 的文件来实现。当然也可以这样来实现覆盖的效果:
  
 
  # ln -s /dev/null /etc/tmpfiles.d/linux-firmware.conf
 
  # ln -s /dev/null /etc/tmpfiles.d/linux-firmware.conf

Latest revision as of 20:27, 20 June 2019

翻译状态: 本文是英文页面 Microcode翻译,最后翻译时间:2019-06-19,点击这里可以查看翻译后英文页面的改动。

处理器制造商发布对处理器微码的稳定性和安全性更新。虽然微码可以通过BIOS进行更新,但Linux内核也可以在引导期间应用这些更新。这些更新提供了对系统稳定性至关重要的错误修复。如果没有这些更新,您可能会遇到虚假崩溃或难以跟踪的意外系统暂停。

CPU 属于 Intel Haswell 和 Broadwell 处理器系列的用户必须安装这些微代码更新,以确保系统稳定性。当然,所有用户都应该安装这些更新。

安装

对于 AMD 处理器,安装 amd-ucode

对于 Intel 处理器,安装 intel-ucode

如果你在一个移动介质上安装Arch Linux,需要应该安装以上两个厂商处理器的微码软件包。

启用早期微码更新

微码必须被 boot loader 加载。由于用户的早期引导配置具有很大的可变性,因此Arch的默认配置是:不会自动触发微码更新。AUR 里很多内核都遵循这个设定。

这些 updates 必须通过把 /boot/amd-ucode.img 或者 /boot/intel-ucode.img 作为第一个 initrd 添加到 bootloader 的配置文件里来启用。下面的章节有对于常见的 bootloader 的配置指导。

注意: 在下面的章节里,把 cpu_manufacturer 换成你的CPU的制造商, 即amd 或者 intel
提示: 对于 安装在可移动设备的Arch Linux,两个厂商的微码文件都要加到配置文件里,顺序没有关系。

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

/boot/loader/entries/entry.conf
 title   Arch Linux
 linux   /vmlinuz-linux
 initrd  /cpu_manufacturer-ucode.img
 initrd  /initramfs-linux.img
 options ...

最新的 cpu_manufacturer-ucode.img 必须在启动时存在于 ESP分区. ESP 必须挂载到 /boot,这样才能在 amd-ucodeintel-ucode 更新时才能更新里面的 img 文件。否则需要在微代码更新时手动将 /boot/cpu_manufacturer-ucode.img 复制到 ESP。

EFI boot stub / EFI handover

添加两个 initrd= 选项:

initrd=/cpu_manufacturer-ucode.img initrd=/initramfs-linux.img

Tango-inaccurate.pngThe factual accuracy of this article or section is disputed.Tango-inaccurate.png

Reason: 这一部分做了什么?为什么上面的配置还不足以实现需求?为什么这个内容属于这个章节? (Discuss in Talk:Microcode (简体中文)#)

如果要创建包含全部initrd、内核参数和内核本身的单文件内核,首先集成两个镜像:

# cat /boot/cpu_manufacturer-ucode.img /boot/initramfs-linux.img > my_new_initrd
# objcopy ... --add-section .initrd=my_new_initrd

rEFInd

如上述 EFI boot stub 一样编辑 /boot/refind_linux.conf 中的引导选项,例如:

"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=/boot/cpu_manufacturer-ucode.img (如果 /boot 独立分区则添加initrd=/cpu_manufacturer-ucode.img) 到选项行。并不需要修改配置的主干部分。

options  "root=PARTUUID=XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX rw add_efi_memmap initrd=/boot/cpu_manufacturer-ucode.img"

Syslinux

Note:cpu_manufacturer-ucode.imginitramfs-linux initrd 文件间不要用空格,下面的点不是省略号,INITRD 行必须和下面示例中一样。

在配置文件/boot/syslinux/syslinux.cfg中,多个 initrd 可以通过逗号来分隔。

LABEL arch
    MENU LABEL Arch Linux
    LINUX ../vmlinuz-linux
    INITRD ../cpu_manufacturer-ucode.img,../initramfs-linux.img
    APPEND ...

LILO

LILO和其他的老版本启动引导器可能不支持多个initrd镜像,所以intel-ucodeinitramfs-linux 需要被合并成一个镜像。

警告: 每次更新内核后都要重新合并!
注意: 顺序很重要。原来的 initramfs-linux 必须在 intel-ucode之后

合并两个镜像并生成 initramfs-merged.img

# cat /boot/intel-ucode.img /boot/initramfs-linux.img > /boot/initramfs-merged.img

现在编辑 /etc/lilo.conf 装载新的镜像:

...
initrd=/boot/initramfs-merged.img
...

以root运行lilo

# lilo

微码更新的后期加载(Late microcode updates)

微码更新的后期加载,是指在系统启动之后的加载。它使用了 /usr/lib/firmware/amd-ucode//usr/lib/firmware/intel-ucode/ 文件夹里的文件。

对于 AMD 处理器来说,微码更新的文件由 linux-firmware 软件包提供。

对于 Intel 的处理器,没有任何软件包提供微码更新文件 (FS#59841)。要使用后期加载,你可能需要从英特尔提供的压缩包里手动解压出 intel-ucode/ 文件夹。

启用微码更新后期加载

后期加载是默认启用的,由 /usr/lib/tmpfiles.d/linux-firmware.conf 实现。在启动过程完成之后,微码更新文件由 systemd-tmpfiles-setup.service(8) 解析,实现 CPU 微码更新。

如果要手动触发微码更新:

# echo 1 > /sys/devices/system/cpu/microcode/reload

在更新了 linux-firmware 之后想马上应用微码更新,而不想重启系统的时候,这个命令比较有用。如果想自动化这个过程,可以创建一个 pacman hook

/etc/pacman.d/hooks/microcode_reload.hook
[Trigger]
Operation = Install
Operation = Upgrade
Operation = Remove
Type = File
Target = usr/lib/firmware/amd-ucode/*

[Action]
Description = Applying CPU microcode updates...
When = PostTransaction
Depends = sh
Exec = /bin/sh -c 'echo 1 > /sys/devices/system/cpu/microcode/reload'

禁用微码更新的后期加载

对于 AMD 的处理器来说,即使不安装 amd-ucode,CPU 的微码仍然会被更新,因为所需的文件是由 linux-firmware 提供的(FS#59840)。如果一定要禁用,你需要覆盖 /usr/lib/tmpfiles.d/linux-firmware.conf 这个 tmpfile,通过在 /etc/tmpfiles.d/ 创建一个名字也是 linux-firmware.conf 的文件来实现。当然也可以这样来实现覆盖的效果:

# ln -s /dev/null /etc/tmpfiles.d/linux-firmware.conf

验证微指令已在启动时更新

使用 /usr/bin/dmesg 可以查看微代码有没有更新:

$ dmesg | grep microcode

在 Intel 系统上,你应当会看到和下面类似的一些东西,表明微指令已在早先更新:

[    0.000000] CPU0 microcode updated early to revision 0x1b, date = 2014-05-29
[    0.221951] CPU1 microcode updated early to revision 0x1b, date = 2014-05-29
[    0.242064] CPU2 microcode updated early to revision 0x1b, date = 2014-05-29
[    0.262349] CPU3 microcode updated early to revision 0x1b, date = 2014-05-29
[    0.507267] microcode: CPU0 sig=0x306a9, pf=0x2, revision=0x1b
[    0.507272] microcode: CPU1 sig=0x306a9, pf=0x2, revision=0x1b
[    0.507276] microcode: CPU2 sig=0x306a9, pf=0x2, revision=0x1b
[    0.507281] microcode: CPU3 sig=0x306a9, pf=0x2, revision=0x1b
[    0.507286] microcode: CPU4 sig=0x306a9, pf=0x2, revision=0x1b
[    0.507292] microcode: CPU5 sig=0x306a9, pf=0x2, revision=0x1b
[    0.507296] microcode: CPU6 sig=0x306a9, pf=0x2, revision=0x1b
[    0.507300] microcode: CPU7 sig=0x306a9, pf=0x2, revision=0x1b
[    0.507335] microcode: Microcode Update Driver: v2.00 <tigran@aivazian.fsnet.co.uk>, Peter Oruba

如果硬件比较新,也可能没有任何微代码更新,结果应该是下面这样:

[    0.292893] microcode: CPU0 sig=0x306c3, pf=0x2, revision=0x1c
[    0.292899] microcode: CPU1 sig=0x306c3, pf=0x2, revision=0x1c
[    0.292906] microcode: CPU2 sig=0x306c3, pf=0x2, revision=0x1c
[    0.292912] microcode: CPU3 sig=0x306c3, pf=0x2, revision=0x1c
[    0.292956] microcode: Microcode Update Driver: v2.00 <tigran@aivazian.fsnet.co.uk>, Peter Oruba

在 AMD 系统上,微指令会在启动的更晚阶段被更新,所以输出会看起来像这样:

[    0.807879] microcode: CPU0: patch_level=0x01000098
[    0.807888] microcode: CPU1: patch_level=0x01000098
[    0.807983] microcode: Microcode Update Driver: v2.00 <tigran@aivazian.fsnet.co.uk>, Peter Oruba
[   16.150642] microcode: CPU0: new patch_level=0x010000c7
[   16.150682] microcode: CPU1: new patch_level=0x010000c7
注意: 微代码的日期和 intel-ucode 软件包版本不一定一样,而是代表英特尔最后一次更新微代码的时间。

哪些 CPU 可以接受微指令更新

可以从 Intel 和 AMD 的网站查看支持的型号:

检查可用微指令更新

可以通过 iucode-tool 来检查 intel-ucode.img 是否包含适用于你 CPU 的微指令映像。

  1. 安装 intel-ucode (检测并不需要修改 initrd)
  2. 从 AUR 安装 iucode-tool
  3. # modprobe cpuid
  4. 解包微指令映像,并根据你的 cpuid 搜索是否适用:
    # bsdtar -Oxf /boot/intel-ucode.img | iucode_tool -tb -lS - 
  5. 如果有更新可用,它应该会在 selected microcodes 之下显示
  6. 微码可能已经在你的BIOS里,所以不会在dmesg里出现。和正在运行的微码对比:grep microcode /proc/cpuinfo

在自定义内核中启用微代码加载

启用 “CPU microcode loading support” 才能在启动早期加载微代码,必须编译到内核中,而不是编译为模块。然后将 “Early load microcode” 设置为 “Y”。

CONFIG_BLK_DEV_INITRD=Y
CONFIG_MICROCODE=y
CONFIG_MICROCODE_INTEL=y
CONFIG_MICROCODE_AMD=y

参阅