Пользователь
0,0
рейтинг
9 июня 2013 в 18:00

Разработка → Доступ к скрытым настройкам UEFI BIOS от Insyde

Здравствуй Хабр!

Одно из направлений моей компании — продажа технологических решений в области виртуализации. По долгу службы, приходится делать пилотные проекты или устраивать тестовые стенды. Недавно, компания Citrix выпустила новый продукт под название XenClient XT, который по сути является клиентским гипервизором первого уровня, то есть работает на чистом железе. Основной идеей клиентского гипервизора является создание виртуальных машин на собственном ноутбуке. Где и как это применимо — опустим.

Все современные процессоры Intel и AMD поддерживают технологию аппаратной виртулизации.
И так, в моем распоряжении был ноутбук с H77 чипсетом и Intel® Core™ i7-3820QM процессором. Согласно спецификации от производителя, мой процессор поддерживал Intel® Virtualization Technology (VT-x) и Intel® Virtualization Technology for Directed I/O (VT-d) технологии. Если первая имеется почти на всех новых ноутбуках, то вторая технология встречается только на топовых моделях. Но она дает много преимуществ, как например прямой проброс GDU в виртуальную среду, соответственно клиентская машина получает полную поддержку 3D. Но давайте не будем углубляться в технологии, отличные от тематики данной статьи.

В моем биосе была возможность включения VT-x, но вот управление технологией VT-d не было предусмотрено изначально.

В расстроенных чувствах, я стал бродить по разным ресурсам в интернете и наткнулся на два очень интересных ресурса: mydigitallife и bios-mods.

Оказалось, что большая часть настроек биоса скрыта от обычного пользователя. Причина понятно — не давать пользователям ковыряться в настройках инициализации железа, дабы не создавать очереди у сервисных центров из армии любопытных «бородатых» субъектов с «кирпичами» в руках.

Первоначальное знакомство с технологией повергло меня в некоторое замешательство. Куча незнакомых мне утилит, новые термины, непонятные трактовки… Я решил не мучиться и написал на обоих ресурсах, что готов заплатить тому, кто мне поможет открыть скрытые от меня меню. Для этого было необходимо покопаться в ассемблерном коде, убрать несколько проверок, прошить патченный биос и у вас полное меню вашего биоса.

Так я прождал неделю, а заработать никто не захотел… ну или не смог.

Взяв себя в руки, я решил сам разобраться как этот биос работает и сделать патч самому. Спустя две недели и с помощью русского сообщества IXBT я написал свой первый патч к биосу моего тестового ноутбука. Скрестив пальцы на руках и с замиранием сердца я прошил свой ноутбук…

Вы помните в лохматые годы мы прошивали свои системные блоки новыми биосами для материнских плат? Тогда на экране красовалась надпись, мол ни в коем случае не выключайте компьютер до окончания прошивания? Были случаи, когда по странному стечению обстоятельств именно в тот момент отключалось электричество… В итоге получали большой не функциональный ящик. Что делалось дальше — история умалчивает.

Мой ноутбук не включился. Перебои с электричеством с батарейкой ему не страшны. Но вот я что-то сделал не правильно. Душевному расстройству не было предела. К моей большой радости оказалось, что биос имеет функцию recovery и путем нехитрых комбинаций клавиш и заранее подготовленной флешки ноутбук можно оживить.

Я пошел другим путем: пропатчил те места, которые ну ни как не могли повлиять на функционал биоса, а точнее заменил логотип. Снова прошил и снова получил кирпич. Размышляя и советуясь с опытными дельцами в этом деле мы пришли к выводу, что современные UEFI биосы имеют вторичную проверку на контрольную сумму образа прошивки. Первая проверка происходит когда вы пытаетесь прошить, а вторая когда биос запускается. Если в первом случае я также пропатчил прошивальщик, чтобы он не проверял контрольную сумму, то вторую проверку мне не преодолеть, так как она зашита в самом железе.

На данный момент имеем следующее: Можно патчить EFI биосы и не можем UEFI. Мой, конечно же, второй случай. Опять долгие поиски в интернете и натыкаюсь на статью Enable VT on InsydeH2O based Sony Vaio laptops, the EFI way.
Суть метода проста: вы загружаетесь в EFI режим с помощью специального загрузчика и получаете доступ к VSS памяти, где настройки вашего биоса и хранятся. Я протестировал что на моем ноутбуке это работает, снова открыл прекрассный дизассемблер IDA, скачал последние спецификации и в полном вооружении начал потрошить свой биос.

Успешным результатом двухнедельной работы стало выпотрошенное меню
небольшая его часть
╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ FormSet: 'Main'                                                         GUID: a04a27f4-df00-4d42-b552-39511302113d ║
╟────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╢
║ VarStore Id: '0x1234', Size: '900', Name: 'SystemConfig'                GUID: a04a27f4-df00-4d42-b552-39511302113d ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Form Name: 'Main'                                                                                  [ ID: '0x0001' ]│
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌- Grayout IF:
|    Question [ ID: '0x08' ] == 0x02
|    Question [ ID: '0x07' ] == 0x01
|    AND expression
└- END IF Grayout;
Time: 'System Time' [ QuestionId: '0x01', VarStore: '0xffff', Help: '<Enter> selects field.' ]
  Default value: '00:00:00', Type: 0x05
Date: 'System Date' [ QuestionId: '0x02', VarStore: '0xffff', Help: '<Enter> selects field.' ]
  Default value: '2010/05/01', Type: 0x06
┌- Grayout IF:
|    EQ == TRUE
|    Text: 'Notebook Model'                 Default: '[Not Detected]'                 Help: ' '
|    Text: 'Product Number'                 Default: '[Not Detected]'                 Help: ' '
|    Text: 'System Board ID'                Default: '[Not Detected]'                 Help: ' '
|    Text: 'Born On Date'                   Default: '[Not Detected]'                 Help: ' '
|    Text: 'Processor Type'                 Default: '[Not Detected]'                 Help: ' '
|    ┌- Suppress IF:
|    |    Question [ ID: '0x06' ] == 0x00
|    |    Text: 'Processor Speed'                Default: '[Not Detected]'                 Help: ' '
|    └- END IF Suppress;
|    Text: 'Total Memory'                   Default: '[Not Detected]'                 Help: ' '
|    Text: 'BIOS Version'                   Default: 'Fake Data'                      Help: ' '
|    Text: 'BIOS Vendor'                    Default: 'Insyde'                         Help: ' '
|    Text: 'Serial Number'                  Default: '[Not Detected]'                 Help: ' '
|    Text: 'UUID Number'                    Default: '[Not Detected]'                 Help: ' '
|    Text: 'Product configuration ID'       Default: '[Not Detected]'                 Help: ' '
|    Text: 'System Board CT Number'         Default: 'C AAAA RR SS WW XXX'            Help: ' '
|    Text: 'Factory installed OS'           Default: '[Not Detected]'                 Help: ' '
|    ┌- Suppress IF:
|    |    Question [ ID: '0x05' ] == 0x00
|    |    Text: 'Primary Battery SN'             Default: 'N/A'                            Help: ' '
|    └- END IF Suppress;
|    ┌- Suppress IF:
|    |    Question [ ID: '0x04' ] == 0x00
|    |    Text: 'Secondary Battery SN'           Default: ''                               Help: ' '
|    └- END IF Suppress;
|    |    |    ┌- Suppress IF:
|    |    EQ == TRUE
|    |    |    |    |    └- END IF Suppress;
└- END IF Grayout;
Reference: 'System Log' [ FormID: '0x0540', QuestionId: '0x03', VarStore: '0xffff' ]
┌- Suppress IF:
|    EQ == TRUE
|    └- END IF Suppress;
┌- Suppress IF:
|    EQ == TRUE
|    └- END IF Suppress;
┌- Suppress IF:
|    EQ == TRUE
|    └- END IF Suppress;
┌- Suppress IF:
|    EQ == TRUE
|    └- END IF Suppress;
┌- Suppress IF:
|    EQ == TRUE
|    └- END IF Suppress;
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Form Name: 'System Log'                                                                            [ ID: '0x0540' ]│
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Subtitle: 'System Log'
Action: ' '                               [ QuestionId: '0xfffe', VarStore: '0xffff', Help: View the system diagnostic failure results. ] 
Text: 'Result:'                        Default: 'Time:'                          Help: 'View the system diagnostic failure results.'
┌- Grayout IF:
|    EQ == TRUE
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
|    Text: ' '                              Default: '- No Data -'                    Help: 'View the system diagnostic failure results.'
└- END IF Grayout;
Text: ' '                              Default: ' '                              Help: 'View the system diagnostic failure results.'


╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ FormSet: 'Security'                                                     GUID: a04a27f4-df00-4d42-b552-39511302113d ║
╟────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╢
║ VarStore Id: '0x1234', Size: '900', Name: 'SystemConfig'                GUID: a04a27f4-df00-4d42-b552-39511302113d ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Form Name: 'Security'                                                                              [ ID: '0x0001' ]│
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Password: Administrator Password           [ VarStore: '0x9d', Help: 'Administrator Password controls access to the setup utility.']
Password: Power-On Password                [ VarStore: '0xa1', Help: 'Power-On Password controls access to the system at boot.']


╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ FormSet: 'Main'                                                         GUID: a04a27f4-df00-4d42-b552-39511302113d ║
╟────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╢
║ VarStore Id: '0x1234', Size: '900', Name: 'SystemConfig'                GUID: a04a27f4-df00-4d42-b552-39511302113d ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Form Name: 'Main'                                                                                  [ ID: '0x0001' ]│
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
┌- Grayout IF:
|    VALUE = 1
|    VALUE = 1
|    EQUAL expression
└- END IF Grayout;
Text: 'InsydeH2O Version'              Default: 'Fake Data'                      Help: ' '
┌- Grayout IF:
|    VALUE = 1
|    VALUE = 1
|    EQUAL expression
└- END IF Grayout;
Text: 'System Memory Speed'            Default: '[Not Detected]'                 Help: ' '
┌- Grayout IF:
|    VALUE = 1
|    VALUE = 1
|    EQUAL expression
└- END IF Grayout;
┌- Grayout IF:
|    VALUE = 1
|    VALUE = 1
|    EQUAL expression
└- END IF Grayout;
Text: 'Total Memory'                   Default: '[Not Detected]'                 Help: ' '
┌- Grayout IF:
|    Question [ ID: '0x05' ] == 0x02
|    Question [ ID: '0x04' ] == 0x01
|    AND expression
└- END IF Grayout;
Time: 'System Time' [ QuestionId: '0x01', VarStore: '0xffff', Help: 'This is the help for the hour, minute, second field. Valid range is from 0 to 23, 0 to 59, 0 to 59. INCREASE/REDUCE : +/-.' ]
  Default value: '00:00:00', Type: 0x05
Date: 'System Date' [ QuestionId: '0x02', VarStore: '0xffff', Help: 'This is the help for the month field, day field, year field. Valid range is from 1 to 12, 1 to 31, 2000 to 2099. (Error checking will be done against month/day/year combinations that are not supported.) INCREASE/REDUCE : +/-.' ]
  Default value: '2011/05/01', Type: 0x06
Action: 'About this Software'             [ QuestionId: '0x1059', VarStore: '0xffff', Help:   ] 
┌- Suppress IF:
|    LIST [ ID: '0x04' ] in ('0x00','0x01')
|    Select option: 'Debug Reclaim'                  [ VarStore: '0x1d7', QuestionId: '0x03',   Help: ' ']
|      Option: 'Enabled'                             [ Value: '1'   Default: 'false'    Type: 'int8'  ]
|      Option: 'Disabled'                            [ Value: '0'   Default: 'true'     Type: 'int8'  ]
└- END IF Suppress;
┌- Suppress IF:
|    EQ == TRUE
|    └- END IF Suppress;
┌- Suppress IF:
|    EQ == TRUE
|    └- END IF Suppress;


╔════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╗
║ FormSet: 'Advanced'                                                     GUID: a04a27f4-df00-4d42-b552-39511302113d ║
╟────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╢
║ VarStore Id: '0x1234', Size: '900', Name: 'SystemConfig'                GUID: a04a27f4-df00-4d42-b552-39511302113d ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Form Name: 'Advanced'                                                                              [ ID: '0x0001' ]│
└────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
Reference: 'Boot Configuration' [ FormID: '0x0021', QuestionId: '0x01', VarStore: '0xffff' ]
Reference: 'Peripheral Configuration' [ FormID: '0x0022', QuestionId: '0x02', VarStore: '0xffff' ]
Reference: 'IDE Configuration' [ FormID: '0x0023', QuestionId: '0x03', VarStore: '0xffff' ]
Reference: 'Thermal Configuration' [ FormID: '0x0024', QuestionId: '0x04', VarStore: '0xffff' ]
Reference: 'Video Configuration' [ FormID: '0x0025', QuestionId: '0x05', VarStore: '0xffff' ]
Reference: 'USB Configuration' [ FormID: '0x0026', QuestionId: '0x06', VarStore: '0xffff' ]
Reference: 'Chipset Configuration' [ FormID: '0x0027', QuestionId: '0x07', VarStore: '0xffff' ]
Reference: 'ACPI Table/Features Control' [ FormID: '0x0028', QuestionId: '0x08', VarStore: '0xffff' ]
Reference: 'PCI Express Configuration' [ FormID: '0x0030', QuestionId: '0x09', VarStore: '0xffff' ]
Reference: 'Intel(R) Anti-Theft Technology Support' [ FormID: '0x0038', QuestionId: '0x0a', VarStore: '0xffff' ]
Reference: 'Extended ICC' [ FormID: '0x1cc0', QuestionId: '0x0b', VarStore: '0xffff' ]
Reference: 'DPTF Configuration' [ FormID: '0x3610', QuestionId: '0x0c', VarStore: '0xffff' ]
Reference: 'Intel(R) Smart Connect Technology Configuration' [ FormID: '0x1e00', QuestionId: '0x0d', VarStore: '0xffff' ]


Я успешно загрузился в загрузчик с доступом к VSS памяти, прописал нужные мне переменные и включил или выключил чего мне не хватало или мешало в моей работе.

Ну а теперь о том как это сделать вам.

Подготовка инструментария


1. Необходимо скачать PhoenixTool с этого форума, где постоянно выкладывается текущая версия. Он вам будет нужен, чтобы разложить файл прошивки на его составляющие.
2. Вам нужен perl. Если у вас есть UNIX система, то все просто, если нет, то ActivePerl или Cygwin под Windows.
3. Вам нужен последний биос от вашего производителя.
4. Любой архиватор.

Получение образа прошивки


1. Откройте архиватором exe файл вашей прошивки, найдите там файл с расширением bin или fd и распакуйте в удобное для вас место. Лучше в отдельную папку.
2. Запустите PhoenixTool и попробуйте открыть файл прошивки.
3. Если при попытке открыть вы видите такое окно

то скорее всего ваш образ от производителя зашифрован. Decrypt метод пока не придумали, но это только дело времени. Если это ваш случай, то переходите к следующему шагу, если нет, то пропускаем и переходим к пункту 8.
4. Распакуйте программу прошивания в удобную для вас папку и запустите обновление вашего биос до последней версии.
5. После того как ваш ноутбук перезагрузится, снова зайдите в эту папку и найдите там файл platform.ini
6. Откройте текстовым редактором и сделайте слеующие изменения:
[BackupROM]
Flag=1
FilePath=c:
FileName=0183AF24.BIN
Это позволит вам прошить еще раз ваш биос, но при этом будет создана резервная копия текущего биоса.
7. После перезагрузки откройте полученную резервную копию с помощью PhoenixTool
8. Через пару секунд вы должны будете увидеть окошко похожее на это:

9. Теперь можете закрыть окошко.
10. В папке, где у вас лежал образ появится папка DUMP, а в ней множество файлов. Нас интересует, который начинается на FE3542FE и имеет самый большой размер:

11. Теперь скачиваем исходный код моего
парсера
#!/usr/bin/perl
#
# Copyright (c) 2013 Nurlan Mukhanov (aka Falseclock) <nurike@gmail.com>
#
# Please inform me if you found error/mistakes or enhance this script.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

$| = 1;

use strict;
use warnings;
use utf8;
use Encode;
use Data::Dumper;
use vars qw($ROM $ROM_SIZE $IFR_PACKAGE_SIG @EFI_HII_PACKAGES %EFI_HII_PACKAGE_TYPE %LANGUAGES @EFI_HII_PACKAGE_FORMS %EFI $DEFAULT_LANGUAGE @STRINGS @TABS %TYPES);

################### !!! IMPORTANT !!! ###################
$IFR_PACKAGE_SIG = '$IFRPKG!';
#########################################################

$DEFAULT_LANGUAGE = 'en-US';
my $file = $ARGV[0] || "Setup.rom";

&SPECIFICATION_LOAD();

#---------------------------- MAIN PROGRAMM ----------------------------#

open($ROM, "<$file ") or die "ERROR : Cannot open $file.\n";
{
	binmode $ROM;
	undef $/;
	$ROM_SIZE = -s $file;
}

#--------------------------------------------------------------------
# 1. Search IFR virtual package
my $header_offset = &IFR_PACKAGE_SIG();
print STDERR "IFR_PACKAGE_SIG not found!\nExiting programm...\n" and exit 1 if (!$header_offset);

#--------------------------------------------------------------------
# 2. Search EFI_HII_PACKAGE_HEADERs
@EFI_HII_PACKAGES = &EFI_HII_PACKAGES($header_offset);
#print Dumper(\@EFI_HII_PACKAGES);

	
#=head
#--------------------------------------------------------------------
# 3. Parse EFI_HII_PACKAGE_STRINGS
#print "Parsing language tables..\n";
%LANGUAGES = &EFI_HII_PACKAGE_STRINGS();
#printf "\tFound %d languages: %s\n", scalar keys %LANGUAGES, join ', ', sort keys %LANGUAGES;
@STRINGS = @{$LANGUAGES{$DEFAULT_LANGUAGE}->{'strings'}};

#print Dumper(\@STRINGS);
#print Dumper(\%LANGUAGES);

=head
# 3.1. Check languages length
my %length;
$length{$_} = scalar @{$LANGUAGES{$_}->{'strings'}}  foreach (keys %LANGUAGES);

my $warn = 0;

foreach (keys %length)
{
	next if $_ eq 'en-US';
	
	if ($length{$_} != $length{'en-US'})
	{
		if (!$warn)
		{
			printf STDERR "\tWARNING: languages array length is different, must be %d elements:\n", $length{'en-US'};
			$warn = 1;
		}
		printf "\t\t%s: (%d)\n", $_, $length{$_} - $length{'en-US'};
	}
}
=cut
#--------------------------------------------------------------------
# 4. FORM packages parsing
@EFI_HII_PACKAGE_FORMS = &EFI_HII_PACKAGE_FORMS();

