Устройство NVRAM в UEFI-совместимых прошивках, часть вторая

    Продолжаем разговор о форматах NVRAM в UEFI-совместимых прошивках, начатый в первой части. На этот раз на повестке дня форматы блока Fsys из прошивок компании Apple, блока FTW из прошивок, следующих заветам проекта TianoCore, и блока FDC, который можно найти в прошивках, основанных на кодовой базе компании Insyde.
    Если вам интересно, зачем нужны и как выглядят не-NVRAM данные, которые можно обнаружить рядом с NVRAM в прошивках различных производителей — добро пожаловать под кат.

    Отказ от ответственности №2


    Как всегда, автор не несет ответственности ни за что, кроме возможных очепяток, все баги автоматически признаются фичами, вы используете полученные сведения на свой страх и риск, короче, вы уже и так в курсе. Если вам все еще непонятно, что в этой статье происходит, куда бежать, что делать, и кто виноват — почитайте тут и здесь, и возвращайтесь. Вернулись или не уходили? Отлично, можно продолжать.

    Блок Fsys


    Начнем с формата блока Fsys, в котором Apple хранит настройки для конкретной модели железа. Настройки эти затем при помощи специального DXE-драйвера превращаются в данные SMBIOS (те самые, которые из ОС можно прочитать утилитой dmidecode).

    Формат, понятное дело, специфичен для прошивок компании Apple, и «был всегда», т.е. встречается как в самых ранних, так и в самых новых прошивках. Блок данных в этом формате обычно находится сразу за первыми двумя хранилищами VSS (основным и резервным), и, по идее, не должен изменяться пользователем, а данные из него не доступны через UEFI runtime-сервисы, поэтому я и не считаю их NVRAM'ом, но если уж им (не) повезло лежать с NVRAM в одном томе — пришлось разобраться и с ними, тем более, что формат оказался тривиальным, и его можно почти весь показать на одном скриншоте без всяких C-структур. Заголовок блока и переменные выглядят вот так:

    Начинается блок с четырехбайтовой сигнатуры, обычно это Fsys (на относительно старых машинах был еще второй блок того же формата с сигнатурой Gaid, на более современных все кладут в один блок Fsys). За сигнатурой следуют 5 неизвестных байт, во всех дампах, что есть у меня, они равны 0x01 0x0E 0x00 0x00 0x00, но у вас они, понятно, могут отличаться. За ними следует двухбайтовый общий размер блока, сразу за которым начинаются переменные, без всякого выравнивания и с максимальной упаковкой. Переменная (лучше назвать эту сущность «записью», т.к. изменять эти данные Apple конечному пользователю не разрешает) хранится так: однобайтовая длина имени, имя в кодировке ASCII, двухбайтовая длина данных, и сами данные. Получается, что на скриншоте видны, кроме заголовка, 3 с половиной записи — dckt, dckh, dck_ и overrides.
    Обратите внимание на начало данных последней: BZ — сигнатура, h — указание на использование кода Хаффмана, 1 — указание на размер блока, а затем и вообще закодированное в BCD число Пи… Ба, старый знакомый, формат Bzip2! Достаем, распаковываем, и получаем вот такое:
    overrides.txt
    ADD_DEVICE () [class=«USBPort»,type=«USB 2.0»,location=«right»,speed=«480»,uhci-id=«0xFA133000»,ehci-id=«0xFA130000»]
    ADD_DEVICE () [class=«USBPort»,type=«USB 2.0»,location=«left»,speed=«480»,uhci-id=«0xFD113000»,ehci-id=«0xFD110000»]
    ADD_DEVICE () [class=«SensorController»,location=«U5510»,model=«EMC1413»,device-key=«SensorController@U5510»]
    ADD_DEVICE () [class=«SensorController»,location=«U5530»,model=«EMC1704»,device-key=«SensorController@U5530»]
    ADD_DEVICE () [class=«ThunderboltPort»,location=«Left»,port1=«1»,port2=«2»,mcuaddr=«0x26»]
    SET_PROPERTY (class=«Processor») [ptype=«iCore»]
    SET_PROPERTY (class=«Battery») [cell-count=«2»]
    SET_PROPERTY (class=«Sensor»&location=«VC0C») [low-limit=«0.0»,high-limit=«1.23»,type=«Voltage»,description=«VOLTAGE Sensor CPU 0 VCore»]
    SET_PROPERTY (class=«Sensor»&location=«VP0R») [low-limit=«7.2»,high-limit=«8.9»,type=«Voltage»,description=«VOLTAGE Sensor PBus 0 Rail»]
    SET_PROPERTY (class=«Sensor»&location=«VN0C») [low-limit=«0.0»,high-limit=«1.23»,type=«Voltage»,description=«VOLTAGE Sensor AGX 0 VCore»]
    SET_PROPERTY (class=«Sensor»&location=«VD0R») [low-limit=«13.5»,high-limit=«15.5»,type=«Voltage»,description=«VOLTAGE Sensor DCIN»]
    SET_PROPERTY (class=«Sensor»&location=«VC1R») [low-limit=«7.2»,high-limit=«8.9»,type=«Voltage»,description=«VOLTAGE Sensor CPU highside»]
    SET_PROPERTY (class=«Sensor»&location=«ID0R») [low-limit=«0.0»,high-limit=«3.5»,type=«Current»,description=«CURRENT Sensor DC IN 0 Rail AMON»]
    SET_PROPERTY (class=«Sensor»&location=«IB0R») [low-limit=«0.0»,high-limit=«10.0»,type=«Current»,description=«CURRENT Sensor CHGR 0 Rail BMON»]
    SET_PROPERTY (class=«Sensor»&location=«IC0R») [low-limit=«0.0»,high-limit=«12.0»,type=«Current»,description=«CURRENT Sensor Chipset 0 INA Highside»]
    SET_PROPERTY (class=«Sensor»&location=«IC1R») [low-limit=«0.0»,high-limit=«12.0»,type=«Current»,description=«CURRENT Sensor Chipset 0 SMBUS Highside»]
    SET_PROPERTY (class=«Sensor»&location=«IC0C») [low-limit=«0.0»,high-limit=«25.0»,type=«Current»,description=«CURRENT Sensor CPU 0 VCore»]
    SET_PROPERTY (class=«Sensor»&location=«IN0C») [low-limit=«0.0»,high-limit=«10.0»,type=«Current»,description=«CURRENT Sensor IG GFX VCore»]
    SET_PROPERTY (class=«Sensor»&location=«IM0R») [low-limit=«0.0»,high-limit=«10.0»,type=«Current»,description=«CURRENT Sensor Memory Power»]
    SET_PROPERTY (class=«Sensor»&location=«Ts0P») [noise-tolerance=«3.0»,low-limit=«10»,high-limit=«50»,type=«Temperature»,description=«TEMP Sensor MLB»]
    SET_PROPERTY (class=«Sensor»&location=«TPCD») [noise-tolerance=«3.0»,low-limit=«15»,high-limit=«100»,type=«Temperature»,description=«TEMP Sensor PCH»]
    SET_PROPERTY (class=«Sensor»&location=«TC0D») [noise-tolerance=«3.0»,low-limit=«10»,high-limit=«110»,type=«Temperature»,description=«TEMP Sensor CPU 0 Die»]
    SET_PROPERTY (class=«Sensor»&location=«TC0P») [noise-tolerance=«3.0»,low-limit=«20»,high-limit=«87»,type=«Temperature»,description=«TEMP Sensor CPU 0 Proximity»]
    SET_PROPERTY (class=«Sensor»&location=«TM0P») [noise-tolerance=«3.0»,low-limit=«20»,high-limit=«75»,type=«Temperature»,description=«TEMP Sensor Inlet»]
    SET_PROPERTY (class=«Sensor»&location=«Ta0P») [noise-tolerance=«3.0»,low-limit=«20»,high-limit=«80»,type=«Temperature»,description=«TEMP Sensor Inlet»]
    SET_PROPERTY (class=«Sensor»&location=«Tm1P») [noise-tolerance=«3.0»,low-limit=«10»,high-limit=«65»,type=«Temperature»,description=«TEMP Sensor Inlet»]
    SET_PROPERTY (class=«Sensor»&location=«Tm0P») [noise-tolerance=«3.0»,low-limit=«10»,high-limit=«65»,type=«Temperature»,description=«TEMP Sensor Inlet»]
    SET_PROPERTY (class=«Sensor»&location=«THSP») [noise-tolerance=«3.0»,low-limit=«10»,high-limit=«65»,type=«Temperature»,description=«TEMP Sensor PCH Proximity»]
    SET_PROPERTY (class=«Sensor»&location=«Th1H») [noise-tolerance=«3.0»,low-limit=«10»,high-limit=«65»,type=«Temperature»,description=«TEMP Sensor Fin Stack»]
    SET_PROPERTY (class=«Sensor»&location=«TB1T») [noise-tolerance=«1.0»,low-limit=«10»,high-limit=«50»,type=«Temperature»,description=«TEMP Sensor BMU 1»]
    SET_PROPERTY (class=«Sensor»&location=«TB2T») [noise-tolerance=«1.0»,low-limit=«10»,high-limit=«50»,type=«Temperature»,description=«TEMP Sensor BMU 2»]
    SET_PROPERTY (class=«Sensor»&location=«TB0T») [noise-tolerance=«1.0»,low-limit=«10»,high-limit=«50»,type=«Temperature»,description=«TEMP Sensor Battery»]
    SET_PROPERTY (class=«Sensor»&location=«TC0C») [noise-tolerance=«1.0»,low-limit=«15»,high-limit=«105»,type=«Temperature»,description=«TEMP Sensor CPU Die — Digital Core 0»]
    SET_PROPERTY (class=«Sensor»&location=«TC1C») [noise-tolerance=«1.0»,low-limit=«15»,high-limit=«105»,type=«Temperature»,description=«TEMP Sensor CPU Die — Digital Core 1»]
    SET_PROPERTY (class=«Sensor»&location=«PCPT») [noise-tolerance=«1.0»,low-limit=«0»,high-limit=«55»,type=«Power»,description=«POWER Sensor CPU Package Total Power»]
    SET_PROPERTY (class=«Sensor»&location=«PCPG») [noise-tolerance=«1.0»,low-limit=«0»,high-limit=«22»,type=«Power»,description=«POWER Sensor CPU Package Gfx Power»]
    SET_PROPERTY (class=«Sensor»&location=«PCPC») [noise-tolerance=«1.0»,low-limit=«0»,high-limit=«33»,type=«Power»,description=«POWER Sensor CPU Package Core Power»]
    SET_PROPERTY (class=«Sensor»&location=«MO_X») [type=«Accelerometer»,description=«Motion Sensor»]
    SET_PROPERTY (class=«Sensor»&location=«MSC0») [low-limit=«9750»,high-limit=«14500»,type=«CalibrationKeys»,description=«Calibration Key 0»]
    SET_PROPERTY (class=«Sensor»&location=«MSLD») [type=«Magnetometer»,description=«Magnetometer»]
    SET_PROPERTY (class=«HardDrive»&type=«SSD») [throttling-support=«TRUE»]
    REMOVE_DEVICE (class=«Sensor») (class=«Sensor»&type="?")


    Записи в блоке следуют друг за другом, пока не встречается запись с говорящим именем EOF, после которой до самого конца блока следуют нули, а в последних четырех байтах записана контрольная сумма CRC32 всего содержимого блока, кроме тех самых последних четырех байт. Apple вообще очень любит CRC32, и считают они её буквально для всего — для записей Fsys, для переменных VSS NVRAM, для исполняемых файлов EFI, для томов и для всего образа целиком тоже. Целостности богу целостности, контроля к трону контроля!

    Если разбирать вручную нет настроения, на помощь снова приходит UEFITool NE, в котором блок Fsys со скришнота выше выглядит вот так:


    Блок FTW


    Следующий блок в нашем списке на препарирование — FTW, который используется для поддержки транзакционной записи в NVRAM, и помогает восстановить её целостность после отключения питания во время записи. К сожалению (или, наверное, к счастью), мне еще не попадались дампы прошивки с какими-либо записями в этом блоке, так что тут получится разобрать только заголовок, а за форматом содержимого придется идти в код проекта TianoCore. Впрочем, теория теорией, а на практике вместо одного красивого и приятного заголовка в прошивках внезапно встречается два почти одинаковых, вот такой:
    struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER32 {
        EFI_GUID  Signature;                  // EFI_SYSTEM_NV_DATA_FV_GUID 
        UINT32    Crc;                        // CRC32 от заголовка с пустыми полями Crc и State. 
                                              // Значение пустого байта определяется битом ErasePolarity тома NVRAM
        UINT8     State;                      // Состояние блока, валидный (0xFE или 0x01, в зависимости от ErasePolarity) или нет (остальные значения)
        UINT8     Reserved[3];                // Зарезервированное поле
        UINT32    WriteQueueSize;             // Размер данных блока, внезапно UINT32
        //UINT8   WriteQueue[WriteQueueSize]; // Данные
    };
    

    И такой:
    struct EFI_FAULT_TOLERANT_WORKING_BLOCK_HEADER64 {
        EFI_GUID  Signature;                  // EFI_SYSTEM_NV_DATA_FV_GUID или EDKII_WORKING_BLOCK_SIGNATURE_GUID 
        UINT32    Crc;                        // ~~~
        UINT8     State;                      // ~~~
        UINT8     Reserved[3];                // ~~~
        UINT64    WriteQueueSize;             // Нормальный UINT64, как написано в спецификации
        //UINT8   WriteQueue[WriteQueueSize]; // ~~~
    };
    

    Такое неожиданное разнообразие создает определенные трудности при попытке угадать, какой именно вариант структуры перед нами. К счастью, чаще всего суммарный размер блока FTW кратен 16 байтам, и потому достаточно проверить значение WriteQueueSize на делимость нацело на 16, если делится — перед нами второй вариант, если в остатке 4 — первый, если в остатке что-то другое — мы нашли еще один вариант этой структуры, ура.

    На скриншоте я покажу только второй тип заголовка, т.к. первый встречается лишь в некоторых старых прошивках времен царя Гороха:

    Все по спецификации, GUID — FFF12B8D-7696-4C8B-A985-2747075B4F50, CRC32 — 0xB0458FB9, состояние блока — валидный, размер данных — 0xFE0, что отлично делится на 16, поэтому последние 4 байта заголовка — все-таки еще заголовок, а не уже кусок данных.

    В UEFITool NE тот же самый блок выглядит вот так:


    Блок FDC


    После того, как UEFI Forum решил хранить ключи для SecureBoot в NVRAM, понадобилось не только серьезно переделать формат VSS (о котором я рассказывал в первой части), но и решать вопрос с хранением «умолчаний» для этих переменных, причем вендорам опять позволили решать его самостоятельно. Одно из таких решений от компании Insyde, а именно блок FDC, мы сейчас и разберем.
    Формат там очень простой, но мне совершенно не ясно, чем руководствовался его разработчик. Заголовок блока вот такой:
    struct FDC_VOLUME_HEADER {
        UINT32 Signature;                          // Сигнатура _FDC
        UINT32 Size;                               // Полный размер блока вместе с заголовком
        //EFI_FIRMWARE_VOLUME_HEADER VolumeHeader; // Заголовок NVRAM-тома, зачем он тут - совершенно непонятно
        //VSS_VARIABLE_STORE_HEADER VssHeader;     // Заголовок хранилища VSS, тоже нужен как собаке пятое колесо
                                                   // Еще и размер в нем указан неверный, чаще всего
    };
    

    На скриншоте весь этот кошмар выглядит вот так:

    Итого: сигнатура — _FDC, общий размер блока — 0x4000, заголовок NVRAM-тома, из которого не используется вообще ничего, сигнатура хранилища VSS с незаполненным размером в отформатированном и здоровом состоянии, и область с переменными. Получается что целых 88 байт потрачено на заголовки, которые вообще ни для чего не нужны, мой внутренний оптимизатор негодует.

    В UEFITool NE я решил не выводить все эти ненужные заголовки вообще, и потому тот же блок FDC в нем выглядит вот так:


    Заключение


    Ну вот, определились и с форматом всяких странных блоков, хранящихся посреди тома NVRAM, на сладкое остались EVSA и NVAR, о которых поговорим в третьей части. Спасибо за внимание.
    Поделиться публикацией
    Ой, у вас баннер убежал!

    Ну. И что?
    Реклама
    Комментарии 15
    • +2
      В прошлом году интересовался вопросом сохранности содержимого флешки SPI, и появилась мысль об аппаратной защите от записи этих микросхем. И вот что успел выяснить: если это BIOS, то в большинстве случаев ему не нужен доступ на запись в SPI, и аппаратная блокировка помогает сохранить содержимое, при ЛЮБЫХ попытках ЛЮБОГО софта что-то записать. Делается так: флешку на программатор, выставляется конфигурация, где включена защита от записи, прошивается (содержимое флешки остаётся тем же), и третий вывод подтягивается на «землю» (на четвёртый, например). В таком состоянии даже программатор уже не может ни записать, ни стереть.
      Для UEFI платформы первый эксперимент провалился, а дальше пока не было у меня времени и плат для экспериментов. Провалился по простой причине — в современных микросхемах с большой ёмкостью используется QuadSPI, с этом режиме третий вывод не используется для защиты от записи, а используется для чтения-записи в режиме Quad. Возможно, это не у всех микросхем есть такая функция. Но на той 25Q64FVAIQ не получилось сделать защиту, нужна микосхема без IQ в конце, или какая-то другая. Время появится — буду пробовать ещё.
      • +2
        Я тоже интересовался этой темой и у меня получилось защитить микросхему SPI от записи, но для этого нужно либо выносить NVRAM на отдельную микросхему, либо заниматься его эмуляцией. Режим QuadSPI можно отключить, но на работающей системе это будет сделать довольно непросто — придется патчить сразу в нескольких местах.
        • 0
          В моём случае не получилось выключить, т.к. на микросхеме за включение этого режима отвечают биты, часть которых OTP (однократно записываемые), и, видимо, настроено уже производителем флешки. Но не исключаю и варианта, что просто мой программатор как-то не так с ней работает.
          Меня больше интересует не то, как эмулировать NVRAM или как вынести его на отдельную мс, а тот случай, когда NVRAM уже содержит нужные значения, и при этом закрыть возможность записи — будет ли корректно работать UEFI, загрузчик, ОС? Да пусть даже не совсем корректно (например, нельзя будет изменить порядок загрузки или ещё что) — но хотя бы просто смогла бы запуститься ОС.
          • +1
            В том то и дело, что корректно работать такая система не будет — упадет на первом же SetVariable, т.к. запись в NVRAM происходит при каждой загрузке (сохраняется последняя загруженная конфигурация, обновляется список загрузочных устройств, обновляется значение MonitonicCounter и т.п.). Чтобы справиться с этой проблемой, нужно либо заменять оригинальный драйвер NVRAM на такой, который на флеш вообще не пишет, либо сразу же загружать вышеупомянутый эмулятор CrEmuVariable, который подменит оригинальные сервисы GetVariable/SetVarible/GetNextVariableName/QueryVariableInfo собственными, и система будет работать. В таком режиме, понятно, тоже есть свои минусы, настройки из BIOS Setup не сохраняются, к примеру, но если все уже настроено — это работает.
            • 0
              Разве UEFI проверяет результат процесса записи какой-либо переменной? Почему-то вот BIOS никак не проверяет — можно даже спокойно писать разными утилитами и в область firmware, и в DMI, ни одна из утилит не ругается, пока не начнёт сверять — при записи флешка «делает вид» что всё пишется (или просто программно это не отследить), но при сверке (считывании) сразу понятно, что ничего не записалось. Поэтому мне не совсем понятно, почему в UEFI должно падать при SetVariable, ведь переменная уже имеет какое-то значение, ранее сохранённое, и если стоит защита от записи, то после попытки записи нового значения просто ничего не поменяется и всё.
              • +1
                Падает потому, что драйвер SPI возвращает ошибку при верификации, и ошибка эта затем доходит до драйвера NVRAM, который из SetVariable возвращает либо EFI_DEVICE_ERROR, либо EFI_WRITE_PROTECTED. Оно не то, чтобы «должно падать», но опыт показывает, что падает. Понятно, что можно сделать написать NVRAM таким образом, чтобы он уживался с RO-флешем, и у AMI есть даже build token для такого режима, но если брать неадаптированную прошивку, она неизбежно упадет где-нибудь посреди фазы DXE, т.к. первая же SetVariable вместо ожидаемого EFI_SUCCESS вернет что-нибудь из вышеперечисленного.
                • +2
                  Спасибо за разъяснение! Значит, в случае UEFI сделать аппаратную защиту от записи намного сложнее, но всё же можно.
                  • +2
                    Пожалуйста. Я бы сказал, что даже нужно, но сделать её получится нормально только на весьма небольшом количестве систем, т.к. кроме UEFI на том же чипе у нас еще хранятся данные ME (который тоже без устали пишет в свой NVRAM), GbE (этот переживает RO без проблем) и EC (это тоже). Проще всего разделить код и данные на две разных микросхемы, оставив МЕ и NVRAM в первой, а все исполняемые компоненты — во второй, которую и защитить от записи аппаратно (или, на крайний случай, джампером на выводе #WP).
                    У меня такая система уже есть и работает, но в ней изначально задумывалось посадочное место под второй чип. Можно сделать такую же конфигарацию на системах AMD с одним чипом, либо договариваться с Intel об отключении ME, но тут мне уже NDA не позволяет продолжать.
                    • 0
                      Это всё по большей части ноутбуков касается. А если обычную десктопную плату взять — то для домашнего пользователя intel me как бы и не особо надо, EC просто нет на плате.
                      Мне кажется, что и оставлять для записи даже отдельную мс не нужно — пару раз попадались десктопные платы, которые не стартовали нормально из-за мусора (нет, не в SPI флешке) в CMOS, или даже не мусора, а каких-то некорректных записей. Так же и с NVRAM может случиться — если вдруг содержимое каких-то переменных будет испорчено — кто знает, как себя поведёт UEFI — хорошо, если просто не загрузится, а ведь может и что-то аппаратно испортить (ну там частоты не те выставить или ещё что).
                      Получается, если хотим полностью защищённую систему от записи — нужно систему на BIOS, с чипом SPI, и ОС на SD-карте с блокировкой от записи (и проверенный картридер, а то некоторые игнорируют защёлку).

                      Ещё одна мысль пришла — а почему производители не учитывают тот факт, что в SPI чипах можно выбрать несколько разных регионов для защиты от записи, при этом остальное будет незащищено? Тогда можно было бы основную firmware писать в те области, которые будут после записи защищены, а для NVRAM и прочего выделять место, которое будет доступно для записи, ну и после этого WP# на землю. При этом можно что угодно сколько угодно писать, и основная прошивка никак не пострадает. Хотя с учётом того, что бывает просто износ, и UEFI проверяет корректность записи… тоже мало что даст.
                      • 0
                        МЕ нынче просто так не отключишь, так что нужен он домашнему пользователю или нет — Интел за него уже все решил.
                        Платы, не стартующие из за мусора в CMOS, я тоже видел, причем иногда они даже но кнопку питания не реагируют, до того залипли. С NVRAM шансы на такой исход пониже, все-таки там форматы поинтереснее, чем голый SRAM, и валидация похитрее.
                        Польностью защищенную систему стоит собирать на процессоре AMD без PSP (на eKabini, например), вместо BIOS лучше использовать Coreboot/Libreboot с reproducible builds, а NVRAM не использовать вообще, задавая все настройки при компиляции.
                        Почему не пользуются защитой отдельных регионов? Никто заморачиваться не хочет, т.к. тот же уровень защиты обеспечивают PR-регистры чипсета, которые при этом намного проще программируются и от производителя SPI-чипа не зависят.
                      • +3
                        — «Проще всего разделить код и данные на две разных микросхемы» стандартным интеловским Fitc+xml или чтото свое с бубнами и на коленке?

                        — «договариваться с Intel об отключении ME» нам Интел ответил «увы это на всегда» (вырезали/вычистили все, но система получала резет каждые 30 минут)
                        • +3
                          Стандартно через FITC, да. Если там выбрать два чипа (и развести их правильно, по соотвествующему SPI_CSx на каждый), то чипсет их отображает друг за другом в непрерывное адресное пространство в конце четвертого гигабайта, а дальше просто оставляем все, кроме томов PEI и DXE, по адресам первой микросхемы, а на вторую после прошивки ставим RO через регистр STATUS и вывод #WP.

                          По поводу МЕ — NDA мешает рассказывать, что Intel сказал нам, могу только сказать, что на рынке Embedded и Industrial достаточно плат с отключенным МЕ, только танцев с бубном вокруг его отключения и работы системы без него с каждым поколением становится все больше.
                          • +1
                            Скажем так, по информации от китайских коллег «отключенный ME» на самом деле не очень честная фраза, ME продолжает дрючить какой-то строжевой таймер и ещё какую-то лажу, но не даёт mailbox и прочие свои «вкусности», по сути дела в плате остаётся minimal ME. И судя по тенденции (945/965 — делайчтохочешь, по x45 — делай правильный дескриптор @ удаляй, далее жоппа) скоро штеуд в ME засунет первоначальную настройку оборудования (хехехе, например MRC туда мигрирует полностью) и всё будет зашибись, и наверное вообще не надо будет думать.
                            • 0
                              «Отключить» МЕ нужно так, чтобы он а) не мешал никому своими вотчдогами, б) ничего не писал на флеш (читает пусть сколько угодно) и в) система при этом не сильно проседала по производительности или возможностям. Понятно, что совсем честное отключение — это когда региона МЕ вообще нет, но на безрыбье народ согласен и на вышеперечисленное, хоть и добиться его становится сложнее с каждым поколением.
                          • +1
                            Ну если есть куууча времени — берите две системы одинаковые, на одной вырезайте, далее анализируйте ВСЕ чипсетные регистры на обеих системах одновременно. Китайцы что-то раскопали, но после допроса с пристрастием была получена только фраза «тама ro регистра прыгает, немагу её модифицировать однако», правда где и что — делиться не хотят.

          Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

          Самое читаемое