Оригиналът е на mjg59 Централните процесори (CPU) не могат нищо да

...
Оригиналът е на mjg59
Централните процесори (CPU) не могат нищо да
Коментари Харесай

Ето как се осъществява първоначалното стартиране при съвременните процесори на Intel

Оригиналът е на mjg59

Централните процесори (CPU) не могат нищо да стартират да вършат, в случай че не им се каже какво да вършат. Очевидният проблем е по какъв начин да въобще да накараме централния процесор да стартира да прави каквото и да било. Мнозина централни процесори вземат решение този проблем, като употребяват вектор за нулиране – твърдо записан в CPU адрес, от който да стартират да се четат командите, когато бъде подадено зареждането. Адресът, към който сочи векторът за нулиране, нормално е някаква ROM или флаш памет, която процесорът може да прочете, даже в случай че към момента не е конфигуриран никакъв различен хардуер. Това разрешава на производителя на системата да сътвори код, който ще се извърши незабавно след включване на зареждането, ще конфигурира целия различен хардуер и последователно ще приведе системата в положение, в което тя може да извършва потребителския код.

Конкретната реализация на вектора за нулиране в x86 системите се е променяла с времето, само че всъщност той постоянно е бил 16 байта под горната част на адресното пространство, т.е. 0xffff0 при 20-битовия 8086, 0xfffff0 при 24-битовия 80286 и 0xfffffff0 при 32-битовия 80386. Стандартно в x86 системите оперативната памет стартира от адрес 0, тъй че горната част на адресното пространство може да се употребява за разполагане на вектора за нулиране с най-малък късмет за спор с оперативната памет.

 

Най-забележителното за x86 тук обаче е, че когато стартира да извършва кода от вектора за нулиране, той е в действителен режим. Реалният режим на x86 е излишък от една доста по-ранна компютърна ера. Адресите не са безспорни (т.е. когато осъществявате достъп до 32-битов адрес, съхранявате целия адрес в 32-битов указател или в указател с по-голям размер), те са 16-битови отмествания, добавени към цената, съхранена в „ сегментен указател “.

Кодът, данните и стекът имат свои лични сегментни регистри, тъй че един 16-битов адрес може да се отнася до разнообразни действителни адреси според от това по какъв начин се интерпретира: прекосяването към 16-битов адрес ще докара до прибавянето на този адрес към сегментния указател на кода, четенето от 16-битов адрес ще докара до прибавянето на този адрес към сегментния указател на данните и така нататък Всичко това е направено за да се резервира съвместимостта с по-старите чипове, и то чак до такава степен, че даже 64-битовият x86 процесор работи в real mode (реален режим) със сегментите и всичко останало (и също по този начин стартира първичното осъществяване на командите на адрес 0xfffffff0вместо на 0xfffffffffffffff0 – 64-битовият режим не поддържа real mode, тъй че 64-битовият физически адрес няма  по какъв начин да бъде заложен благодарение на сегментни регистри и всичко към момента стартира на адреса тъкмо под 4-те GB, макар че е налично доста по-голямо адресно пространство).

 

Хайде, нали всички знаят това. В актуалните системи UEFI фърмуерът, стартиран от вектора за нулиране, препрограмира процесора в подобаващ режим (т.е. без всички тези неща със сегментирането) и прави най-различни неща, като да вземем за пример настройване контролера на паметта, тъй че да може да се получи достъп до оперативната памет (този развой употребява кеша на процесора като оперативна памет, защото програмирането на контролера на паметта е много комплицирано, тъй като би трябвало да се съхранява повече информация за положението, в сравнение с ще се побере в регистрите, т.е. нужна е оперативна памет, само че ние нямаме оперативна памет, до момента в който не проработи контролерът на паметта; за благополучие, процесорът има доста лични мегабайти памет, тъй че може умерено да си поемем дъх). Това е много погрешно, само че такива са следствията от лесните и добре разбираеми наследени (legacy) решения.

Това обаче не е тъкмо по този начин. Съвременният Intel x86 процесор работи по по-различен метод. Всичко е доста по-странно и комплицирано. Да, на пръв взор наподобява, че процесорът прави тъкмо това, само че зад кулисите се случват и доста други неща. Нека да поговорим за сигурността на стартирането. Принципът на всеки тип верифицирано пускане (като UEFI Secure Boot) е, че сигнатурата на идващия модул във веригата на пускане се валидира, преди модулът да бъде изпълнен. Но кой или какво ревизира първия съставен елемент във веригата? Не можете просто да поискате от BIOS самичък да се ревизира – в случай че нападателят може да размени BIOS, неговата версия на BIOS просто ще излъже, че е направила всичко това. Intel е решила този проблем със системата Boot Guard.

 

Но преди да пристъпим към Boot Guard, би трябвало да се уверим, че процесорът работи допустимо най-безпроблемно и без бъгове. Ето за какво, когато процесорът се започва, той преглежда систематичната флаш памет и търси заглавие на блок, показващ, че микрокодът на процесора е бил обновен. Процесорът на Intel има вграден микрокод, само че той постоянно е остарял и с неточности, тъй че систематичният фърмуер може да реши да включи копие, което е задоволително ново, с цел да работи надеждно. Образът на микрокода се копира от флаш паметта, сигнатурата се ревизира и новият микрокод стартира да работи. Това е правилно както при потребление на Boot Guard, по този начин и без него.