close($ROM); 

#-----------------------------------------------------------------------#
#-----------------------------------------------------------------------#

sub str2hex {
	return unpack ("H*", shift);
}

sub dec2bin {
    return unpack("B32", pack("N", shift));
}

sub bin2dec {
    return unpack("N", pack("B32", substr("0" x 32 . shift, -32)));
}

sub oplength {
	my $data = shift;
	my $length = unpack("C", $data);
	
	return bin2dec(substr &dec2bin($length), -7);
	
}

sub EFI_IFR {
	my $data = shift;
	my $length = length($data);
	
	my @opcodes;
	
	#printf "length: %d, hex: %s\n", length($data), join (' ', unpack("(H2)*",substr($data,0,10)));
	
	my $i = 0;

	while ($i < $length)
	{
		my %op;
		
		# Reading OPCODE
		$op{'opcode'} = unpack("C", substr($data,$i,1));
		$i++;
		
		# Reading length
		$op{'length'} = oplength(substr($data,$i,1));
		$i++;

		# Reading payload
		$op{'payload'} = substr($data,$i,$op{'length'}-2);
		$i += $op{'length'} -2;

		# Setting indent
		#$op{'indent'} = $INDENTS{$op{'opcode'}};
	
		push @opcodes, \%op;
		
#		printf "Opcode: %02X, Length: %d\n",$op{'opcode'} , $op{'length'};
#		my $www = <STDIN>;
	}
		
	return \@opcodes;
}

sub EFI_HII_PACKAGE_FORMS {
	my @forms = ();
	
	foreach (@EFI_HII_PACKAGES)
	{
		my %pkg = %{$_};
		my %form;
		if ($_->{type} == 0x02)
		{
			# printf "EFI_HII_PACKAGE_FORMS offset int : %d, hex: (0x%08x)\n",$pkg{'int_offset'},$pkg{'int_offset'};
			# Skeep first 4 bytes of FULLL_PACKAGE_LENGTH
					
			my $FORM_PACKAGE_LENGTH = unpack('I', (data($pkg{int_offset} + 4, 3).pack("H",0))   );
			my $FORM_PACKAGE_TYPE = unpack('C', (data($pkg{int_offset} + 7, 1))   );

			$form{'length'} = $FORM_PACKAGE_LENGTH;
			$form{'type'} = $FORM_PACKAGE_TYPE;
			
			#printf "  Form length: %s, type: %s\n", $FORM_PACKAGE_LENGTH, $FORM_PACKAGE_TYPE;
			
			my $op_offset = $pkg{int_offset} + 8;
			my $op_length = ($FORM_PACKAGE_LENGTH - 4);
			
			$form{'opcodes'} = &EFI_IFR(data($op_offset,$op_length));
			$form{'package'} = $_;
			
			push @forms, \%form;
		}
	}
	
	&EFI_IFR_FORM_SET(\@forms);
	#print Dumper(\@forms);
	
	return @forms;
}

sub EFI_IFR_FORM_SET {
	my $forms = shift;
	my @forms = @{$forms};
	
	#print Dumper(\@forms);
	
	foreach my $form (@forms)
	{
		my %form = %{$form};
		my @ops = @{$form{'opcodes'}};
		
		foreach (@ops)
		{
			my %op = %{$_};
			&EFI_IFR_PRINT(\%op,\%{$form{'package'}});
		}
		print "\n";
	}
}

sub fguid {
	my $guid = shift;
	
	my ($a, $b, $c, $d, $e);
	
	$a = unpack("H*",scalar reverse(substr($guid,0,4)));
	$b = unpack("H*",scalar reverse(substr($guid,4,2)));
	$c = unpack("H*",scalar reverse(substr($guid,6,2)));
	$d = unpack("H*",substr($guid,8,2));
	$e = unpack("H*",substr($guid,10,6));
	
	return sprintf("%s-%s-%s-%s-%s",$a,$b,$c,$d,$e);
}

