# Установка Coreboot+Tianocore на ThinkPad T530

![Coreboot logo](https://nekoea.red/wrfreely-images/coreboot.png)

#coreboot #bios #uefi #firmware #tianocore #thinkpad

Нян!
Сегодня мы будем заниматься установкой Coreboot'а на ноутбук ThinkPad T530, используя Tianocore для получения свободного варианта UEFI.
Раз вас заинтересовала данная статья, то, скорее всего, что такое [Coreboot](https://www.coreboot.org/ ), и так знаете. Но на всякий случай всё-так сделаю небольшое лирическое отступление "кто и зачем".

> Coreboot - проект по созданию свободного встроенного программного обеспечения для ряда ПК, одобренный FSF (Free Software Foundation). Целью проекта является замена проприетарных и закрытых систем BIOS и UEFI, используемых большинством персональных компьютеров, на легковесный, предназначенный исключительно для загрузки и запуска современных 32-битных и 64-битных операционных систем.

> TianoCore представляет собой открытую реализацию UEFI, разрабатываемую компанией Intel, но не содержащую компонентов для инициализации оборудования.

То есть, Coreboot отвечает за инициализацию железа, а Tianocore - за предоставление функционала UEFI.
Из-за привязки к оборудованию Coreboot доолжен быть отдельно портирован на каждую платформу, в отличие от Tianocore, который, при наличии инициализированного железа, будет работать где угодно.
Если мы совместим эти два компонента, то получим (почти) свободную реализацию UEFI, Tianocore используется в качестве т.н. payload'а ("полезная нагрузка") для coreboot.
Стоит отметить, что существуют и иные payload'ы для Coreboot, например, [SeaBIOS](https://ru.wikipedia.org/wiki/SeaBIOS), который предоставляет x86 BIOS, по некоторым ссылкам в конце данной статьи упомянуты моменты, специфичные для этой полезной нагрузки.
Итак, но почему бы не использовать стоковые закрытые и проприетарные прошивки?  На самом деле, у них крайне много проблем. Например, наличие критических уязвимостей ([из недавнего](https://www.opennet.ru/opennews/art.shtml?num=56656)), выявление которых зачастую фактически невозможно в силу отсутствия исходных кодов самой прошивки. Если вирус установит себя на уровне ниже операционной системы (ОС), то выковырять его оттуда будет крайне проблематично.
Отдельно стоит отметить наличие подсистемы [Intel ME](https://ru.wikipedia.org/wiki/Intel_Management_Engine) в подавляющем большинстве современных x86 компьютеров. Если коротко - то это компьютер внутри компьютера, который имеет доступ ко всем компонентам системы, от оперативной памяти до видеопотока, имеет выделенный сетевой интерфейс, который НЕ виден для основной системы. В теории, это означает, что тот, кто владеет доступом к Intel ME, тот владеет и компьютером. У вас этого доступа нет, так что вывод, я думаю, очевиден. А, ну и да, никто не отменял уязвимости Intel ME =3
К сожалению, большая производителей выпускают прошивки для своего оборудования исключительно в бинарном виде, а открытых альтернатив нет. Именно поэтому в Coreboot присутствуют т.н. бинарные блобы (binary blobs), необходимые для функционирования некоторых компонентов, например, Ethernet. Несмотря на это, количество блобов минимально и, как правило, они не представляют особой опасности.
Существует также проект [Libreboot](https://libreboot.org/), представляющий собой прошивку без блобов. Но ее можно поставить на очень малый список устройств (даже меньше, чем в и так [скудном списке coreboot'а](https://www.coreboot.org/status/board-status.html)) , да и подходящие девайсы - далеко не первой свежести, так что слабое железо и дохлые аккумуляторы.
Intel ME невозможно полностью отключить на современных чипсетах, так как на эту подсистему перевесили много важных функций, но на Sandy Bridge и Ivy Bridge есть возможность так "сломать" Intel ME, что он проведет инициализацию нужных для нормального функционирования системы компонентов, но сам запустится в крайне ограниченном и беззубом режиме.

Итого, какие плюсы от установки Coreboot:

* Есть возможность обезвредить Intel ME, используя утилиту [me_cleaner](https://github.com/corna/me_cleaner);
* Исчезнет "белый" список Wi-Fi адаптеров, который есть в ThinkPad'ах. По умолчанию, в синках стоят карточки с закрытыми и проприетарными драйверами. После установки Coreboot будет возможно поставить, например, Qualcomm Atheros AR9285, для которой есть открытый драйвер ath9k;
* Меньшее время загрузки системы;
* В освободившееся место можно засунуть небольшую программку, типа memtest или тетриса =3

Минусы:

* Сложность самой процедуры;
* Необходимо наличие подходящего железа;
* Иногда становится невозможным просмотр DRM-защищенного контента. [Но он же нам и не нужен, правда](https://www.defectivebydesign.org/)?
* Периодически вылезают баги и проблемы, которые, тем не менее, фиксятся разработчиками, не зря же проект открытый.

Ладно, посмотрели, пора и потрогать, как оно там.

## Подготовка

Нам понадобится:

* Ноутбук, куда ставим (в моем случае - ThinkPad T530);
* Устройство, с которого ставим (можно использовать Raspberry Pi или другой ноутбук. В случае малины нужно удостоверится, что питание на ней достаточное!). На нем поставить linux. Я использовал Artix. Скрытого смысла тут нет, просто у меня была флешка с образом, да и pacman мне ближе (хотя могут быть некоторые плюсы, о которых упомяну чуть позже). А так - можете использовать тот же Debian, список пакетов к установке смотрите по ссылкам в конце статьи;
* Программатор CH341A (с малиной не нужен, там есть SPI, но распиновку на нем я оставляю в качестве упражнения для читателя, ищите всяких индусов на ютубе ;3);
* Прищепка SOIC-8, для однократного применения можно брать и не особо дорогую;
* Набор отверток и прочего инструмента для разборки ноутбука;
* (Опционально) Термопаста, компрессор/пылесос - чтоб почистить перед сборкой;
* (Обязательно!) Желание довести дело до конца, терпение, внимательность и спокойствие. ~~Один прогиб - и ты погиб!~~ В некоторых моментах есть возможность сжечь чип с прошивкой, после такого вашу материнку можно будет использовать разве что как плитку в ванной. Сидеть с нерабочей прошивкой - вариант тоже не особо привлекательный, так что **ни в коем случае не пренебрегаем бекапами и сравнением хэшей!**

### Подготовка системы, из которой будем шить
Устанавливаем нужные пакеты:
```
$ sudo pacman -S base-devel curl git gcc-ada ncurses zlib
```
Создаем каталог с нашим сокровищем, в нем - каталог, куда положим оригинальную прошивку. Клонируем репозиторий coreboot:
```
nihonium@delta/~$ mkdir ~/T530
nihonium@delta/~$ cd ~/T530
nihonium@delta/~/T530$ mkdir bios-backup
nihonium@delta/~/T530$ git clone https://review.coreboot.org/coreboot
nihonium@delta/~/T530$ cd coreboot
nihonium@delta/~/T530/coreboot$ git submodule update --init --checkout
```
Мы можем собрать toolchain для сборки coreboot, чтоб результат был воспроизводим не только на нашем устройстве (или чтоб собрать образ, сидя на другой архитектуре, например, на малине):
```
nihonium@delta/~/T530/coreboot$ make crossgcc-i386 CPUS=$(nproc)
```
Но я собирал, используя системный toolchain, пользуясь тем, что в Artix все пакеты свежие (вот и пригодился Arch-based!). Очевидно, собрать на малине таким образом образ для ThinkPad'а не выйдет, так что там обязателен данный шаг!

### Знакомимся с CH341A

Если вы никогда не имели дело с программатором, то настоятельно рекомендую посмотреть какое-нибудь видео на эту тему.

![Программатор](https://nekoea.red/wrfreely-images/programmer.cleaned.jpg)
![Чип](https://nekoea.red/wrfreely-images/sop.jpg)

Самое важное при работе с программатором - соблюдение нумерации контактов.
Красный провод на прищепке - 1, крепим прищепку к площадке красным проводом на единицу. Затем отжимаем лапку на программаторе, ставим площадку в левую часть, опускаем лапку. Результат представлен на фото ниже.

![Площадка](https://nekoea.red/wrfreely-images/ch341a.cleaned.jpg)
![Площадка](https://nekoea.red/wrfreely-images/ch341a_1.cleaned.jpg)

1 на чипе соответствует нога с выемкой около нее. Красный провод прищепки крепится к этому контакту.

> **ВАЖНО! Перед тем, как пытаться что-то шить, необходимо убедиться, что на устройстве-пациенте нет питания! Должны быть отсоединены аккумулятор, блок питания и внутренняя батарейка.**

> **Подключаемся к чипу в следующем порядке: сначала надеваем прищепку на чип, потом вставляем программатор в USB порт. Извлекаем в обратном порядке - сначала вынимаем программатор из USB порта, затем снимаем прищепку.**

### Готовим подопытный ноутбук

![Материнка](https://nekoea.red/wrfreely-images/motherboard.cleaned.jpg)
Перед началом ломания желательно обновить заводской BIOS до последней версии, если планируете ставить новые компоненты, то протестируйте их до перепрошивки (кроме, разве что, Wi-FI карт).
Приступаем к разборке ноутбука, [видео процесса](https://invidious.snopyta.org/watch?v=StH4DWwaHoo). В обязательном порядке снимаем и маленькую батарейку на материнской плате!
Находим чипы, в которых записан текущий BIOS (на материнской плате под ними написано SPI1 и SPI2). Левый - на 8 МБ, правый - на 4 МБ.

![Чипы SPI1 и SPI2](https://nekoea.red/wrfreely-images/chips.cleaned.jpg)

Смотрим, что написано на каждом из этих чипов, например - MX25L6406E и MX25L3206E. Записываем эти значения.

## Прошивка

### Делаем бекап оригинальной прошивки (ВАЖНО)

Подключаем программатор к левому чипу (SPI1), втыкаем программатор в USB.
Смотрим, определился ли чип:
```
nihonium@delta/~/T530$ sudo flashrom -p ch341a_spi
```
Если в выводе фигурирует значение, которое мы списали с данного чипа, то все в порядке. Иногда чип определяется не с первого запуска flashrom'а, тогда, во-первых, надо проверить подключение прищепки к чипу, во-вторых, попробовать запустить flashrom еще пару раз.
Пример вывода:
```
Calibrating delay loop... OK.
Found Macronix flash chip "MX25L6405" (8192 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L6405D" (8192 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L6406E/MX25L6408E" (8192 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L6436E/MX25L6445E/MX25L6465E/MX25L6473E" (8192 kB, SPI) on ch341a_spi.
Multiple flash chip definitions match the detected chip(s): "MX25L6405", "MX25L6405D", "MX25L6406E/MX25L6408E", "MX25L6436E/MX25L6445E/MX25L6465E/MX25L6473E"
Please specify which chip definition to use with the -c <chipname> option.
```
Наш чип - "MX25L6406E/MX25L6408E", дальше подставляем эту строку при считывании/записи.

![Крепление прищепки к чипу](https://nekoea.red/wrfreely-images/clip.cleaned.jpg)

Если чип стабильно читается, то идем в каталог bios-backup и считываем левый чип (SPI1):
```
nihonium@delta/~/T530$ cd bios-backup
nihonium@delta/~/T530/bios-backup$ sudo flashrom -p ch341a_spi -r factory_spi1-1.bin -c "MX25L6406E/MX25L6408E"
nihonium@delta/~/T530/bios-backup$ sudo flashrom -p ch341a_spi -r factory_spi1-2.bin -c "MX25L6406E/MX25L6408E"
nihonium@delta/~/T530/bios-backup$ sha512sum factory_spi1-*
```
Мы два раза считываем один чип, а затем проверяем, совпадают ли хеши этих двух файлов. Если хеши совпадают, то идем дальше.

Делаем такую же операцию для правого чипа (SPI2).
Подключаем программатор к правому чипу, смотрим, определяется ли чип flashrom'ом.
```
nihonium@delta/~/T530$ sudo flashrom -p ch341a_spi
```
Пример вывода:
```
Calibrating delay loop... OK.
Found Macronix flash chip "MX25L3205(A)" (4096 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L3205D/MX25L3208D" (4096 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L3206E/MX25L3208E" (4096 kB, SPI) on ch341a_spi.
Found Macronix flash chip "MX25L3273E" (4096 kB, SPI) on ch341a_spi.
Multiple flash chip definitions match the detected chip(s): "MX25L3205(A)", "MX25L3205D/MX25L3208D", "MX25L3206E/MX25L3208E", "MX25L3273E"
Please specify which chip definition to use with the -c <chipname> option.
```
Наш чип - "MX25L3206E/MX25L3208E".
Если все в порядке, идем считывать правый чип:
```
nihonium@delta/~/T530/bios-backup$ sudo flashrom -p ch341a_spi -r factory_spi2-1.bin -c "MX25L3206E/MX25L3208E"
nihonium@delta/~/T530/bios-backup$ sudo flashrom -p ch341a_spi -r factory_spi2-2.bin -c "MX25L3206E/MX25L3208E"
nihonium@delta/~/T530/bios-backup$ sha512sum factory_spi2-*
```
Так же сверяем суммы, если все совпадает - идем дальше.
Снимаем программатор, **папку bios-backup сохраняем в надежном месте.**

### Готовим образ Coreboot

Сливаем два файла в один:
```
nihonium@delta/~/T530/bios-backup$ cat factory_spi1-1.bin factory_spi2-1.bin > T530-bios.rom
```
Полученный образ состоит из нескольких элементов:

* Flash Descriptor (4 КБ);
* BIOS (7 МБ);
* Прошивка Intel ME (5 МБ);
* Прошивка Gigabit Ethernet (8 КБ).

Для разделения целого образа исходной прошивки на данные компоненты существует утилита ifdtool.Воспользуемся ей.
```
nihonium@delta/~/T530/bios-backup$ cd ../coreboot/util/ifdtool
nihonium@delta/~/T530/coreboot/util/ifdtool$ make
nihonium@delta/~/T530/coreboot/util/ifdtool$ cp ~/T530/bios-backup/T530-bios.rom .
nihonium@delta/~/T530/coreboot/util/ifdtool$ ./ifdtool -x T530-bios.rom
```
После выполнения данной операции мы получаем следующие файлы в текущей директории:

* flashregion\_0\_flashdescriptor.bin
* flashregion\_1\_bios.bin
* flashregion\_2\_intel\_me.bin
* flashregion\_3\_gbe.bin

Названия файлов вполне себе интуитивно понятные. Файл flashregion\_1\_bios.bin нам не пригодится вообще.
Теперь давайте вычистим Intel ME с помощью me_cleaner.
```
nihonium@delta/~/T530/coreboot/util/ifdtool$ cd ..
nihonium@delta/~/T530/coreboot/util$ git clone https://github.com/corna/me_cleaner.git
nihonium@delta/~/T530/coreboot/util$ cd me_cleaner
nihonium@delta/~/T530/coreboot/util/me_cleaner$ cp ../ifdtool/flashregion_2_intel_me.bin .
nihonium@delta/~/T530/coreboot/util/me_cleaner$ python me_cleaner.py -t -r flashregion_2_intel_me.bin -O me.bin
```
Все, в файле me.bin мы имеем обезвреженный вариант Intel ME.
Создадим каталог для блобов и скопируем туда все необходимое.
```
nihonium@delta/~/T530/coreboot/util/me_cleaner$ mkdir -p ~/T530/coreboot/3rdparty/blobs/mainboard/lenovo/t530
nihonium@delta/~/T530/coreboot/util/me_cleaner$ mv me.bin ~/T530/coreboot/3rdparty/blobs/mainboard/lenovo/t530
nihonium@delta/~/T530/coreboot/util/me_cleaner$ mv ../ifdtool/flashregion_0_flashdescriptor.bin ~/T530/coreboot/3rdparty/blobs/mainboard/lenovo/t530/descriptor.bin
nihonium@delta/~/T530/coreboot/util/me_cleaner$ mv ../ifdtool/flashregion_3_gbe.bin ~/T530/coreboot/3rdparty/blobs/mainboard/lenovo/t530/gbe.bin
```
Все, теперь у нас есть все нужные компоненты для сборки Coreboot.

Давайте его соберем!

```
nihonium@delta/~/T530/coreboot/util/me_cleaner$ cd ~/T530/coreboot
nihonium@delta/~/T530/coreboot$ make nconfig
```
Нам вылезет окно конфигурации, с которым мы и будем работать.
Крутим все примерно вот так:
```
+ general
  - Compress ramstage with LZMA
  - Allow building with any toolchain (Разрешаем сборку системным toolchain'ом)
  - Include the coreboot .config file into the ROM image
  - Allow use of binary-only repository
+ mainboard
  - Mainboard vendor (Lenovo)
  - Mainboard model (ThinkPad T530)
  - ROM chip size (12288 KB (12 MB))
  - (0x250000) Size of CBFS system in ROM
+ chipset
  - Enable VMX for virtualization
  - Support bluetooth on wifi cards
  - Add Intel descriptor.bin file
  - Add Intel ME/TXE firmware
    + Verify the integrity of the supplied ME/TXE firmware
  - Add gigabit ethernet configuration
+ devices
  - Graphics initialization (Use libgfxinit)
  - Display
    - Framebuffer mode (Linear "high-resolution" framebuffer)
  - Enable PCIe Clock Power Management
  - Enable PCIe ASPM L1 SubState
+ generic drivers
  - Support for flash based, SMM mediated data store
  - Support Intel PCI-e WiFi adapters
  - PS/2 keyboard init
+ console
  - Show POST codes on the debug console
+ payloads
  - Add a payload (Tianocore coreboot payload package)
  - Tianocore payload (CorebootPayload)
  - Secondary Payloads (None)
```
Особое внимание следует уделить параметру payloads/Tianocore payload.
Тут необходимо выбрать именно этот пункт, т.к. [иные версии Tianocore чаще всего не работают на ThinkPad'ах](https://www.reddit.com/r/coreboot/comments/rilew7/tianocore_upstream_vs_uefipayload_vs/). Но из-за "старости" кода в данном варианте, нам надо поставить python2 и разрулить пару проблем с gcc.
Ставим второй питон и начинаем сборку.
```
nihonium@delta/~/T530/coreboot$ sudo pacman -S python2
nihonium@delta/~/T530/coreboot$ make CPUS=$(nproc)
```
Скорее всего, посреди сборки вылезет ошибка gcc с жалобами на vla-parameter.
Делаем вот такой финт:
```
nihonium@delta/~/T530/coreboot$ cd ~/T530/coreboot/payloads/external/tianocore/tianocore/BaseTools/Source/C/BrotliCompress
nihonium@delta/~/T530/coreboot/payloads/external/tianocore/tianocore/BaseTools/Source/C/BrotliCompress$ gcc  -c -I ./brotli/c/include -I .. -I ../Include/Common -I ../Include/ -I ../Include/IndustryStandard -I ../Common/ -I .. -I . -I ../Include/X64/ -MD -fshort-wchar -fno-strict-aliasing -fwrapv -fno-delete-null-pointer-checks -Wall -Werror -Wno-vla-parameter -Wno-deprecated-declarations -Wno-stringop-truncation -Wno-restrict -Wno-unused-result -nostdlib -g -O2  dec/decode.c -o dec/decode.o
nihonium@delta/~/T530/coreboot/payloads/external/tianocore/tianocore/BaseTools/Source/C/BrotliCompress$ gcc  -c -I ./brotli/c/include -I .. -I ../Include/Common -I ../Include/ -I ../Include/IndustryStandard -I ../Common/ -I .. -I . -I ../Include/X64/ -MD -fshort-wchar -fno-strict-aliasing -fwrapv -fno-delete-null-pointer-checks -Wall -Werror -Wno-vla-parameter -Wno-deprecated-declarations -Wno-stringop-truncation -Wno-restrict -Wno-unused-result -nostdlib -g -O2  enc/encode.c -o enc/enccode.o
nihonium@delta/~/T530/coreboot/payloads/external/tianocore/tianocore/BaseTools/Source/C/BrotliCompress$ cd ~/T530/coreboot
```
[Если коротко, то проблема вызвана добавлением новых функций в GCC 11.](https://github.com/patmagauran/i915ovmfPkg/issues/21)
После таких манипуляций все должно собраться без проблем, получаем файл build/coreboot.rom. Разделим его на две части, на каждый чип.
```
nihonium@delta/~/T530/coreboot$ cd build
nihonium@delta/~/T530/coreboot/build$ dd if=coreboot.rom of=coreboot-spi1.rom bs=1M count=8
nihonium@delta/~/T530/coreboot/build$ dd if=coreboot.rom of=coreboot-spi2.rom bs=1M skip=8
```

### Прошиваем Coreboot

Подключаем программатор к левому чипу (SPI1), не забываем про порядок действий при этом.
```
nihonium@delta/~/T530/coreboot/build$ sudo flashrom -p ch341a_spi
```
Если чип считывается, то можно шить. Если нет - то проверяем подключение.
```
nihonium@delta/~/T530/coreboot/build$ sudo flashrom --chip "MX25L6406E/MX25L6408E" --programmer ch341a_spi --write coreboot-spi1.rom
```
Примерный вывод:
```
Calibrating delay loop... OK.
Found Macronix flash chip "MX25L6406E/MX25L6408E" (8192 kB, SPI) on ch341a_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip... Erase/write done.
Verifying flash... VERIFIED.
```
Если все прошло хорошо, то перецепляем программатор на правый чип (SPI2) и повоторяем.
```
nihonium@delta/~/T530/coreboot/build$ sudo flashrom -p ch341a_spi
```
Считался - шьем.
```
nihonium@delta/~/T530/coreboot/build$ sudo flashrom --chip "MX25L3206E/MX25L3208E" --programmer ch341a_spi --write coreboot-spi2.rom
```
Примерный вывод:
```
Calibrating delay loop... OK.
Found Macronix flash chip "MX25L3206E/MX25L3208E" (4096 kB, SPI) on ch341a_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip... Erase/write done.
Verifying flash... VERIFIED.
```
Поключаем монитор, питание, клавиатуру и оперативку, проверяем включение. Если на экране появился зайчик, то поздравляю с успехом!
Cобираем ноутбук, ставим новую Wi-Fi карточку (при наличии).

### Проверка статуса Intel ME

Это делаем из системы, запущенной на прошитом ноутбуке. К параметрам загрузки ядра надо добавить iomem=relaxed. Это можно сделать из GRUB'а.
```
aimi@alpha/~/$ git clone --depth=1 https://review.coreboot.org/coreboot
aimi@alpha/~/$ cd coreboot/util/intelmetool
aimi@alpha/~/coreboot/util/intelmetool$ make
aimi@alpha/~/coreboot/util/intelmetool$ ./intelmetool -m
```
И идем сравнивать результат выполнения с [табличкой](https://github.com/corna/me_cleaner/wiki/Get-the-status-of-Intel-ME).
Если значения как в столбце Stock firmware, то вы где-то ошиблись, надо снова вычищать Intel ME и заново шить.
Если как в последних двух столбцах - Intel ME отключен, поздравляю!

Спасибо за внимание!
Статья, вероятно, будет понемногу дополняться.
Буду очень благодарен за конструктивную критику и комментарии!
В Федиверсе меня нет, но связаться со мной можно через [e-mail](mailto:nihonium@nekoea.red) ([публичный OpenPGP ключ](https://nekoea.red/nihonium.gpg)), XMPP (nihonium@nekoea.red), или через Matrix - @nihonium:nyatrix.nekoea.red.

## Источники информации
* Статья чувака с Runion под названием "Паранойя на марше: замена BIOS на coreboot", легко ищется в Интернете, [например](https://playffa.ru/wps/?p=24911);
* Официальный сайт [Coreboot](https://doc.coreboot.org/) - много общих мест, мало практических руководств,  информация сильно фрагментирована;
* [Опыт на X220](https://szclsya.me/posts/coreboot/x220/);
* [Coreboot tutorial](https://doc.coreboot.org/tutorial/part1.html);

<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="Creative Commons License" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />This work is licensed under a <a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">Creative Commons Attribution-ShareAlike 4.0 International License</a>.