При Boot Guard обаче микрокодът в процесора прочита модула за заверен код (ACM) от флаш паметта и ревизира неговата сигнатура по отношение на записания от Intel ключ, преди да премине към вектора за нулиране. Ако те съответстват, той стартира да извършва ACM. Тук би трябвало да се има поради, че процесорът не може просто да ревизира ACM и по-късно да го извърши непосредствено от флаш паметта: в случай че го направи, флаш паметта може да го разпознае, да подаде удостоверения ACM за инспекция и по-късно да подаде други указания на процесора, когато той ги прочете още веднъж за осъществяване (това е добре познатата в наши дни накърнимост Time of Check vs Time of Use или TOCTOU). Това значи, че ACM би трябвало да бъде заимствуван в процесора, преди да може да бъде тестван и изпълнен, което значи, че се нуждаем от RAM, което пък значи, че процесорът към този момент би трябвало да знае по какъв начин да конфигурира кеша си, с цел да може да го употребява като RAM.

 

Както и да е. Вече изтеглихме и проверихме ACM, след което той може да бъде умерено изпълнен. ACM прави разнообразни неща, само че най-важното от позиция на Boot Guard е, че чете набор от защитни блокове с еднократен запис в чипсета на дънната платка, представляващи обществения ключ SHA256. След това той прочита първия блок на фърмуера (Initial Boot Block, или IBB) в оперативната памет (по-точно, както беше упоменато нагоре, в кеша на процесора) и го проучва. В него има блок, съдържащ обществен ключ – той хешира този ключ и ревизира дали той съответствува с SHA256 на защитните блокове. След това употребява този ключ, с цел да удостовери подписа на IBB. Ако всичко е вярно, той извършва IBB и всичко стартира да наподобява на красивия банален модел, за който говорихме нагоре.

Само че, не ви ли се коства, че целият този код е извънредно сложен за осъществяване в действителен режим? И да, осъществяването на всички тези калкулации на актуалната криптография единствено с 16-битови регистри би било доста мъчителна задача. Ето за какво това не се прави по този метод. Всичко това се случва в изцяло разумния и рационален 32-битов режим, а по-късно процесорът в действителност превключва на една ужасна настройка, с цел да резервира съвместимостта с 80386, излязъл през 1986 година „ Добрата “ вест е, че най-малко фърмуерът може да открие, че процесорът към този момент е конфигурирал кеша като оперативна памет и може да не прави това независимо.

 

Тук прескачам няколко стъпки – ACM в действителност извършва и други задания: ревизира фърмуера в TPM и конфигурира TXT за тези, които се нуждаят от DRTM, само че в резюме, процесорът се привежда в положение, в което работи като съвременен процесор, и по-късно съзнателно още веднъж се деактивират куп потребни функционалности, преди да стартира осъществяването на фърмуера. Пропускам и обстоятелството, че целият този развой стартира едвам откакто Management Engine го позволи, което значи, че чакаме изцяло самостоятелният x86 да започва цялата операционна система, преди процесорът най-малко да стартира да се преструва, че извършва систематичния фърмуер.

Разбира се, както бе упоменато нагоре, в актуалните системи фърмуерът ще препрограмира процесора в нещо по-смислено, тъй че разработчиците на операционни системи към този момент не би трябвало да се тормозят за това. Това значи, че сме прескачали сред няколко положения единствено поради вероятността някой да желае да започва legacy – доста остарял BIOS и по-късно да зареди DOS на процесор, който има пет порядъка повече транзистори от 8086.

 

Големият ми въпрос е за какво моят актуален х86 процесор не може да се разсъни непосредствено във вградения в него предпазен режим (protected mode)? Само на мен ли ми омръзнаха тези тлъсти legacy програмни пластове?

Допълнения

Само с ACPI ще пропуснем по-голямата част от кода за настройване на фърмуера, тъй че би трябвало да стартираме процесора в 16-битов режим, тъй като suspend/resume  – т.е., спирането/възстановяването всъщност е един извънредно дълъг цикъл на рестартиране А, да, и тъй като е прекомерно евентуално процесорът ви да има няколко ядра: неприятната вест за това положение е, че множеството ядра не се започват от фърмуера при стартирането на операционната система, тъй че те ще бъдат в 16-битов действителен режим, даже в случай че работещият процесор към този момент е в 64-битов предпазен режим; малко по-различна кошмарна обстановка поражда, в случай че сте употребявали TXT. По-точно, подобен беше казусът и преди, само че ACPI 6.4 (издаден през 2021 г.) има механизъм, който дава опция на операционната система да изиска от фърмуера да разсъни процесора, тъй че той да е незабележим за нея, само че в този случай фърмуерът по този начин или другояче отново ще би трябвало да извършва доста комплицирани задания

Да си напомним, че процесорът Intel 8088 излезе през далечната 1979 година и това е чипът присъединил компанията в влиятелния рейтинг топ Fortune 500. Процесорът Intel 8088 е чипът, който IBM избра за своята продуктова гама PC, което докара до доминирането на 8088 на пазара. По подигравка на ориста, чипът който стана прародителят на х86 архитектурата, не приключва на „ 86 “. Процесорът 8088 бе просто леко модифициран 8086 и първият 16-битов процесор на Intel. 

Но от този момент измина прекалено много време и е може би към този момент би трябвало да се откажем от наследените от това далечно минало похвати и способи.

Източник: kaldata.com

СПОДЕЛИ СТАТИЯТА


Промоции

КОМЕНТАРИ
НАПИШИ КОМЕНТАР