sub EFI_HII_PACKAGE_STRINGS {
	my %pkg;
	
	foreach (@EFI_HII_PACKAGES)
	{
		%pkg = %{$_} and last if ($_->{type} == 0x04);
	}
	
	my $reader= 4;  # current reading offset
	
	my %languages;
	
	while ($reader < $pkg{size}) # read until we in package
	{
		my $LANG_PACKAGE_LENGTH = unpack('I', (data($pkg{int_offset} + $reader, 3).pack("H",0))   );
		my $LANG_PACKAGE_OFFSET = $pkg{int_offset} + $reader;
		
		#print $LANG_PACKAGE_LENGTH,"\n";
		
		if ($LANG_PACKAGE_LENGTH)
		{
			$reader += (3 + 1 + 42);
			
			my $LANG_PACKAGE_NAME = (data($pkg{int_offset} + $reader, 5)); # skip 00 - end of header
			
			$languages{$LANG_PACKAGE_NAME} = {'offset' => $LANG_PACKAGE_OFFSET, 'length' => $LANG_PACKAGE_LENGTH, 'name' => $LANG_PACKAGE_NAME };
		}
		
		$reader += $LANG_PACKAGE_LENGTH - (3 + 1 + 42);
	}
	
	foreach (keys %languages)
	{
		my %lang = %{$languages{$_}};
		
		#print "Reading language from offset: ".$lang{'offset'}."\n";
		#print "Language name is: ".$lang{'name'}."\n";
		
		my $table = data($lang{'offset'}+46+6, $lang{'length'} - 46 - 6);
	
		my @table = unpack('(H2)*',$table);
		
		# Так как начало слова содержит флаг типа строки
		# и мы не можем сделать сплит всей строки, будем читать побайтно

		my @strings;
		my $position=0;
		my $word = undef;
		my $eof = 0;
		my $last = undef;
		my $skip = 0;
		my $word_start = 0;
		push @strings, undef;	# MEMEORY OFFSET CAN NOT BE 0
		
		my %EFI_HII_STRING_BLOCK = map { $_ => 1 } ('10', '11', '12', '13', '15', '16', '17', '22', '30', '31', '32', '40');
		
		for (my $l=0; $l < $#table; $l++)
		{
			my $byte = $table[$l];
			
			if ( exists($EFI_HII_STRING_BLOCK{$byte}) && !$word && $last ne '14')
			{
				print STDERR "Unexpected EFI_HII_STRING_BLOCK -> BlockType = $byte found!\n";
				printf STDERR "String offset: %d (0x%08x)\n", $lang{'offset'} + $l, $lang{'offset'} + $l;
				
				exit 1;
			}
			
			$last = $byte and $word_start = 1 and next if ($byte eq '14');		# EFI_HII_SIBT_STRING_UCS2

			if ($byte eq '21' && !$word && !$word_start )					# EFI_HII_SIBT_SKIP2
			{
				#print "SKEEP FOUND\n";
				$skip = hex($table[$l+1]);					# number of skips
				$l += 2;									# pass reading @table for next 2 bytes
				
				while ($skip)
				{
					push @strings, "EFI_HII_SIBT_SKIP2-$skip";
					$skip--;
				}
				next;
			}
			
			if ($byte eq '20' && !$word && !$word_start  )					# EFI_HII_SIBT_DUPLICATE
			{
				push @strings, $strings[$#strings];
				$l += 3;
				next;
			}
			
			# If word end
			if ($byte eq '00' && $table[$l+1] eq '00')
			{
				#print $word."\n";
				
				push @strings, $word;
				
				$word = undef;
				$word_start = 0;
				$l++;
				next;
			}
			
			$word .= decode('utf-16le',pack("H*",$byte).pack("H*",$table[$l+1]));
			
			$l++;
		}
		$languages{$_}->{'strings'} = \@strings;
	}

	return %languages;
	#print Dumper(\%languages);
}

sub EFI_HII_PACKAGES {
	my $offset = shift;
	$offset += 8;

	my @address = ();
	
	while (1)
	{
		my $data = data($offset,8);
		my $hex = unpack("H*",$data);
		last if $hex !~ /^[ABCDEF0-9]{10}000000$/i;
		
		if ($hex =~ /^[ABCDEF0-9]{6}8001000000$/i)
		{
			push @address, substr ((join '', (reverse ($hex =~ m/../g))), 10);
			
			#my $address = substr ((join '', (reverse ($hex =~ m/../g))), 10);
			#printf "$address - %s\n", hex($address);
		}
		$offset += 8;
	}
	my @pkg = ();
	foreach (@address)
	{
		my %pkg;
		$pkg{int_offset} = hex($_);
		$pkg{hex_offset} = $_;
		$pkg{size} = unpack("I*",data(hex($_),4));
		$pkg{type} = unpack("C", data( hex($_)+7 , 1 ));
		$pkg{type_name} = $EFI_HII_PACKAGE_TYPE{$pkg{type}}->{name};
		$pkg{type_text} = $EFI_HII_PACKAGE_TYPE{$pkg{type}}->{text};
		
		push @pkg, \%pkg;
	}
	
	return @pkg;
}

sub IFR_PACKAGE_SIG {
	my $i = 0;
	my $offset = 0;
	my $seek = undef;
	my @sig = split //, $IFR_PACKAGE_SIG;
	
	while ($i <= $ROM_SIZE)
	{
		my $byte = data($i,1);
		#last unless $byte;

		# If we found start of header
		if ($byte eq '$')
		{
			$offset = $i;									# Store current offset
			$seek = $byte;									# Store begining of the signature
			$i++;
			next;
		}
		
		if ($offset)										# just to save CPU time
		{
			if (scalar grep $byte eq $_, @sig)
			{
				$seek .= $byte if ($IFR_PACKAGE_SIG =~ $seek.$byte );
				last if ($IFR_PACKAGE_SIG eq $seek );
			}
			else
			{
				$offset = 0;
				$seek = undef;
			}
		}
		$i++;
	}
	
	#printf "\nIFR_PACKAGE_SIG found at offset: %d (0x%08x)\n", ($offset, $offset) if $offset;

	return $offset;
}

sub data {
	my $offset = shift;
	my $length = shift;
	my $data;
	
	seek $ROM, $offset, 0; 
	sysread $ROM, $data, $length;
	
	return $data;
};

sub TabSpace {
	# Pushing 
	push @TABS, shift;
	
	return '    ' x (scalar @TABS - 1);
}

sub TabClose {
	my $length = scalar @TABS;
	my $return = "";
	
	if ($length)
	{
		my $opcode = pop @TABS;
	
		if ($opcode == $EFI{EFI_IFR_GRAY_OUT_IF_OP})
		{
			$return = sprintf "\xE2\x94\x94- END IF Grayout;\n";
		}
		elsif ($opcode == $EFI{EFI_IFR_SUPPRESS_IF_OP})
		{
			$return = sprintf "\xE2\x94\x94- END IF Suppress;\n";
		}
		else
		{
			$return = "What the fuck?";
		}
	}
	return $return;
}

sub EFI_IFR_PRINT
{
	my $op = shift;
	my $package = shift;
	my $TabSpace = '';
	
	my %op = %{$op};
	my %package = %{$package};
	
	if ($op{'opcode'} != $EFI{EFI_IFR_FORM_SET_OP} and scalar @TABS) {
		
		if ($op{'opcode'} == $EFI{EFI_IFR_SUPPRESS_IF_OP} or $op{'opcode'} == $EFI{EFI_IFR_GRAY_OUT_IF_OP})
		{
			$TabSpace = sprintf "|";
		}
		elsif ( $op{'opcode'} == $EFI{EFI_IFR_END_OP} )
		{
			$TabSpace = sprintf  "%s",'|    ' x (scalar @TABS - 1 );
		}
		else
		{
			$TabSpace = sprintf  "%s",'|    ' x (scalar @TABS);
		}
		
		print $TabSpace;
	}

	if    ($op{'opcode'} == $EFI{EFI_IFR_FORM_SET_OP})			{	# 0x0E
		my $Guid = substr($op{'payload'},0,16);
		my $FormSetTitle = unpack("S2",substr($op{'payload'},16,2));
		my $Help = unpack("S2",substr($op{'payload'},18,2));
		my $Flags = substr($op{'payload'},20,2);
		my $ClassGuid = substr($op{'payload'},22,16);
	
		printf "\n\xE2\x95\x94%s\xE2\x95\x97\n","\xE2\x95\x90"x116;
		printf "\x{E2}\x{95}\x{91} FormSet: '%-62sGUID: %s \xE2\x95\x91\n", ($STRINGS[$FormSetTitle]."'", fguid($Guid));
		printf "\x{e2}\x{95}\x{9f}%s\x{e2}\x{95}\x{a2}\n","\x{e2}\x{94}\x{80}"x116;
		

		if ($STRINGS[$Help] and $STRINGS[$Help] ne ' ')
		{
			printf " \\Help text: '%s'\n", $STRINGS[$Help];
		}
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_GUID_OP})				{	# 0x5F
		my $Guid = substr($op{'payload'},0,16);
		my $Data = unpack("H*", substr($op{'payload'},16));
		#printf "\x{E2}\x{95}\x{91} Operation data: '%-55sGUID: %s \xE2\x95\x91\n", $Data, &fguid($Guid);
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_DEFAULTSTORE_OP})		{	# 0x5C
		my $DefaultId = unpack("S2", substr($op{'payload'},2,2));
		my $DefaultName = unpack("S2", substr($op{'payload'},2,2));
		#printf "EFI_IFR_DEFAULTSTORE_OP, length: %d, DefaultId: %s, DefaultName: %s \n",length($op{'payload'}),$DefaultId,$DefaultName ;
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_VARSTORE_OP})			{	# 0x24
		# typedef struct _EFI_IFR_VARSTORE {
		#   EFI_IFR_OP_HEADER        Header;
		#   EFI_GUID                 Guid;
		#   EFI_VARSTORE_ID          VarStoreId;
		#   UINT16                   Size;
		#   UINT8                    Name[1];
		# } EFI_IFR_VARSTORE;
		#printf "EFI_IFR_VARSTORE_OP, length: %d \n",length($op{'payload'});

		my $Guid = substr($op{'payload'},0,16);
		my $VarStoreId = unpack("S2", substr($op{'payload'},16,2));
		my $Size = unpack("S2", substr($op{'payload'},18,2));
		my $Name = substr($op{'payload'},20,12);
		
		printf "\x{E2}\x{95}\x{91} VarStore Id: '0x%x', Size: '%s', Name: '%s'                GUID: %s \x{E2}\x{95}\x{91}\n", $VarStoreId, $Size, $Name, &fguid($Guid);
		printf "\xE2\x95\x9A%s\xE2\x95\x9D\n","\xE2\x95\x90"x116;

	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_FORM_OP})				{	# 0x01
		my $FormId = unpack("S2",substr($op{'payload'},0,2));
		my $FormTitle = unpack("S2",substr($op{'payload'},2,2));
		printf "\x{e2}\x{94}\x{8c}%s\x{e2}\x{94}\x{90}\n","\x{e2}\x{94}\x{80}"x116;
		printf "\x{e2}\x{94}\x{82} Form Name: '%-86s [ ID: '0x%04x' ]\x{e2}\x{94}\x{82}\n", ($STRINGS[$FormTitle]."'", $FormId);
		printf "\x{e2}\x{94}\x{94}%s\x{e2}\x{94}\x{98}\n","\x{e2}\x{94}\x{80}"x116;
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_GRAY_OUT_IF_OP})		{	# 0x19
		printf "%s\x{E2}\x{94}\x{8C}- Grayout IF:\n",TabSpace($op{'opcode'});
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_SUPPRESS_IF_OP})		{	# 0x0A
		printf "%s\xE2\x94\x8C- Suppress IF:\n",TabSpace($op{'opcode'});
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_END_OP})				{	# 0x29
		printf "%s",&TabClose($op{'opcode'});
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_EQ_ID_VAL_OP})			{	# 0x12
		my $QuestionId =  unpack("S2",substr($op{'payload'},0,2));
		my $Value =  unpack("S2",substr($op{'payload'},2,2));
		printf "Question [ ID: '0x%02x' ] == 0x%02x\n", $QuestionId, $Value,;
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_AND_OP})				{	# 0x15
		printf "AND expression\n";
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_SUBTITLE_OP})			{	# 0x02
		my $Prompt = unpack("S2",substr($op{'payload'},0,2));
		my $Help = unpack("S2",substr($op{'payload'},2,2));

		printf "Subtitle: '%s'\n", ($STRINGS[$Prompt]) if defined $STRINGS[$Prompt] and $STRINGS[$Prompt] ne ' ';
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_DEFAULT_OP})			{	# 0x5B
		my $DefaultId = unpack("S2",substr($op{'payload'},0,2));
		my $Type = unpack("C",substr($op{'payload'},2,1));
		my $value;
		if ($Type == 0) {
			$value = unpack("C",substr($op{'payload'},3,1));
		} 
		elsif ($Type == 1) {
			$value = unpack("S2",substr($op{'payload'},3,2));
		}
		elsif ($Type == 2) {
			$value = unpack("S2",substr($op{'payload'},3,2));
		}
		elsif ($Type == 5) {
			$value = sprintf("%02d",unpack("C",substr($op{'payload'},3,1))).':'.sprintf("%02d",unpack("C",substr($op{'payload'},4,1))).':'.sprintf("%02d",unpack("C",substr($op{'payload'},5,1)));
		}
		elsif ($Type == 6) {
			$value = unpack("S2",substr($op{'payload'},3,2)).'/'.sprintf("%02d",unpack("C",substr($op{'payload'},5,1))).'/'.sprintf("%02d",unpack("C",substr($op{'payload'},6,1)));
		}
		else {
			$value = unpack("S*",substr($op{'payload'},3,4));
		}
		printf "  Default value: '%s', Type: 0x%02x\n",$value, $Type;
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_TRUE_OP})				{	# 0x46
		printf "EQ == TRUE\n";
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_TEXT_OP})				{	# 0x03
		my $Prompt = unpack("S2",substr($op{'payload'},0,2));
		my $Help = unpack("S2",substr($op{'payload'},2,2));
		my $TextTwo = unpack("S2",substr($op{'payload'},4,2));
		my $t2 = "";
		$t2 = $STRINGS[$TextTwo] if (defined $STRINGS[$TextTwo]);
		printf "Text: '%-32.32sDefault: '%-32.32sHelp: '%s'\n", $STRINGS[$Prompt]."'", $t2."'", $STRINGS[$Help];
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_UINT64_OP})			{	# 0x45
		my $Value = $op{'payload'};
		printf "VALUE = %s\n", unpack("S*",$Value);
		
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_EQUAL_OP})				{	# 0x2F
		printf "EQUAL expression\n";
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_EQ_ID_LIST_OP})		{	# 0x14

		my $QuestionId = unpack("S2", substr($op{'payload'},0,2));
		my $ListLength = unpack("S2", substr($op{'payload'},2,2));
		my @ValueList = unpack("(S4)*", substr($op{'payload'},4));
		@ValueList = map {sprintf "'0x%02x'", $_ } @ValueList;
		
		printf "LIST [ ID: '0x%02x' ] in (%s)\n",$QuestionId, join ",", @ValueList;
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_OR_OP})				{	# 0x16
		printf "OR expression\n";
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_NOT_OP})				{	# 0x17
		printf "NOT expression \n";
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_TIME_OP})				{# 0x1b
		my $Prompt = unpack("S2",substr($op{'payload'},0,2));
		my $Help = unpack("S2",substr($op{'payload'},2,2));
		my $QuestionId = unpack("S2",substr($op{'payload'},4,2));
		my $VarStoreId = unpack("S2",substr($op{'payload'},8,2));
		
		#my $VarName = unpack("S2",substr($op{'payload'},8,1));
		#my $VarOffset = unpack("S2",substr($op{'payload'},9,1));
		#my $Flags = unpack("S2",substr($op{'payload'},9,1));
	
		printf "Time: '%s' [ QuestionId: '0x%02x', VarStore: '0x%02x', Help: '%s' ]\n", $STRINGS[$Prompt],$QuestionId,$VarStoreId,$STRINGS[$Help] ;		
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_DATE_OP})				{# 0x1A
		my $Prompt = unpack("S2",substr($op{'payload'},0,2));
		my $Help = unpack("S2",substr($op{'payload'},2,2));
		my $QuestionId = unpack("S2",substr($op{'payload'},4,2));
		my $VarStoreId = unpack("S2",substr($op{'payload'},8,2));
		
		#my $VarName = unpack("S2",substr($op{'payload'},8,1));
		#my $VarOffset = unpack("S2",substr($op{'payload'},9,1));
		#my $Flags = unpack("S2",substr($op{'payload'},9,1));
	
		printf "Date: '%s' [ QuestionId: '0x%02x', VarStore: '0x%02x', Help: '%s' ]\n", $STRINGS[$Prompt],$QuestionId,$VarStoreId,$STRINGS[$Help] ;	
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_NUMERIC_OP})			{# 0x07
		my $Prompt = unpack("S2",substr($op{'payload'},0,2));
		my $Help = unpack("S2",substr($op{'payload'},2,2));
		my $QuestionId = unpack("S2",substr($op{'payload'},4,2));
		my $VarStoreId = unpack("S2",substr($op{'payload'},8,2));
		#my $VarStoreInfo = unpack("C",substr($op{'payload'},10,1));

		my $Type = unpack("C",substr($op{'payload'},11,1));
		my $MinValue = unpack("C",substr($op{'payload'},12,1));
		my $MaxValue = unpack("C",substr($op{'payload'},13,1));
		my $Step = unpack("C",substr($op{'payload'},14,1));

		printf "Number question: Prompt: %s, Help: %s\n",($STRINGS[$Prompt], $STRINGS[$Help]) if $Prompt;
		printf "%s \x{E2}\x{94}\x{94}- [ QuestionId: '0x%02x', VarStore: '0x%02x' , Type: '%02x', MinValue: '%d', MaxValue: '%d', Step: '%d' ]\n",($TabSpace,$QuestionId, $VarStoreId, $Type,$MinValue, $MaxValue, $Step) if $Prompt;;
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_REF_OP})				{# 0x0F
		my $Prompt = unpack("S2",substr($op{'payload'},0,2));
		my $Help = unpack("S2",substr($op{'payload'},2,2));
		my $QuestionId = unpack("S2",substr($op{'payload'},4,2));
		my $VarStoreId = unpack("S2",substr($op{'payload'},8,2));
		
		my $FormId = unpack("S2>*!",substr($op{'payload'},11,4));
		
		printf "Reference: '%s' [ FormID: '0x%04x', QuestionId: '0x%02x', VarStore: '0x%02x' ]\n", $STRINGS[$Prompt], $FormId, $QuestionId, $VarStoreId;
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_ACTION_OP})			{# 0x0C
		my $Prompt = unpack("S2",substr($op{'payload'},0,2));
		my $Help = unpack("S2",substr($op{'payload'},2,2));
		my $QuestionId = unpack("S2",substr($op{'payload'},4,2));
		my $VarStoreId = unpack("S2",substr($op{'payload'},8,2));
		#my $VarStoreInfo = unpack("C",substr($op{'payload'},8,1));
		
		printf "Action: '%-32.32s [ QuestionId: '0x%02x', VarStore: '0x%02x', Help: %s ] \n", ($STRINGS[$Prompt]."'", $QuestionId,$VarStoreId, $STRINGS[$Help]);
		#printf "%s \x{E2}\x{94}\x{94}- \n", ($TabSpace if $STRINGS[$Prompt];
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_PASSWORD_OP})			{# 0x08
		my $Prompt = unpack("S2", substr($op{'payload'},0,2));
		my $Help    = unpack("S2", substr($op{'payload'},2,2));
		my $VarStoreId = unpack("S2", substr($op{'payload'},8,2));
		printf "Password: %-32.32s [ VarStore: '0x%02x', Help: '%s']\n", ($STRINGS[$Prompt], $VarStoreId, $STRINGS[$Help]);
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_ONE_OF_OP}) {			# 0x05
		my $Prompt = unpack("S2", substr($op{'payload'},0,2));
		my $Help    = unpack("S2", substr($op{'payload'},2,2));
		my $QuestionId = unpack("S2", substr($op{'payload'},4,2));
		my $VarStoreId = unpack("S2", substr($op{'payload'},8,2));
#		my $VarOffset    = unpack("S2", substr($op{'payload'},4,2));
		
		printf "Select option: '%-32.32s[ VarStore: '0x%02x', QuestionId: '0x%02x',   Help: '%s']\n", ($STRINGS[$Prompt]."'", $VarStoreId, $QuestionId, (defined $STRINGS[$Help] ? $STRINGS[$Help] : '' ));
	}
	elsif ($op{'opcode'} == $EFI{EFI_IFR_ONE_OF_OPTION_OP}) {	# 0x09
		my $Option	= unpack("S2", substr($op{'payload'},0,2));
		my $Flags	= str2hex(substr($op{'payload'},2,1));
		my $Type	= unpack("C", substr($op{'payload'},3,1));
		my $Value	= unpack("C*", substr($op{'payload'},4,8));

#			oid, value, flags, key = struct.unpack("<HHBH", self.payload)
#			print ts+"Option '%s' = 0x%x Flags 0x%x Key 0x%x"%(s[oid], value, flags, key)
		
		printf "  Option: '%-37.37s[ Value: '%s'   Default: '%-6s    Type: '%-6.6s ]\n", ($STRINGS[$Option]."'", $Value, ($Flags eq '10' ? 'true' : 'false')."'", $TYPES{$Type}."'");

	}
	else {
		printf "--> UNKNOWN OPCODE: %02X, length: %d\n", $op{'opcode'}, $op{'length'};
		exit 1;
	}
}

