EFI Inside

Материал из Wiki.

EFI, как мало в этом звуке... Пропустим одиозные утверждения о всемогуществе оного и давно морально погибшем BIOS-е. Перейдём к "практическо-прикладной" стороне - что и как работает, где и чем с ним бороться.

/* Разбор проведём на примере биоса от Intel D945GTP */

/* Нижеизлагаемое - "в процессе" (т.е. прямо в процессе разбора), потому возможны исправления в последствии. Указания на неточности (равно как и грубые ошибки :) ) - всячески приветствуются (путём исправления здесь же). */

Старт

Плохое начинается прямо со старта.

FFFF:FFF0 wbinvd
FFFF:FFF2 jmp loc_FF00
...
FFFF:FF00 loc_FF00:
FFFF:FF00 mov esi, 0FFFFFB00h ; Start
FFFF:FF06 jmp short $+2
FFFF:FF08 mov ebp, eax  ; Save BIST
FFFF:FF0B xor eax, eax
FFFF:FF0E mov ax, cs
FFFF:FF10 mov ds, ax
FFFF:FF12 lgdt cs:qword_FF90
FFFF:FF19 mov eax, cr0
FFFF:FF1C or eax, 3
FFFF:FF20 mov cr0, eax
FFFF:FF23 mov eax, cr4
FFFF:FF26 or eax, 600h
FFFF:FF2C mov cr4, eax
FFFF:FF2F mov ax, 18h
FFFF:FF32 mov ds, ax
FFFF:FF34 mov es, ax
FFFF:FF36 mov fs, ax
FFFF:FF38 mov gs, ax
FFFF:FF3A mov ss, ax
FFFF:FF3C jmp large [fword ptr cs:byte_FF44]
...
loc_FFFFFF42:
FFFF:FF42 jmp esi ; jmp to Start
; -----------------------------------
FFFF:FF44 dd offset loc_FFFFFF42

Плохое - это переключение в защищённый режим работы. Всё - "с места - в карьер", никаких "биосных штучек".

Start:
FFFFFB00 xor eax, eax
FFFFFB02 inc eax
FFFFFB03 cpuid
FFFFFB05 mov eax, cr0
FFFFFB08 or eax, 60000000h
FFFFFB0D wbinvd
FFFFFB0F mov cr0, eax  ; Disable Cache
FFFFFB12 mov esi, offset word_FFFFFE37 ; 2FF
FFFFFB17 mov edi, 1Ch
FFFFFB1C xor eax, eax
FFFFFB1E xor edx, edx
loc_FFFFFB20:
FFFFFB20 movzx ecx, word ptr cs:[esi]
FFFFFB24 wrmsr
FFFFFB26 add esi, 2
FFFFFB29 dec edi
FFFFFB2A jnz short loc_FFFFFB20
FFFFFB2C jmp short $+2
FFFFFB2E mov dx, 0CF8h
FFFFFB32 mov eax, 8000F8D8h  ; Firmware Hub Decode Enable Register
FFFFFB37 out dx, eax
FFFFFB38 add dx, 4
FFFFFB3C mov ax, 0FFCFh  ; Default Value
FFFFFB40 out dx, ax
FFFFFB42 mov eax, offset CPU_0F43.data
...

Далее следует первичная инициализация системы, где кроме "преинициализации" микрокодов, происходит весьма хитрые манипуляции с кэшем:

...
FFFFFCE1 loc_FFFFFCE1:
FFFFFCE1 mov eax, cr0
FFFFFCE4 and eax, 9FFFFFFFh
FFFFFCE9 wbinvd
FFFFFCEB mov cr0, eax  ; Enable Cache
FFFFFCEE
FFFFFCEE cld
FFFFFCEF mov esi, 0FEF00000h
FFFFFCF4 mov edi, esi
FFFFFCF6 mov ecx, 800h
FFFFFCFB rep lodsd
FFFFFCFD mov esi, 0FEF00000h
FFFFFD02 mov edi, esi
FFFFFD04 mov ecx, 800h
FFFFFD09 mov eax, 5AA55AA5h
FFFFFD0E rep stosd
FFFFFD10
FFFFFD10 mov eax, cr0
FFFFFD13 or eax, 60000000h
FFFFFD18 mov cr0, eax  ; Disable Cache
FFFFFD1B jmp short $+2
FFFFFD1D
FFFFFD1D mov esp, 0FEF02000h ; Set ESP to CAR
FFFFFD22 xor eax, eax
FFFFFD24 inc eax
FFFFFD25 cpuid
FFFFFD27 shr ebx, 10h
FFFFFD2A and ebx, 0FFh
FFFFFD30 push ebx
FFFFFD31 cmp bl, 1
FFFFFD34 jbe short loc_FFFFFD4E
FFFFFD36 mov ecx, 203h
FFFFFD3B rdmsr
FFFFFD3D shr eax, 0Ch
FFFFFD40 push ax
FFFFFD42 mov ecx, 202h
FFFFFD47 rdmsr
FFFFFD49 shr eax, 0Ch
FFFFFD4C push ax
FFFFFD4E
FFFFFD4E loc_FFFFFD4E:

CAR - не имеет никакого отношения к машинам. Это есть режим работы системы - "Cache as RAM", когда кэш используется как память. Размер такой "халявной" памяти равняется объёму кэша второго уровня делённому на ассоциативность. Например, для Core 2 Duo это поулучится 2Мб / 8 = 256кБ (для каждого ядра отдельно) - "выше крыши".

Именно поэтому, в частности, последним идёт выключение кэша - ведь он должен "работать памятью". И именно поэтому "в туда" устанавливается стэкпоинтер. В общем, после всех таких фокусов и "внезапно появившейся" памяти - происходит стандартный (в смысле - как при наличии "реальной" памяти) переход на "начало начала":

loc_FFFFFD4E:
FFFFFD4E push ebp
FFFFFD4F push dword ptr ds:word_FFFFFFFC
FFFFFD55 push 2000h ; Stack Size
FFFFFD5A mov edi, offset _PeiMain ; PeiMain
FFFFFD5F call dword ptr [edi]

PEI

Всё, закончился ассемблер "человеческий". :) Далее лишь плоды компиляторов, потому "членораздельный" код "без полста" найти не получится. Берём в руки доступные исходники и весь остальной разбор лишь с помощью оных.

FFFF03FB PeiMain       proc near
FFFF03FB
FFFF03FB var_C = dword ptr -0Ch
FFFF03FB var_8 = dword ptr -8
FFFF03FB arg_0 = dword ptr 8
FFFF03FB arg_4 = dword ptr 0Ch
FFFF03FB
FFFF03FB push ebp
FFFF03FC mov ebp, esp  ; push ebp
FFFF03FC  ; push dword ptr ds:word_FFFFFFFC
FFFF03FC  ; push 2000h
FFFF03FE sub esp, 10h
FFFF0401 mov eax, [ebp+arg_0] ; 2000h
FFFF0404 mov [ebp+var_8], eax
FFFF0407 mov eax, [ebp+arg_4] ; ds:word_FFFFFFFC
FFFF040A mov [ebp+var_C], eax
FFFF040D
FFFF040D lea eax, [ebp-10h]
FFFF0410 push 0  ; *OldCoreData
FFFF0412 push eax  ; *PeiStartupDescriptor
FFFF0413 mov dword ptr [ebp-10h], offset xor_eax_eax
FFFF041A mov dword ptr [ebp-4], offset _EFI_SEC_PLATFORM_INFORMATION_GUID
FFFF0421 call PeiCore
; ---------------------------------------------------------------------------------------
; The entry routine to Pei Core, invoked by PeiMain during transition
; from SEC to PEI. After switching stack in the PEI core, it will restart
; with the old core data.
; Arguments:
; PeiStartupDescriptor - Information and services provided by SEC phase.
; OldCoreData - Pointer to old core data that is used to init the core's data areas.
; ---------------------------------------------------------------------------------------
FFFF0426 pop ecx
FFFF0427 pop ecx
FFFF0428 leave
FFFF0429 retn
FFFF0429 PeiMain endp

PEI - есть Pre-EFI Initialization phase. Т.е. в проекции на BIOS (в "классическом" понимания этого слова) - это код, выполняемый в бутблоке, т.е на самой начальной стадии работы компьютера, который подготавливает работу для "основной" части кода BIOS-POST / EFI-DXE (Driver Execution Environment phase).

FFFF042A PeiCore         proc near               ; CODE XREF: PeiMain+26↑p
FFFF042A  ; DATA XREF: PeiCore+238↓o
FFFF042A
FFFF042A var_84 = dword ptr -84h
FFFF042A OldCoreData = dword ptr 8
FFFF042A PeiStartupDescriptor= dword ptr 0Ch
FFFF042A
FFFF042A push ebp
FFFF042B mov ebp, esp
FFFF042D sub esp, 1A4h
FFFF0433 push ebx
FFFF0434 mov ebx, [ebp+PeiStartupDescriptor]
FFFF0437 push esi
FFFF0438 push edi
FFFF0439
FFFF0439 push [ebp+OldCoreData]
FFFF043C mov ecx, ebx
FFFF043E
FFFF043E PrivateData.PS = &mPS;
FFFF043E lea eax, [ebp-1A0h]
FFFF0444
FFFF0444 PrivateData.Signature = PEI_CORE_HANDLE_SIGNATURE;
FFFF0444 mov dword ptr [ebp-1A4h], 'CieP' ; 'PeiC' = PEI_CORE_HANDLE_SIGNATURE
FFFF044E mov dword ptr [ebp-1A0h], offset EFI_PEI_SERVICES
FFFF0458
FFFF0458 InitializeMemoryServices (&PrivateData.PS, PeiStartupDescriptor, OldCoreData);
FFFF0458 call InitializeMemoryServices
Если данная информация оказалась полезной/интересной - плюсаните, пожалуйста:

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Разрешённые HTML-теги: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd> <img>
  • You can use BBCode tags in the text. URLs will automatically be converted to links.

Подробнее о форматировании текста

Антибот - введите цифру.
Ленты новостей