mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
4.0 KiB
142 lines
4.0 KiB
.. SPDX-License-Identifier: GPL-2.0 |
|
|
|
========================== |
|
The Linux Microcode Loader |
|
========================== |
|
|
|
:Authors: - Fenghua Yu <[email protected]> |
|
- Borislav Petkov <[email protected]> |
|
|
|
The kernel has a x86 microcode loading facility which is supposed to |
|
provide microcode loading methods in the OS. Potential use cases are |
|
updating the microcode on platforms beyond the OEM End-Of-Life support, |
|
and updating the microcode on long-running systems without rebooting. |
|
|
|
The loader supports three loading methods: |
|
|
|
Early load microcode |
|
==================== |
|
|
|
The kernel can update microcode very early during boot. Loading |
|
microcode early can fix CPU issues before they are observed during |
|
kernel boot time. |
|
|
|
The microcode is stored in an initrd file. During boot, it is read from |
|
it and loaded into the CPU cores. |
|
|
|
The format of the combined initrd image is microcode in (uncompressed) |
|
cpio format followed by the (possibly compressed) initrd image. The |
|
loader parses the combined initrd image during boot. |
|
|
|
The microcode files in cpio name space are: |
|
|
|
on Intel: |
|
kernel/x86/microcode/GenuineIntel.bin |
|
on AMD : |
|
kernel/x86/microcode/AuthenticAMD.bin |
|
|
|
During BSP (BootStrapping Processor) boot (pre-SMP), the kernel |
|
scans the microcode file in the initrd. If microcode matching the |
|
CPU is found, it will be applied in the BSP and later on in all APs |
|
(Application Processors). |
|
|
|
The loader also saves the matching microcode for the CPU in memory. |
|
Thus, the cached microcode patch is applied when CPUs resume from a |
|
sleep state. |
|
|
|
Here's a crude example how to prepare an initrd with microcode (this is |
|
normally done automatically by the distribution, when recreating the |
|
initrd, so you don't really have to do it yourself. It is documented |
|
here for future reference only). |
|
:: |
|
|
|
#!/bin/bash |
|
|
|
if [ -z "$1" ]; then |
|
echo "You need to supply an initrd file" |
|
exit 1 |
|
fi |
|
|
|
INITRD="$1" |
|
|
|
DSTDIR=kernel/x86/microcode |
|
TMPDIR=/tmp/initrd |
|
|
|
rm -rf $TMPDIR |
|
|
|
mkdir $TMPDIR |
|
cd $TMPDIR |
|
mkdir -p $DSTDIR |
|
|
|
if [ -d /lib/firmware/amd-ucode ]; then |
|
cat /lib/firmware/amd-ucode/microcode_amd*.bin > $DSTDIR/AuthenticAMD.bin |
|
fi |
|
|
|
if [ -d /lib/firmware/intel-ucode ]; then |
|
cat /lib/firmware/intel-ucode/* > $DSTDIR/GenuineIntel.bin |
|
fi |
|
|
|
find . | cpio -o -H newc >../ucode.cpio |
|
cd .. |
|
mv $INITRD $INITRD.orig |
|
cat ucode.cpio $INITRD.orig > $INITRD |
|
|
|
rm -rf $TMPDIR |
|
|
|
|
|
The system needs to have the microcode packages installed into |
|
/lib/firmware or you need to fixup the paths above if yours are |
|
somewhere else and/or you've downloaded them directly from the processor |
|
vendor's site. |
|
|
|
Late loading |
|
============ |
|
|
|
There are two legacy user space interfaces to load microcode, either through |
|
/dev/cpu/microcode or through /sys/devices/system/cpu/microcode/reload file |
|
in sysfs. |
|
|
|
The /dev/cpu/microcode method is deprecated because it needs a special |
|
userspace tool for that. |
|
|
|
The easier method is simply installing the microcode packages your distro |
|
supplies and running:: |
|
|
|
# echo 1 > /sys/devices/system/cpu/microcode/reload |
|
|
|
as root. |
|
|
|
The loading mechanism looks for microcode blobs in |
|
/lib/firmware/{intel-ucode,amd-ucode}. The default distro installation |
|
packages already put them there. |
|
|
|
Builtin microcode |
|
================= |
|
|
|
The loader supports also loading of a builtin microcode supplied through |
|
the regular builtin firmware method CONFIG_EXTRA_FIRMWARE. Only 64-bit is |
|
currently supported. |
|
|
|
Here's an example:: |
|
|
|
CONFIG_EXTRA_FIRMWARE="intel-ucode/06-3a-09 amd-ucode/microcode_amd_fam15h.bin" |
|
CONFIG_EXTRA_FIRMWARE_DIR="/lib/firmware" |
|
|
|
This basically means, you have the following tree structure locally:: |
|
|
|
/lib/firmware/ |
|
|-- amd-ucode |
|
... |
|
| |-- microcode_amd_fam15h.bin |
|
... |
|
|-- intel-ucode |
|
... |
|
| |-- 06-3a-09 |
|
... |
|
|
|
so that the build system can find those files and integrate them into |
|
the final kernel image. The early loader finds them and applies them. |
|
|
|
Needless to say, this method is not the most flexible one because it |
|
requires rebuilding the kernel each time updated microcode from the CPU |
|
vendor is available.
|
|
|