sub SPECIFICATION_LOAD
{
	$EFI{EFI_IFR_FORM_OP}                 = 0x01;
	$EFI{EFI_IFR_SUBTITLE_OP}             = 0x02;
	$EFI{EFI_IFR_TEXT_OP}                 = 0x03;
	$EFI{EFI_IFR_IMAGE_OP}                = 0x04;
	$EFI{EFI_IFR_ONE_OF_OP}               = 0x05;
	$EFI{EFI_IFR_CHECKBOX_OP}             = 0x06;
	$EFI{EFI_IFR_NUMERIC_OP}              = 0x07;
	$EFI{EFI_IFR_PASSWORD_OP}             = 0x08;
	$EFI{EFI_IFR_ONE_OF_OPTION_OP}        = 0x09;
	$EFI{EFI_IFR_SUPPRESS_IF_OP}          = 0x0A;
	$EFI{EFI_IFR_LOCKED_OP}               = 0x0B;
	$EFI{EFI_IFR_ACTION_OP}               = 0x0C;
	$EFI{EFI_IFR_RESET_BUTTON_OP}         = 0x0D;
	$EFI{EFI_IFR_FORM_SET_OP}             = 0x0E;
	$EFI{EFI_IFR_REF_OP}                  = 0x0F;
	$EFI{EFI_IFR_NO_SUBMIT_IF_OP}         = 0x10;
	$EFI{EFI_IFR_INCONSISTENT_IF_OP}      = 0x11;
	$EFI{EFI_IFR_EQ_ID_VAL_OP}            = 0x12;
	$EFI{EFI_IFR_EQ_ID_ID_OP}             = 0x13;
	$EFI{EFI_IFR_EQ_ID_LIST_OP}           = 0x14;
	$EFI{EFI_IFR_AND_OP}                  = 0x15;
	$EFI{EFI_IFR_OR_OP}                   = 0x16;
	$EFI{EFI_IFR_NOT_OP}                  = 0x17;
	$EFI{EFI_IFR_RULE_OP}                 = 0x18;
	$EFI{EFI_IFR_GRAY_OUT_IF_OP}          = 0x19;
	$EFI{EFI_IFR_DATE_OP}                 = 0x1A;
	$EFI{EFI_IFR_TIME_OP}                 = 0x1B;
	$EFI{EFI_IFR_STRING_OP}               = 0x1C;
	$EFI{EFI_IFR_REFRESH_OP}              = 0x1D;
	$EFI{EFI_IFR_DISABLE_IF_OP}           = 0x1E;
	$EFI{EFI_IFR_ANIMATION_OP}            = 0x1F;
	$EFI{EFI_IFR_TO_LOWER_OP}             = 0x20;
	$EFI{EFI_IFR_TO_UPPER_OP}             = 0x21;
	$EFI{EFI_IFR_MAP_OP}                  = 0x22;
	$EFI{EFI_IFR_ORDERED_LIST_OP}         = 0x23;
	$EFI{EFI_IFR_VARSTORE_OP}             = 0x24;
	$EFI{EFI_IFR_VARSTORE_NAME_VALUE_OP}  = 0x25;
	$EFI{EFI_IFR_VARSTORE_EFI_OP}         = 0x26;
	$EFI{EFI_IFR_VARSTORE_DEVICE_OP}      = 0x27;
	$EFI{EFI_IFR_VERSION_OP}              = 0x28;
	$EFI{EFI_IFR_END_OP}                  = 0x29;
	$EFI{EFI_IFR_MATCH_OP}                = 0x2A;
	$EFI{EFI_IFR_GET_OP}                  = 0x2B;
	$EFI{EFI_IFR_SET_OP}                  = 0x2C;
	$EFI{EFI_IFR_READ_OP}                 = 0x2D;
	$EFI{EFI_IFR_WRITE_OP}                = 0x2E;
	$EFI{EFI_IFR_EQUAL_OP}                = 0x2F;
	$EFI{EFI_IFR_NOT_EQUAL_OP}            = 0x30;
	$EFI{EFI_IFR_GREATER_THAN_OP}         = 0x31;
	$EFI{EFI_IFR_GREATER_EQUAL_OP}        = 0x32;
	$EFI{EFI_IFR_LESS_THAN_OP}            = 0x33;
	$EFI{EFI_IFR_LESS_EQUAL_OP}           = 0x34;
	$EFI{EFI_IFR_BITWISE_AND_OP}          = 0x35;
	$EFI{EFI_IFR_BITWISE_OR_OP}           = 0x36;
	$EFI{EFI_IFR_BITWISE_NOT_OP}          = 0x37;
	$EFI{EFI_IFR_SHIFT_LEFT_OP}           = 0x38;
	$EFI{EFI_IFR_SHIFT_RIGHT_OP}          = 0x39;
	$EFI{EFI_IFR_ADD_OP}                  = 0x3A;
	$EFI{EFI_IFR_SUBTRACT_OP}             = 0x3B;
	$EFI{EFI_IFR_MULTIPLY_OP}             = 0x3C;
	$EFI{EFI_IFR_DIVIDE_OP}               = 0x3D;
	$EFI{EFI_IFR_MODULO_OP}               = 0x3E;
	$EFI{EFI_IFR_RULE_REF_OP}             = 0x3F;
	$EFI{EFI_IFR_QUESTION_REF1_OP}        = 0x40;
	$EFI{EFI_IFR_QUESTION_REF2_OP}        = 0x41;
	$EFI{EFI_IFR_UINT8_OP}                = 0x42;
	$EFI{EFI_IFR_UINT16_OP}               = 0x43;
	$EFI{EFI_IFR_UINT32_OP}               = 0x44;
	$EFI{EFI_IFR_UINT64_OP}               = 0x45;
	$EFI{EFI_IFR_TRUE_OP}                 = 0x46;
	$EFI{EFI_IFR_FALSE_OP}                = 0x47;
	$EFI{EFI_IFR_TO_UINT_OP}              = 0x48;
	$EFI{EFI_IFR_TO_STRING_OP}            = 0x49;
	$EFI{EFI_IFR_TO_BOOLEAN_OP}           = 0x4A;
	$EFI{EFI_IFR_MID_OP}                  = 0x4B;
	$EFI{EFI_IFR_FIND_OP}                 = 0x4C;
	$EFI{EFI_IFR_TOKEN_OP}                = 0x4D;
	$EFI{EFI_IFR_STRING_REF1_OP}          = 0x4E;
	$EFI{EFI_IFR_STRING_REF2_OP}          = 0x4F;
	$EFI{EFI_IFR_CONDITIONAL_OP}          = 0x50;
	$EFI{EFI_IFR_QUESTION_REF3_OP}        = 0x51;
	$EFI{EFI_IFR_ZERO_OP}                 = 0x52;
	$EFI{EFI_IFR_ONE_OP}                  = 0x53;
	$EFI{EFI_IFR_ONES_OP}                 = 0x54;
	$EFI{EFI_IFR_UNDEFINED_OP}            = 0x55;
	$EFI{EFI_IFR_LENGTH_OP}               = 0x56;
	$EFI{EFI_IFR_DUP_OP}                  = 0x57;
	$EFI{EFI_IFR_THIS_OP}                 = 0x58;
	$EFI{EFI_IFR_SPAN_OP}                 = 0x59;
	$EFI{EFI_IFR_VALUE_OP}                = 0x5A;
	$EFI{EFI_IFR_DEFAULT_OP}              = 0x5B;
	$EFI{EFI_IFR_DEFAULTSTORE_OP}         = 0x5C;
	$EFI{EFI_IFR_FORM_MAP_OP}             = 0x5D;
	$EFI{EFI_IFR_CATENATE_OP}             = 0x5E;
	$EFI{EFI_IFR_GUID_OP}                 = 0x5F;
	$EFI{EFI_IFR_SECURITY_OP}             = 0x60;

	%EFI_HII_PACKAGE_TYPE = 
	(
		0x00	=> { name => 'EFI_HII_PACKAGE_TYPE_ALL'				, text => 'Pseudo-package type' },
		0x01	=> { name => 'EFI_HII_PACKAGE_TYPE_GUID'			, text => 'Package type where the format of the data is specified using a GUID immediately following the package header' },	
		0x02	=> { name => 'EFI_HII_PACKAGE_FORMS'				, text => 'Forms package' },
		0x04	=> { name => 'EFI_HII_PACKAGE_STRINGS'				, text => 'Strings package' },
		0x05	=> { name => 'EFI_HII_PACKAGE_FONTS'				, text => 'Fonts package' },
		0x06	=> { name => 'EFI_HII_PACKAGE_IMAGES'				, text => 'Images package' },
		0x07	=> { name => 'EFI_HII_PACKAGE_SIMPLE_FONTS'			, text => 'Simplified (8x19, 16x19) Fonts package' },
		0x08	=> { name => 'EFI_HII_PACKAGE_DEVICE_PATH'			, text => 'Binary-encoded device path' },
		0x09	=> { name => 'EFI_HII_PACKAGE_KEYBOARD_LAYOUT'		, text => 'Used to mark the end of a package list' },
		0x0A	=> { name => 'EFI_HII_PACKAGE_ANIMATIONS'			, text => 'Animations package' },
		0xDF	=> { name => 'EFI_HII_PACKAGE_END'					, text => 'Package types reserved for use by platform firmware implementations' },
		0xE0	=> { name => 'EFI_HII_PACKAGE_TYPE_SYSTEM_BEGIN'	, text => 'Package types reserved for use by platform firmware implementations' },
	);

%TYPES = 
(
	0x00 => 'int8',
    0x01 => 'int16',
    0x02 => 'int32',
    0x03 => 'int64',
    0x04 => 'bool',
    0x05 => 'time',
    0x06 => 'date',
    0x07 => 'string',
	0x08 => 'other',
);
}

12. Сохраняете его себе на компьютер туда, где у вас лежит файл из пункта 10 и даете ему удобное для вас название, например uefidump.pl
13. Переходите в консольный режим и даете команду perl uefidump.pl FE3542FE-C1D3-4EF8-657C-8048606FF670_2_514.ROM > uefidump.log
14. По окончанию вы найдете дамп меню вашего биоса в файле uefidump.log.

Подготовка загрузочной дискеты

1. Берем флешку, размер не важен.
2. Форматируем ее в FAT32
3. Создаем структуру каталогов EFI\Boot
4. Скачиваем BOOTX64.EFI
5. Кладем в папку Boot
6. Перегружаемся в BIOS, включаем Legacy и отключаем Secure Boot.
7. Сохраняемся и загружаемся через флешку.
8. После загрузки вы должны увидеть желтый текст на черном экране
> Welcome to GRUB!
>
> Entering rescue mode...
> error: file not found
> grub rescue
>

9. К модификации настройки биоса все готово.

Изменение параметров

Для изменений используются поля VarStore и Value. Value в логе в десятичном варианте, при изменении необходимо указывать шестнадцатиричное значение.

1. Допустим вам надо изменить режим работы диска с IDE на AHCI. Кому-то это надо для хакинтошей, а кто-то купил себе твердотельный жесткий диск, а ноутбук его не видит. Ищем в лог файле что что касается сабжа и находим следующие строки:
Select option: 'HDC Configure As'               [ VarStore: '0x39', QuestionId: '0x1a',   Help: 'Set Harddisk Controller Configure Type']
  Option: 'IDE'                                 [ Value: '0'   Default: 'true'     Type: 'int8'  ]
  Option: 'AHCI'                                [ Value: '1'   Default: 'false'    Type: 'int8'  ]
  Option: 'RAID'                                [ Value: '2'   Default: 'false'    Type: 'int8'  ]

Для того чтобы вам изменить настройку, необходимо сперва дать команду setup_var 0x39.
Результатом данной команды будет текущее значение данной переменной. Чтобы ее изменить и поставить в AHCI, надо дать команду setup_var 0x39 0x1. Учтите, что если у вас стоит Windows, то потребуется его переустановка, так как однажды настроенный Windows на IDE не сможет понять, что теперь ему надо работать с AHCI. Как вариант — предварительно загрузившись в безопасный режим подредактировать реестр, тогда переустанавливать ничего не придется.

2. Например вам надо запретить дискретный видеоадаптер. За этот пункт отвечает следующие строки:
Select option: 'Special Features'               [ VarStore: '0x1e6', QuestionId: '0x92',   Help: 'Enable Switch Graphic Function']
  Option: 'Disabled'                            [ Value: '0'   Default: 'false'    Type: 'int8'  ]
  Option: 'Enabled'                             [ Value: '1'   Default: 'true'     Type: 'int8'  ]
Команда setup_var 0x1e6 0x0 отключит дискретный и будет работать только встроенный.

3. Хотим чтобы Numlock не включался
Select option: 'Numlock'                        [ VarStore: '0x08', QuestionId: '0x10',   Help: 'Selects Power-on state for Numlock']
  Option: 'Off'                                 [ Value: '0'   Default: 'false'    Type: 'int8'  ]
  Option: 'On'                                  [ Value: '1'   Default: 'true'     Type: 'int8'  ]
Команда setup_var 0x08 0x0 отключит его при загрузке.

Эпилог


Данное руководство составлено как оно есть и так как я делаю это на практике. Я не несу ответственности за испорченные материнские платы или утерянную информацию. Все что мы можете сделать — вы делаете на свой страх и риск.

Если что-то пошло не так, то первым спасательным кругом может быть извлечение батарейки биоса для стирания VSS памяти. Если не помогает, то вам нужно искать способ recovery для вашего биоса. В случае HP инструкцию можно посмотреть здесь. Для других вендоров там же, но я не искал.

Моя тема, где я нет, нет помогаю страждущим находится здесь. Благодарности от пользователей в доказательство тому, что это все работает.

И последнее, не пытайтесь отключить оборудование, которое у вас имеется или включить то, которого у вас нет, иначе сбой инициализации оборудования приведет к полном краху и невозможности восстановления материнской платы.

И самое последнее, мой вам совет: прежде чем начинать экспериментировать с оверклокингом и тюнингом биоса, проверьте, что для вашего ноутбука работает способ восстановления биоса в случае его краха. Пока таких случаев не было, но мало ли.
Нурлан Муханов @Falseclock
карма
59,0
рейтинг 0,0
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (80)

  • +6
    Хабр торт!
    Скажите, а возможно ли аналогичное на десктопных материнках?
    иногда там тоже настроек, что кот наплакал.
    • 0
      Да, возможно.

      Я не могу точно сказать будет ли данный метод работать на AMI, Phoenix, и других биосах, так как не тестировал.
      Но если ваш на десктопе UEFI и от Insyde, то должно.
    • 0
      Обычно да. Надо искать информацию по производителю этого BIOS'a.
    • 0
      Можно редактировать некоторые настройки AMI Aptio4 UEFI (на нем сейчас почти все современные десктопные платы) с помощью утилиты AMIBCP 4. Жаль только, что далеко не все.

      Автору темы респект, отличный проект.
      Я тоже сейчас неспеша занимаюсь темой патча UEFI: пишу поддержку новых БИОСов для плат на Z87 в PMPatch (это патчер для снятия защиты от записи с регистра 0xE2, которая не дает загружаться драйверу CPUPM из OS X).

  • 0
    Замечательно. Совсем недавно озадачился на похожую тему. У моего ноута после обновления прошивки перестал работать режим Sata-3 (ssd вместо 400МБ/с стал выдавать жалкие 250). Уже веду поиски своего параметра с помощью вашей программы и сравнения двух последних версий биоса =)
    Скажите, а вывод скрытых первоначально параметров в UEFI не реализуем?
    • 0
      берете старый биос и новый, дампите настройки у обоих, а потом сравниваете )
      ну и касательно скорости, в биосе есть параметр под тип

      Select option: '  SATA Device Type'             [ VarStore: '0x327', QuestionId: '0x20',   Help: 'Identify Solid state Drive or Hard Disk Drive']
        Option: 'Hard Disk Drive'                     [ Value: '0'   Default: 'true'     Type: 'int8'  ]
        Option: 'Solid State Drive'                   [ Value: '1'   Default: 'false'    Type: 'int8'  ]
      


      и в некоторых видах биоса видл настройки с выбором SATA II или SATA III
      • 0
        берете старый биос и новый, дампите настройки у обоих, а потом сравниваете )
        именно так я и делаю ) diff никто не отменял ;-) правда у меня отличия только в hdd pass вывело. Нашел про SSD — попробую изменить. Премного благодарен
        • 0
          будьте осторожны. Ссылки и методы восстановления биоса в статье.
  • 0
    Есть проблема на маке (mac mini 2010) с виртуализацией. При запуске гипервизора на виртуальной машине появлятся ошибка что vt-x не активирован, виртуализация не поддерживается. Просмотрел много постов, была рекомендация обновить uefi до последней версии (уже давно сделано), либо загрузиться с образа, подменить бинарники. Последний способ не смог обновиться корректно, при этом убив загрузку с жесткого диска. Уже сделал восстановление, все работает, но виртуализация так и не запустилась. Это очень странно, что мак не поддерживает эти инструкции.
    • 0
      Скорее всего поддерживают, но в биосе отключено. в 2010 годах все вендоры этот пункт отключали.
      • 0
        на самом деле, Apple конечно говорит об этом, но их способ для меня не работает support.apple.com/kb/TS2744
        • 0
          А процессор у вас какой? Смотрели спеку на intel.com? Биос от какого вендора?
          • 0
            Процессор Intel Core Duo и cpuinfo говорит что проц поддерживает виртуализацию. Но проблема в биосе, где эта функция залочена.
            • 0
              то что может говорить cpuinfo или Aida64 не всегда правда.



              может у вас как раз тот, который не поддерживает VT-x?

              ark.intel.com/Products/VirtualizationTechnology
              • 0
                Инфа по моему Маку:
                Model Name: Mac mini
                Model Identifier: Macmini4,1
                Processor Name: Intel Core 2 Duo
                Processor Speed: 2,4 GHz
                Number of Processors: 1
                Total Number of Cores: 2
                L2 Cache: 3 MB
                Memory: 8 GB
                Bus Speed: 1,07 GHz
                Boot ROM Version: MM41.0042.B03
                SMC Version (system): 1.65f2

                Здесь спека по моей модели: www.everymac.com/systems/apple/mac_mini/specs/mac-mini-core-2-duo-2.4-mid-2010-specs.html

                У меня проц P8600, vt-x поддерживается, ep-t нет.
                • 0
                  я распотрошил ваш биос, который был по ссылке support.apple.com/kb/TS2744, но там нет меню. Это похоже не полный биос, а апдейт отдельных модулей.
                  Где можно взять полный вариант биоса?
                  • 0
                    посмотрите эту ссылку, не уверен что это полная версия — support.apple.com/kb/DL1479
                    • 0
                      я скачал, но что-то у меня под виндой плохо распаковывается.
                      Вы можете сами все кишки распаковать и скинуть мне в нормальном зипе?
                      • 0


                        Сохраните как .zip, внутри распакованный dmg, pkg, его payload и bom.
                        • 0
                          В смысле изображение с яблочком сохраните и смените расширение на .zip, если что.
                        • 0
                          Как сделать zip архив в виде png?
                          • 0
                            Допишите архив в хвост PNG-файлу. Для ZIP, RAR и 7Z это выглядит, как распаковка SFX-архива. Для PNG и JPEG это выглядит как игнорируемый мусор после конца файла.
                            • 0
                              Спасибо, не знал
  • +1
    берете старый биос и новый, дампите настройки у обоих, а потом сравниваете )
    ну и касательно скорости, в биосе есть параметр под тип

    Select option: '  SATA Device Type'             [ VarStore: '0x327', QuestionId: '0x20',   Help: 'Identify Solid state Drive or Hard Disk Drive']
      Option: 'Hard Disk Drive'                     [ Value: '0'   Default: 'true'     Type: 'int8'  ]
      Option: 'Solid State Drive'                   [ Value: '1'   Default: 'false'    Type: 'int8'  ]
    


    и в некоторых видах биоса видл настройки с выбором SATA II или SATA III
  • 0
    Для меня сложновато… блин
    • 0
      а вы попробуйте. сложного ничего нет, все просто на самом то деле.
      • 0
        Ну вот остановился на П10. Нет у меня файлов начинающихся на FE3542FE
        Подскажите, вообще что значат эти файлы )
        • 0
          вполне вероятно.

          дайте ссылку на ваш биос. у вас скорее всего не Inside и GUID отличается от привычного.
          • 0
            Сейчас пытаюсь вашим скриптом разобрать все ромы подряд, пока ничего
            P8Z77-V BIOS 2003
            На все сыпет «IFR_PACKAGE_SIG not found! Exiting programm...».
            В скрипт не вникал пока, отчасти потому что с перлом не знаком
            • 0
              Сильные сомнения, что там Insyde…
              • 0
                так и есть, Insyde, только старый, EFI 2.1 версии
            • +1


              Видите Setup написано?
              начинается с 899407D7

              сейчас попробуем распаковать
            • +1
              все правильно, у вас БИОС старой версии, не UEFI.
              соответственно спецификация не та.

              Вы скажите, что хотите в своем биосе сделать? Может я смогу вам помочь
              • 0
                Очень бы хотелось попытаться включить VT-D ( тот который Directed I/O, а не простая виртуализация VT-X),
                Суть в том, что многие матери на Z77 его поддерживают, и Intel в части документации тоже говорит что оно работает для всей линейки чипсетов. Но почему-то на сайте ARK указано, что поддержки нет (хотя много примеров на тех же ASROCK-ах)
              • 0
                В общем-то на Q77 он точно есть, вроде и биосы похожи кроме расцветки
                Скрытый текст
                • 0
                  ах вот оно что, то-то я понять не могу почему не вижу в Setup menu ассемблерного кода. У вас биос графический.
                  поищите на форумах, что в статье, скорее всего для вашего биоса есть патченная версия с раскрытыми менюшками
                  • 0
                    Нету )) Уже искал )
                    Подскажите, куда копать, пожалуйста.
                  • 0
                    [irony] Зато за 2 часа я нашел где фоновый рисунок биоса поменять [/irony]
                    • 0
                      поменять можно и сам интерфейс. картинки одна за другой хранятся в одном из файлов
                  • 0
                    Вопрос: Я тут заметил, что UUID-ы блоков (или как там правильно их) свпадают с UUID-ами в прошивке от другой матери, где данный функционал меется. Есть ли смысл попробовать импортировать из прошивки Q77 в Z77 и прошиться? Никакие цифровые подписи не требуются (или нужны)?
                    • 0
                      любые цифровые подписи можно обойти, а вот от чужого биоса прошивать бы не советовал, разве что на доннорском ноутбуке, если его не жалко убить.
      • 0
        Просто риск получить кирпичик ценой 30 кило обычно вызывает ненужную дрожь в руках.
        • 0
          прецедентов за прошедшее время еще не было.
  • +1
    Я так понимаю, что настройки сделаны в БИОСе, но просто скрыты? Если да, то неужели не утекает прошивок, где они разблокированы?
    • 0
      Правильно понимаете. Может и утекают, но нигде они не появляются.
  • 0
    • 0
      К чему это здесь?
      • –3
        К тому, что автор статьи пишет:
        Для того чтобы вам изменить настройку, необходимо сперва дать команду setup_var 0x39.
        Результатом данной команды будет текущее значение данной переменной. Чтобы ее изменить и поставить в AHCI, надо дать команду setup_var 0x39 0x1. Учтите, что если у вас стоит Windows, то потребуется его переустановка, так как однажны настроенный Windows на IDE не сможет понять, что теперь ему надо работать с AHCI.


        А те, кто минусовали мой коммент, продемонстрировали ограниченность своих усмтвенных способностей и явно топик не читали.
        • +3
          Автор вообще то пишет как полностью выпотрошить и отредактировать UEFI, а не о том, как в несчастной Винде включить режим AHCI…
          Статья хороша, жду продолжения в том же духе. Особенно про UEFI от Apple.
  • 0
    А для чего скрывают настройки? Для градации ценников за железо?
    • +2
      Не всегда (но отчасти).
      Во-первых, скрывают тогда, когда ти настройки могут что-то сломать. Например, банально, возможность разгона CPU на ноутбуке, который явно не рассчитан на большое тепловыдление. Или VT-X на компьютерах, оборудовнных изначально 2 Гб ОЗУ (чтобы не ныли, что тормозит).
      Во-вторых, например в моем случае, скрыта официально неподдерживаемая опция (VT-D На чипе Z77 — интел ее не заявляет, хотя у всех (AsRock, MSI) работает, а у ASUS залочена в биосе, ибо по спецификации ее нет) — раз сказли, что не должнобыть, то и не будет

      Все же от настройки зависит, отсюда куча причин ее скрывать
  • 0
    А таким образом можно отключить сам Secure Boot? У меня ноутбук Lenovo Ideapad Z570 и в BIOS нигде нет такой опции.
    • 0
      А как вы загрузитесь с флешки без отключения secure boot?
      • 0
        Оно вполне работает на той же Убунте последней, x86_64. Т.е. берем iso-образ, разворачиваем на флэшку или прожигаем, и оно вполне успешно грузится с UEFI/Secure Boot. Ну, по крайней мере, на моем ноуте работает.
      • 0
        Собсно, как тогда отключить Secure Boot, если такой опции нет?
        • 0
          а без этого секьюра грузиться пробовали?
        • 0
          А он точно включен на этом буке?
          • 0
            Что, пока нет ни одной матплаты, куда нельзя Linux установить из-за Secure Boot? А вони-то сколько было…
            • 0
              www.linlap.com/lenovo_ideapad_z570

              Да нет, люди вот ставят убунту
            • 0
              Вообще-то сейчас в Ubuntu используется загрузчик, подписанный ключем Microsoft. Потому и можно установить.
              А вот на ARM, в частности Surface, уже не поставишь — т.к. там другой ключ нужен, который Microsoft не дает никому.
              • 0
                Ну в принципе не мудрено, раз Microsoft в 2014-ом году собрался делать релиз офиса под Ubuntu.
              • 0
                Про ARM откуда информация? Вы не путаете с подписью приложений?
                • 0
                  > Про ARM откуда информация?
                  Отсюда: msdn.microsoft.com/library/windows/hardware/hh748188 (windowsnext-hardware-cert-requirements-system.pdf, страница 114, пункт 18, последнее предложение).
                  • 0
                    Я про то, что Microsoft отказывается подписать bootloader для SurfaceRT.
                    • 0
                      Вы ещё спросите, как так вышло, что на Винфоны нельзя поставить другие ОС и где вообще доказательства.
                      • 0
                        Вы ещё спросите, как так вышло, что на Винфоны нельзя поставить другие ОС и где вообще доказательства.
                        Подозреваю, что технически это возможно. Просто никто ещё не дорвался. Когда винфонов было больше (во времена Windows Mobile), это без проблем делали.
                        • 0
                          Поинт не в потенциальной возможности, а в намеренном препятствовании.
                          • 0
                            Если Вы не заметили, речь идёт не о поинтах, а о потенциальной возможности.
                            С SSL в мире примерно такая же ситуация. И что-то сейчас никто не разводит вонь о том, что надо сертификаты получать у определённой группы дядек. С загрузчиком тоже самое.
                          • 0
                            И, кстати, наивно полагать, что Secure Boot заметно осложняет портирование.
                • 0
                  Не путаю. На ARM Microsoft требует запретить отключение Secure Boot.
                  www.softwarefreedom.org/blog/2012/jan/12/microsoft-confirms-UEFI-fears-locks-down-ARM/
                  По поводу ключа — сходу статью не нашел, но даже выше по ссылке указано, что запустить другую ОС на SurfaceRT невозможно.

                  Вот тут: fedoraproject.org/wiki/Secureboot
                  также написано (жирным выделил я):
                  On ARM Microsoft Windows 8 ready requirements say that Secure boot should be enabled by default and cannot be disabled.
                  Fedora has no plans to support secure boot on that platform and suggests buying Non Windows 8 ready hardware.

                  А т.к. Fedora поддерживает Secure Boot на x86, то из этого следует, что ключ, используемый для подписи на x86, для ARM не подойдет.
                  • 0
                    И как это доказывает предположение, что Microsoft отказывается подписывать загрузчики для ARM?
                    • 0
                      Так, что если бы подписывали — Fedora подписала бы себе и спокойно клепала дистрибутив.
                      • –1
                        Я так понимаю источник информации — Ваша собственная логика? Ну так у меня своя логика и Ваше утверждение мне очевидным не кажется.
                        • 0
                          Не совсем. Я выше написал, что читал об этом где-то, только где — к сожалению, не нашел сейчас.
                          Возможно, я ошибаюсь — тогда, если вас не затруднит, найдите обратное утверждение — где написано то, что ключем Microsoft можно подписать свой загрузчик для ARM и это будет работать на SurfaceRT?
                          • –1
                            Я этого не утверждал и потому доказывать не намерен. И Вам рекомендую не делать бездоказательных утверждений. В научной среде (а я надеюсь Хабр всё-таки таковой является) это выглядит глупо.
                            • +1
                              Я говорил о том, что видел эту информацию, а не о том, что сам её придумал.
                              Мой Вам совет — больше доверяйте людям. Тут никто обмануть Вас не хочет.

                              Но чтобы Вы не сомневались, я таки постарался найти статьи, в которых читал об этом. Такой пруф вас устроит?
                              При этом Microsoft не требует от производителей включения в прошивку ключа верификации драйверов, который используется для подписи сторонних продуктов в сервисе Microsoft. Если данный проверочный ключ не будет включён в прошивку UEFI система может быть сертифицирована на совместимость с Windows 8, но не сможет загружать сторонние ОС, поставляемые с загрузчиком, заверенным в сервисе Microsoft.
                              www.opennet.ru/opennews/art.shtml?num=36510
                              В Microsoft Surface используется стандартная технология UEFI Secure Boot и привязанная к устройству прошивка, которая поддерживает только загрузку подписанных исполняемых файлов. Казалось бы, что достаточно использовать подписанный через сервис Microsoft загрузчик для обеспечения работы сторонних систем, но не всё так просто — в Microsoft Surface задействован отдельный ключ верификации, который используется Microsoft только для Windows. В связи с этим, замена предустановленной на планшет операционной системы Windows RT возможна только через эксплуатацию уязвимостей в прошивке.
                              www.opennet.ru/opennews/art.shtml?num=35725
                              • –1
                                Вопрос не в доверии в смысле правда/ложь. Вопрос в том, насколько точно вы поняли и запомнили источник.

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