пятница, 23 июня 2017 г.

Apple Keyboard (MB110/B). Настраиваем Insert и PrintScreen под Ubuntu.

Сегодняшний пост наверное будет из серии "чем бы дитя не тешилось, лишь бы не покупало девайсы от Apple", да простят меня поклонники и многочисленные фанаты "яблочной" корпорации. Началось все с того что я решил поддаться искушению и приобрести себе клавиатуру Apple MB110/B. Не то чтобы я относил себя к числу фанатов Apple, просто работать с текстами, кодом и т.п. приходится достаточно часто, а следовательно удобство в их наборе играет важную роль. Те кто так или иначе следил за моим блогом, наверное помнит, что в свое время я купил Defender'овскую клавиатуру с "низкопрофильными" кнопками, подсветкой и прочими радостями жизни, т.к. она по-сути очень походит на клавиатуру моего ноутбука HP, которая меня максимально устраивает. Так вот, спустя несколько месяцев работы на стационарном ПК за Defender'ом я понял что она конечно напоминает ноутбучную, но достаточно отдаленно. Т.е. ход клавиш немного не тот, ощущения от нажатий и т.п. Т.е. аналог конечно, но как-то немного не тот. В поисках максимально удобной для меня клавиатуры я попробовал Apple Wired Keyboard (беспроводные просто не люблю по многим причинам) и как мне показалось - это именно то, что мне подходит. Так что я оформил заказ в DNS - и вот он, час "X" настал. Я забрал заказ, разорвал в клочья Apple'овскую коробку, которую вот в этом видео автор открывает с каким-то непонятным мне благоговейным трепетом и подключил ее к ПК.

Несколько минут знакомства с новым гаджетом подтвердили первоначальный тест - это удобно, но было несколько моментов, которые практически сводили удобство использования клавиатуры на нет, это:

  • По-умолчанию, верхний ряд кнопок F1-F12 работал не как функциональные, а как дополнительные кнопки (!), например, F1 - уменьшал яркость, F2 - увеличивал и т.п. Т.е. это были вовсе не функциональные клавиши, а дополнительные. Теперь представьте, если нам нужно нажать комбинацию кнопок Alt-F1 или Alt-F2, то приходится нажимать целых три кнопки Alt-F1-Fn или Alt-F2-Fn расположенных в разных местах, что чертовские неудобно. Я конечно понимаю, что акробатические этюды на клавиатуре в какой-то степени возможно и востребованы, но я то брал клавиатуру именно для работы, а не для освоения новых трюков. Поэтому F1-F12 мне были нужны как воздух и чтобы они нажимались без дополнительных модификаторов.
  • Отсутствие кнопки Insert ... Да, да ... на Apple'овской клавиатуре эта кнопка отсутствует в принципе (см. фото в начале статьи), открою секрет, чтобы нажать Insert нужно нажать комбинацию Fn+Enter или переключить дополнительную клавиатуру с помощью NumLock и нажать 0 на дополнительной клавиатуре. Представьте себе каково это вместо Ctrl-Insert или Shift-Insert исполнять этюд в виде Ctrl-Fn-Enter.
  • Отсутствие кнопки Prtsc / SysRq, т.е. банальный PrintScreen знакомый всем Windows пользователям на этом чуде техники отсутствует физически.
  • Ну и последнее ... расположение кнопок Ctrl-Alt-Cmd (Cmd на Mac клавиатуре - это Windows-key). Кнопки Ctrl и Cmd большие, а вот Alt находится между ними. Но лично я привык к другому порядку, Ctrl-Win-Alt, при этом Win - маленькая, а Ctrl и Alt должны быть большими. Я привык именно так и переучиваться не собирался. Поэтому в моем понимании нужно было поменять местами Alt и Cmd и тогда все стало бы на свои места.

Казалось бы всего 4 пункта в списке, но для меня они являлись существенными, без них, многие привычные и удобные вещи в работе превращались в 9-й круг ада, т.к. нажимать вместо обычного Ctrl-Ins целых три кнопки я явно не собирался. Да и реакция функциональных кнопок по-умолчанию меня совсем не устраивала. 

Первое что я решил сделать - это обратиться к официальному сайту Apple, где я нашел вот это: Изменение назначения функциональных клавиш компьютера Mac. Отлично, всего лишь одна настройка «Использовать функциональные клавиши F1, F2 и др. как стандартные» для первого пункта. Но вот незадача, у нас нет компьютера Mac, у нас даже нет MacOS, а только клавиатура Apple от которой мы хотим добиться такого же поведения. Дальнейшие поиски привели меня к следующему замечательному мануалу, вернее двум:


Автору первого руководства - отдельно спасибо. Честно говоря я не пробовал использовать Apple MB110 в Windows, но почему-то мне кажется что по написанному все пройдет достаточно гладко. Назначение функциональных клавиш в Windows определяется ключом реестра OSXFnBehavior, как видно из статьи. Однако как быть с другими ОС? И в частности моей Ubuntu 16.04? Чтобы найти ответ на этот вопрос пришлось провести еще немного времени с Google и в конечном итоге я наткнулся на мануал:


Который и послужил отправной точкой для решения всех перечисленных задач, правда с небольшими изменениями. Чтобы сделать функциональные клавиши как F1-F12 по-умолчанию в моей Ubuntu 16.04, а также, чтобы поменять местами Alt и Cmd (WinKey) я воспользовался следующими двумя командами:

sudo echo 2 | sudo tee /sys/module/hid_apple/parameters/fnmode - включение режима F1-F12 на функциональных кнопках по-умолчанию.
sudo echo 1 | sudo tee /sys/module/hid_apple/parameters/swap_opt_cmd - поменять назначение Alt и Command (Win-Key)

Честно говоря я небольшой специалист в Linux и в Ubuntu в частности, но здесь, как я понял, мы просто определяем параметры модуля hid-apple.ko (/lib/modules/4.4.0-81-generic/kernel/drivers/hid/hid-apple.ko), которые изначально предусмотрены в нем. Желающие могут погуглить про модуль ядра hid-apple и тогда все станет более ясно. После двух этих команд две озвученные проблемы были успешно решены, однако, надо было что-то делать с Insert'ом и PrintScreen'ом. И вот как раз на это у меня ушло несколько часов.

Remap кнопок с помощью xmodmap у меня работал из рук вон плохо. Т.е. если в окне терминала дать команду:

xmodmap -e "keycode 191 = Insert NoSymbol Insert NoSymbol Insert"

То remap работал, но только какое-то ограниченное время и не совсем понятно. Например мы открываем отдельное окно терминала и вводим в нем эту команду, все вроде получается. Т.е. при нажатии F13 в этом окне срабатывает Insert, однако стоит только открыть LibreOffice с помощью ярлыка на рабочем столе - то вот в нем уже почему-то F13 не работает как Insert. Также, соответствующие изменения ~/.Xmodmap с последующей перезагрузкой не привели к желаемому результату. Почитав немного многочисленные сообщения людей, которые пробовали на форуме сделать то же самое, я пришел к выводу что "это не наш метод". Т.к. среди решений было даже что-то вроде создать .desktop файл с запуском xmodmap /home/decker/.Xmodmap и поместить его в Startup Applications ... Но и этот метод не у всех работал, как его "дальнейшее развитие", люди делали bash скрипт с чем-то вроде sleep 4 && xmodmap /home/decker/.Xmodmap и все равно, когда-то это работало, а когда-то нет. С этого момента я понял что искать способ remap'а кнопок нужно на более низком уровне.

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

hardware --scancode--> kernel --keycode--> X11 --> keysym --> application

что-то прояснила для меня, но далеко не все (да, да, я не совсем хорошо представляю как работает X11 и что происходит в ядре). Но эта статья дала очередной импульс поискам и я набрел на следующее:

Ключевой точкой был абзац из первой статьи:


Теперь рассказываю как сделал я и как я к этому пришел. Итак, мы решили назначить F13 на Insert, а F15 на PrintScreen. Что же, приступим

1. Ставим утилиту evtest через sudo apt install evtest и запускаем ее, как sudo evtest
2. В появившемся списке выбираем "Apple Inc. Apple Keyboard", у меня это было устройство /dev/input/event17. В выводе утилиты мы увидим нечто вроде:

Input driver version is 1.0.1
Input device ID: bus 0x3 vendor 0x5ac product 0x250 version 0x111
Input device name: "Apple Inc. Apple Keyboard"

Нажимаем кнопку F13 чтобы определить ее KEYBOARD_KEY_%VALUE%, после нажатия F13 мы увидим:


Event: time 1498176151.012832, -------------- SYN_REPORT ------------
Event: time 1498176154.612842, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70068
Event: time 1498176154.612842, type 1 (EV_KEY), code 183 (KEY_F13), value 1
Отсюда нам нужно запомнить значение value - 70068, это шестнадцатиричное значение. Руководствуясь статьей User XKB Customization проверяем версию udev - udevadm info --ver, в моем случае результатом было 229. Таким образом теперь нам необходимо написать соответствующий файл /etc/udev/hwdb.d/98-apple-keyboard.hwdb . Но как узнать идентификатор для evdev:input? Здесь нам поможет статья How to find the .hwdb header of a general input device? .

3. Выполняем udevadm info /dev/input/event17 и запоминаем ID_VENDOR_ID, в нашем случае это 05ac. Далее делаем find /sys -name *modalias | xargs grep -i 05ac , где 05ac наш vendor_id. Ответом будут множество строк, в том числе и одна, следующего вида: 

/sys/devices/pci0000:00/0000:00:14.0/usb1/1-11/1-11.2/1-11.2:1.0/0003:05AC:0250.0005/input/input20/modalias:input:b0003v05ACp0250e0111... # далее много всего

Здесь нас интересует все что находится после modalias:input до 'e', т.е. в нашем случае b0003v05ACp0250 .

4. Создаем файл /etc/udev/hwdb.d/98-apple-keyboard.hwdb от имени root и вписываем туда следующие строки:

evdev:input:b0003v05ACp0250*
 KEYBOARD_KEY_70068=insert      # F13: Insert

Обратите внимание, пробел перед KEYBOARD_KEY важен. После чего делаем:

sudo udevadm hwdb --update и sudo udevadm trigger (убедиться в том что все сработало можно сделав udevadm info /dev/input/event17 | grep KEYB , если в выводе будет что-то вроде KEYBOARD_KEY_70068=insert - значит все Ок).

5. Проверяем визуально, идем в Параметры системы -> Клавиатура -> Ввод текста и нажимаем на иконку клавиатуры под списком раскладок, у нас откроется вот такое окно:


Теперь нажимая F13 мы видим что у нас засчитывается нажатие Insert. Аналогично делаем с F15 -> PrintScreen. Здесь я приведу уже готовый вариант /etc/udev/hwdb.d/98-apple-keyboard.hwdb :

evdev:input:b0003v05ACp0250*
 KEYBOARD_KEY_70068=insert      # F13: Insert
 KEYBOARD_KEY_7006a=sysrq       # F15: PrinScr / SysRq

Вот таким нехитрым образом мы заставили работать функциональные клавиши, а также Insert и PrintScreen на клавиатуре Apple MB110/B под Ubuntu 16.04. При этом мы не использовали "плясок с бубном" вокруг отложенного запуска xmodmap, не разбирались почему не "подцепляется" наш ~/.Xmodmap, а решили проблему "уровнем ниже". И хотя в данном случае до полного понимания принципов работы и назначения udevadm и hwdb нам еще "расти и расти", поставленную задачу успешно удалось решить. Конечно, ее можно было решить и другими путями, например сборкой модифицированного hid-apple.ko (на эту тему также есть соответствующие статьи в интернете, например эта), но фраза "Macbook keyboard is painful" в самом начале как бы намекает ;) Нет, конечно, можно собрать hid-apple.ko с модифицированным / пропатченным hid-apple.c (кстати есть даже проект на Git'е), однако, для этого нужно еще качать исходники ядра, разбираться как собираются модули, а если у вас Ubuntu на системе с UEFI, как у меня, например, то еще и понимать каким образом заставить грузиться собранный неподписанный hid-apple.ko. Конечно, при наличии времени и должного энтузиазма можно сделать и это, но способ описанный мной чуть проще. Этот пост я уже писал на Apple'овской клавиатуре с работающими так, как мне нужно кнопками.

p.s. Комментарии, предложения, пожелания - приветствуются ... и да, Macbook keyboard is painful ;)

пятница, 16 июня 2017 г.

Corsair HX1000i. Качественные блоки питания, какими они должны быть?

Сегодняшний пост будет несколько необычным, в нем я бы хотел затронуть тему качественных блоков питания для ПК и попробовать разобраться, насколько они востребованы и актуальны для домашнего применения. Согласитесь, что собирая обычный домашний или игровой ПК, мало кто из нас задумывался какой БП стоит приобрести. Обычно процесс выбора комплектующих сводится к подбору материнской платы, процессора, видеокарты и уже на последнем этапе мы выбираем корпус и БП. Причем в выборе последних двух компонентов мало кто из нас руководствуется какими-то "критериями выбора", скорее это выглядит так: все куплено, какой бы корпус нам выбрать? А возьмем вот этот черненький, вроде ничего, да и по цене адекватный ... БП? Видюшка не такая мощная, да и зачем покупать что-то дорогое, возьмем вот этот 600-750 Вт'ник, в бюджет вписывается и ладно. Т.е. при выборе комплектующих для ПК мы расставляем акценты на CPU + GPU, а уже БП, корпус и все остальное получается чем-то вроде "второстепенной покупки" на то что осталось и что вписывается в планируемые расходы.

Скажу честно, что сам руководствовался таким подходом долгое время (например, сейчас в моем домашнем ПК стоит какой-то Aerocool KCAS 600W и единственным критерием его выбора послужила цена - до ~3000 руб. на момент покупки, что я посчитал приемлемым), однако, после того как я "вживую" познакомился с флагманскими БП от Corsair я понял что разница на самом деле есть и довольно существенная. Заключается она даже в мелочах, начиная от упаковки / комплектации БП и заканчивается качеством сборки, используемыми компонентами, качеством комплектных проводов (!) и реально выдерживаемыми БП нагрузками (далеко не каждый БП на котором написано, к примеру, 600W реально способен потянуть такую нагрузку по 12В линии). Но обо всем по-порядку ... Да, кстати, еще одно существенное замечание, если вы внимательно рассмотрели фотографию коробки от Corsair HX1000i в заголовке поста, то наверняка заметили надпись Ultra Low Noise на ней. В случае с Corsair и других топовых БП на практике это действительно означает бесшумность. Т.е. с небольшими нагрузками, например, вы просто включили ПК, открыли браузер, поставили музыку и т.п. - кулер на БП совсем не будет вращаться, т.е. фактически, если нагрузки нет - ваш БП превращается в абсолютно бесшумный компонент ПК, что, согласитесь, достаточно важно, особенно в ситуации, когда вам частенько приходится работать по ночам, а в той же самой комнате спят ваши близкие.

Перед тем как начать рассказ о Corsair HX1000i давайте попробуем разобраться с сериями БП этого производителя, ведь у них есть серии AX, HX/HXi, RM, TX-M, SF, CX, VS и другие и немногие представляют чем например HX отличается от той же RM-серии и т.п. Для начала рекомендуется ознакомиться с описанием серий на официальном сайте производителя:

  • AXi Series — наша основная линейка блоков питания, предназначенная для использования в сверхмощных ПК. Это первая линейка блоков питания для настольных ПК, оснащенная процессором цифровых сигналов для обеспечения непревзойденной эффективности без ущерба для электрических характеристик. Если вам необходим блок питания для новой системы вашей мечты — это именно то, что вам нужно.
  • Блоки питания HX и HXi Series разработаны для игровых компьютеров, разогнанных систем и прочих ПК, где ключевую роль играет надежность и бесперебойность работы. Сертификация 80 PLUS Platinum означает, что блок питания работает без перегрева, бесшумно и эффективно. Модели HXi Series обладают еще лучшими характеристиками благодаря мониторингу и управлению с помощью Corsair Link, а также модернизированным вентиляторам.
  • Блоки питания RMx и RMi Series изготовлены с применением высококачественных компонентов, обеспечивающих отличные рабочие характеристики и невероятно низкий уровень шума. Эти блоки питания сертифицированы по стандарту 80 PLUS Gold и обеспечивают чрезвычайно точную регулировку напряжения, работая практически бесшумно. Использование конденсаторов исключительно японского производства с рабочей температурой 105 °C делает эти блоки питания отличным выбором для использования в высокопроизводительных ПК, для которых надежность имеет решающее значение. Комплект полностью модульных кабелей упрощает установку и замену. Благодаря совместимости с RMi Link вы сможете контролировать параметры блока питания, которые ранее не были доступны для пользователей.

Таким образом AX - представляет собой "флагманскую линейку", HX - были "топовыми" до появления линейки AX, ну и RM, соответственно, также высококачественная линейка БП, сертифицированная как 80+ Gold (большинство БП AX серии имеют 80+ Titanium, а HX - 80+ Platinum сертификацию, более подробно о сертификатах для БП вы может прочитать здесь - 80 PLUS). 

Энергоэффективность потребления - фактически это КПД вашего БП. Т.е. отношение выходной мощности к потребляемой, для стандарта 80+ он должен быть не менее 80% при 20%, 50% и 100% нагрузке относительно номинальной мощности БП:


Не нужно быть специалистом в электронике, чтобы понять, что БП тем лучше, чем лучше его КПД. Т.е. если считать что БП берет из розетки 100% мощности, то по стандарту 80 PLUS он должен отдавать не менее 80% полезной мощности подключенным к нему устройствам при 20% нагрузке. В случае с 80+ Platinum мы видим этот показатель как 90%, т.е. "потери" при 20% нагрузке всего 10%. Думаю что с классификацией мы разобрались, ну а теперь посмотрим на HX1000i более пристально.

p.s. Продолжение следует ... 


вторник, 6 июня 2017 г.

PXE Boot. Бездисковые устройства. Загружаемся по сети.

В этом небольшом посте я расскажу вам о практических способах реализации загрузки бездисковых устройств через PXE. Скажем так, что до определенного момента я совсем не интересовался этой проблемой и о PXE имел весьма посредственное представление, также, наверное как и у большинства. Т.е. все из нас знают, что в современных ПК есть возможность загрузки по сети, каждый видел в BIOS'е собственного ПК такую возможность (PXE Boot, LAN Boot), но мало кто использовал ее на практике. Реализацией этой возможности мы и займемся на практике, а также рассмотрим какое практическое применение в "домашних условиях" может иметь сетевая загрузка.

Наша "тестовая лаборатория" включает в себя:

  • Маршрутизатор Mikrotik 951G-2HnD с RouterOS v6.39 (stable)
  • Сетевое хранилище Western Digital My Cloud EX2

Для реализации загрузки через PXE вовсе не обязательно наличие подобных устройств, т.е. по сути нам потребуются DHCP Server, TFTP Server, NFS и/или HTTP для организации хранения и передачи тяжеловесных образов по сети. Все эти компоненты можно установить например и на обычный ПК под управлением Windows, или же, поставить тот же Ubuntu на отдельную машину в локальной сети и настроить все эти сервисы там, благо мануалов в сети предостаточно. Но раз уж так получилось что у нас есть Mikrotik'овский роутер и NAS - то функции DHCP + TFTP логично возложить на Mikrotik, а NFS / HTTP на NAS.


Также нам понадобится самая обычная USB Flash'ка, любого размера, которую мы вставим в Mikrotik чтобы обеспечить хранение файлов, которые будут отдаваться по TFTP. Если у вас уже есть подобная конфигурация (DHCP+TFTP+NFS+HTTP), то можно приступать. 

Здесь я расскажу путь, которым прошел я. Первоначально мне было интересно сделать бездисковую загрузку LiveCD дистрибутива Ubuntu, т.е. чтобы любой ПК в сети с HDD или без можно было включить и получить на экране работоспособный Ubuntu, а-ля посидеть в сети / почитать почту и т.п. Подобное решение может оказаться удобным и в местах организации коллективного доступа в интернет, например, различных компьютерных клубах, библиотеках и т.п. Плюс в том, что когда машина не имеет собственного HDD и грузится с единственного образа по сети "сломать" или испортить что-то случайно или умышленно - пользователи вряд-ли смогут. Т.е. после одного сеанса работы пользователя в Интернет можно будет просто перезагрузить ПК и все будет "как новое". Но перед тем как приступить к реализации этой идеи я решил почитать "что пишут в интернете" на тему сетевой загрузки Ubuntu и т.п. Статей как раз нашлось много, но конкретных работоспособных реализаций, в которых описываются все нюансы конфигурирования - было как раз мало. Чтобы у вас на этом же этапе был ровно тот же запас знаний что и у меня, приведу несколько ссылок на статьи, которые меня заинтересовали:
  • PXE - Сетевая загрузка с микротика - здесь описывается настройка Mikrotik + TFTP для сетевой загрузки с использованием GRUB (Grub4DOS), а также приведен пример рабочей конфигурации для загрузки ALKID LiveCD и VINCOME LiveCD через PXE. Немного не то что нам хотелось (мы то хотели грузить Ubuntu LiveCD), но тем неменее информация полезная, берем на заметку.
  • Настройка TFTP сервера на Mikrotik RouterOS - а вот здесь рассматривается настройка TFTP на Mikrotik, правда тут уже у нас уже используется не GRUB, а PXELINUX (SysLinux) в качестве загрузчика. Который, как мы убедимся позже, можно будет использовать и для реализации сетевой установки Ubuntu, и для загрузки LiveCD и для множества других вещей. Уже интересно, не правда ли? Знакомимся со статьями дальше.
  • Загрузочный сервер — как загрузочная флешка, только сервер и по сети - пост на Хабре, в котором рассказывается о том как сделать "загрузочную флешку" по сети. Собственно такая конфигурация отлично подойдет для различных сервисных центров и т.п., с другой стороны, выбрать то, что будет грузиться по сети лично у него - это решение каждого, благо примеров полно. К концу чтения этого поста, вы (по-крайней мере я на это надеюсь) поймете, насколько это удобно.
  • Домашний роутер с PXE-Boot и сервисами. - приводится пример организации PXE загрузки на Asus'овском роутере с прошивкой Merlin-Firmware. Честно говоря я сам подобную никогда не использовал, но статья ценна уже как минимум различными примерами рассмотренных в ней конфигураций для загрузки. А также как отличная иллюстрация того, что при желании, для реализации PXE загрузки можно использовать только лишь ресурсы бюджетного SOHO устройства.
  • Как воспользоваться сетевой загрузкой (PXE) для Ubuntu LiveCD - переводная статья с HowToGeek, в принципе тоже может быть интересна. Кстати, именно по теме сетевой загрузки Ubuntu LiveCD вы так или иначе наткнетесь на различные ее вариации в поиске.
  • Мультизагрузочный PXE-реаниматор - статья на 3DNews от 2012 года, но тоже в принципе интересно. Если вы читая этот пост пока просто просматриваете эти ссылки "по диагонали" - то наверное уже поняли, что PXE загрузка предоставляет практически неограниченный набор возможностей, наша задача лишь научиться правильно применить их для наших задач.
  • [How-To] Запуск LiceCD Ubuntu (и не только) с любого ПК в сети с помощью PXE - название поста говорит само за себя, все действия автор проводит на сервере под управлением Debian 7. Т.е. DHCP + TFTP и т.п. у него развернуты на отдельном ПК с Debian 7. Тоже интересно, помечаем в "копилку".
  • Configure PXE Server In Ubuntu 14.04 - похожий англоязычный вариант.
  • Установка Ubuntu по сети (DHCP, PXE, boot-menu) на примере Ubuntu 14.04. 
  • Ubuntu 16.04 / Debian 8: Run PXE boot server for automated install - конфигурирование сервера для автоматизированной установки Ubuntu и Debian по сети. Лично мне эта статья понравилась различными комментариями и дополнительными пояснениями. Если читать вдумчиво, а не по диагонали, то становится (хотя бы на базовом уровне) понятно что такое pxelinux.0, ldlinux.c32 и т.п.
  • Booten vom Netzwerk: Ubuntu 16.04 via PXE starten - статья, правда на немецком, подробно рассказывающая про то, как правильно настроить загрузку LiveCD с Ubuntu по сети. Собственно она и легла в основу решения поставленной задачи.
  • Руководство по сетевой загрузке предустановочной среды Windows (WinPE)
  • IT Geek: How to Network Boot (PXE) the WinPE Recovery Disk with PXElinux v5 & Wimboot
Ну и на первое время достаточно. Просмотрев / прочитав все это начнем ваять что-то свое. Первое что мы делаем - это подключаем флешку к Mikrotik'у и форматируем ее в FAT32: System -> Disks -> Format drive ... Сделать это можно как через WinBox, так и через Web-интерфейс Mikrotik. Проблем с этим возникнуть не должно.

Затем скачиваем заранее подготовленный архив pxe-mikrotik-disk1.rar и распаковываем его содержимое в корень флешки. Сделать это можно как в меню Files в web-интерфейсе Mikrotik'а, так и через FTP в Mikrotik, ну или просто вставив отформатированную USB Flash в ПК и распаковав в корень содержимое архива. В результате там должна получиться следующая структура файлов (смотреть скриншот справа).

Некоторых файлов, например kolibri.iso (образ Kolibri OS) в архиве не будет, т.к. их можно без труда найти и скачать в интернете, также в архиве не будет содержимого папки winpe (т.к. все эти файлы есть на любом установочном диске с Windows и включать их в состав архива я не вижу смысла). А вот на остальных мы остановимся подробнее.

pxelinux.0 - это основной загрузчик, на который направляются DHCP сервером все клиенты сетевой загрузки, он входит в состав пакета syslinux. Все что касается данного загрузчика, а также используемых им библиотек (*.c32) можно взять в следующих пакетах:

Чем я успешно и воспользовался. Возможно это и не совсем правильно делать "сборную солянку" из netboot и syslinux разных версий, но, например, готовый бинарник memdisk, использующийся в отдельных сценариях загрузки я нашел только в каком-то одном из этих пакетов. С файлами загрузчиков, ядер и т.п. более менее понятно. Т.е. у вас есть набор который получился у меня pxe-mikrotik-disk1.rar и набор источников откуда это бралось.

ipxe.lkrn здесь - это загрузчик Open Source Boot Firmware iPXE, собранный из исходников с поддержкой HTTP, NFS (!) и некоторых друг фич. Но к нему мы вернемся чуть позже, т.к. не рассказать про него я не могу, ввиду его обширного функционала (по хорошему достаточно только iPXE, т.е. PXELinux он как бы не обязателен, т.к. iPXE обладает более широким функционалом и удобнее в конфигурации, но так уж сложилось, что изначально я начал настраивать именно PXELinux, а возможность загрузки iPXE я добавил уже потом).

После того как вы распаковали все файлы из архива pxe-mikrotik-disk1.rar на флешку, заходим в Mikrotik в меню IP -> TFTP и настраиваем в нем следующие соответствия: Req. Filename -> Real Filename:


Для удобства все эти правила в виде одного скрипта:

/ip tftp
add real-filename=disk1/tftpboot/pxelinux.0 req-filename=pxelinux.0
add real-filename=disk1/images/kolibri.iso req-filename=images/kolibri.iso
add real-filename=disk1/images/winvblock.gz req-filename=images/winvblock.gz
add real-filename=disk1/images/pxetheme.gz req-filename=images/pxetheme.gz
add real-filename="disk1/images/Hiren's.BootCD.15.2.iso" req-filename="images/Hiren's.BootCD.15.2.iso"
add real-filename=disk1/tftpboot/memdisk req-filename=memdisk
add real-filename=disk1/winpe/bootmgr req-filename=winpe/bootmgr
add real-filename=disk1/menu.lst/default req-filename=menu.lst/default
add real-filename=disk1/winpe/bootmgr.exe req-filename=winpe/bootmgr.exe
add real-filename=disk1/winpe/boot/boot.sdi req-filename=winpe/boot/boot.sdi
add real-filename=disk1/winpe/boot/bcd req-filename=winpe/boot/bcd
add real-filename=disk1/tftpboot/ldlinux.c32 req-filename=ldlinux.c32
add real-filename=disk1/tftpboot/grldr req-filename=grldr
add real-filename=disk1/tftpboot/undionly.kpxe req-filename=undionly.kpxe
add real-filename=disk1/tftpboot/ipxe.lkrn req-filename=ipxe.lkrn
add real-filename=disk1/tftpboot/wim-boot.ipxe req-filename=wim-boot.ipxe
add real-filename=disk1/tftpboot/boot.ipxe req-filename=boot.ipxe
add real-filename=disk1/tftpboot/boot.png req-filename=boot.png
add real-filename=disk1/tftpboot/wimboot req-filename=wimboot
add real-filename=disk1/tftpboot/pxelinux.cfg/default req-filename=pxelinux.cfg/default
add real-filename=disk1/tftpboot/ubuntu-installer/amd64/boot-screens/vesamenu.c32 req-filename=\
    ubuntu-installer/amd64/boot-screens/vesamenu.c32
add real-filename=disk1/tftpboot/ubuntu-installer/amd64/boot-screens/linux.c32 req-filename=ubuntu-installer/amd64/boot-screens/linux.c32
add real-filename=disk1/tftpboot/ubuntu-installer/amd64/boot-screens/chain.c32 req-filename=ubuntu-installer/amd64/boot-screens/chain.c32
add real-filename=disk1/tftpboot/ubuntu-installer/amd64/boot-screens/libcom32.c32 req-filename=\
    ubuntu-installer/amd64/boot-screens/libcom32.c32
add real-filename=disk1/tftpboot/ubuntu-installer/amd64/boot-screens/libutil.c32 req-filename=\
    ubuntu-installer/amd64/boot-screens/libutil.c32
add real-filename=disk1/tftpboot/ubuntu-installer/amd64/boot-screens/menu.cfg req-filename=ubuntu-installer/amd64/boot-screens/menu.cfg
add real-filename=disk1/tftpboot/ubuntu-installer/amd64/linux req-filename=ubuntu-installer/amd64/linux
add real-filename=disk1/tftpboot/ubuntu-installer/amd64/initrd.gz req-filename=ubuntu-installer/amd64/initrd.gz
add real-filename=disk1/tftpboot/ubuntu-installer/amd64/vmlinuz.efi req-filename=ubuntu-installer/amd64/vmlinuz.efi
add real-filename=disk1/tftpboot/ubuntu-installer/amd64/initrd.lz req-filename=ubuntu-installer/amd64/initrd.lz
add real-filename=disk1/winpe/sources/boot.wim req-filename=winpe/sources/boot.wim

Для чего они? После загрузки PXELinux на устройство начинается поиск дополнительных файлов и библиотек, т.е. устройство пытается подключиться к TFTP серверу, указанному в опциях отдаваемых DHCP сервером и запросить у него, например, файл ldlinux.c32, так вот TFTP сервер должен знать о реальном местоположении файла, чтобы отдать его, например в нашем случае он лежит в disk1/tftpboot/ldlinux.c32. Честно говоря я не экспериментировал, можно ли задать соответствие не отдельным файлам, а папкам или файлам по маскам, поэтому на всякий случай сделал правила для всех файлов на TFTP сервере. После того как мы прописали правила необходимо настроить наш DHCP сервер.

Переходим на закладку IP -> DHCP Server -> Networks в Mikrotik, выбираем нашу подсеть и делаем там следующие настройки:


На этом приготовления к первому запуску закончены. Можно брать любой ПК и пробовать загрузиться по сети. Для меня наиболее простым решением было создание отдельной виртуальной машины в VirtualBox и настройка ее на загрузку по сети. В результате, если все сделано правильно, вы увидите вот такую вот симпатичную менюшку PXELinux:


Сама конфигурация этого меню находится в файле disk1/tftpboot/ubuntu-installer/amd64/boot-screens/menu.cfg . Если мы попробуем загрузиться в Kolibri OS для примера, то заметим что передача казалось бы маленького (всего 66.5 Mb) образа kolibri.iso через TFTP даже по гигабитной сети займет довольно продолжительное время:


Связано это с тем, что протокол TFTP не предназначен для передачи тяжеловесных файлов и в этом отношении работает крайне медленно (плюс еще, как вы понимаете, USB порт в Mikrotik'е, да и флешка не являются высокоскоростными), поэтому хранить на этой флешке какие-то тяжеловесные образы, например тот же Hirens Boot CD, который занимает ~650 Mb и отдавать их по TFTP устройствам - превращается в настоящую муку. Т.е. грузится - да, но оЧЧень медленно. Первая мысль которая приходит в голову - а что если в качестве средства доставки тяжеловесного контента использовать не TFTP, а HTTP или NFS? И да, действительно, такая возможность есть.

Посмотрите как реализована в конфигурации (menu.cfg) загрузка того же Ubuntu LiveCD:

label Ubuntu 16.04 LiveCD [RU]
 kernel ubuntu-installer/amd64/vmlinuz.efi
 append nfsroot=172.17.112.46:/nfs/Public/iso/ubuntu16.04_live_amd64/ netboot=nfs ro file=/cdrom/preseed/ubuntu.seed boot=casper initrd=ubuntu-installer/amd64/initrd.lz locale=ru_RU bootkbd=ru console-setup/layoutcode=ru --

Здесь ядро vmlinuz.efi и рамдиск initrd.lz у нас грузятся по TFTP, а вот содержимое rootfs уже берется с NFS ресурса (благо Ubuntu так умеет). Порядок создания папки ubuntu16.04_live_amd64 на NFS ресурсе описан тут.

Ну или если вкратце, то я создал отдельную папку на WDMyCloud EX2, разрешил доступ к ней по NFS:


Затем смонтировал ее на машине с Ubuntu в ~/nfs и просто скопировал необходимые файлы с LiveCD с Ubuntu в нее:

sudo apt-get install nfs-kernel-server nfs-common # добавляем поддержку NFS в Ubuntu
sudo mount -t nfs -O uid=1000,iocharset=utf-8 172.17.112.46:/nfs/Public/iso ~/nfs # монтируем NFS шару в ~/nfs
wget http://mirror.yandex.ru/ubuntu-releases/16.04/ubuntu-16.04.2-desktop-amd64.iso # качаем LiveCD с Ubuntu
sudo mount -o loop ubuntu-16.04.2-desktop-amd64.iso /mnt # монтируем его в /mnt
mkdir -p ~/nfs/ubuntu16.04_live_amd64 # создаем папку на nfs шаре
sudo cp -a /mnt/. ~/nfs/ubuntu16.04_live_amd64 # копируем все файлы с LiveCD в нее

В результате содержимое папки ubuntu16.04_live_amd64 у нас полностью идентично корню LiveCD с Ubuntu:


Просто? Просто. Теперь пробуем загрузиться по PXE выбрав в меню LiveCD:


С гигабитной сетью все получилось достаточно быстро. Основное время здесь правда тратится на загрузку vmlinuz.efi (7 Mb) и initrd.lz (27 Mb) по TFTP. И вот здесь мы подходим к главному? А можно ли как-то грузить эти файлы тоже с NFS или с HTTP ресурса? Можно! И ответом здесь является использование вместо PXELinux (который к сожалению так не умеет), загрузчика iPXE. Настоятельно рекомендую вам познакомиться с ним и изучить примеры и т.п. на официальном сайте. В архив pxe-mikrotik-disk1.rar уже входит ipxe.lkrn , собранный мной из исходников с включенной поддержкой HTTP, NFS и т.п.:


Обратите внимание, есть поддержка DNS, HTTP, iSCSI, NFS, TFTP и др. вещей. Т.е. грубо говоря используя iPXE вы можете разместить необходимые файлы не только на NFS шаре, но и где-нибудь в интернете, например, на http://yourdomain.ru/files/ ... и загрузчик будет брать их оттуда. При выборе опции Load iPXE SuperBoot Menu в PXELinux открывается меню загрузчика iPXE:


И вот здесь уже, согласитесь, есть чем впечатлиться. Сама конфигурация этого меню находится в файле boot.ipxe, который был взят мной из этого проекта bradgillap/IPXEBOOT на GitHub'е. Внутри подробные примеры и комментарии для всех вариантов загрузки, фактически это означает что вы с минимальными усилиями сможете настроить у себя загрузку любого из приведенных пунктов меню, просто разместив необходимые файлы у себя в сети и скорректировав boot.ipxe .

Ну и последнее о чем хотелось бы рассказать - это о загрузке *.wim образов WinPE через PXE. Для этого в моем примере используется именно iPXE и wimboot. Пример конфигурации вы можете увидеть в menu.cfg от PXELinux в пункте меню "Load iPXE [wim-boot.ipxe]". Фактически там грузится ipxe.lkrn, который читает файл конфига wim-boot.ipxe. Просто размещаете файлы wimboot, bootmgr, bcd, boot.sdi и boot.wim вашего WinPE дистрибутива где-либо в сети (на HTTP, NFS ресурсах) и все замечательно загружается. Примеры опять же, смотрите в wim-boot.ipxe.

Кстати, в меню iPXE SuperBoot от bradgillap есть пункт External Linux Installs. Фактически это внешнее (т.е. находящееся в интернет) загрузочное меню, которое позволяет вам установить некоторые Linux-based ОС, а также загрузить некоторые варианты LiveCD онлайн. Т.е. для того чтобы установить тот же Ubuntu, фактически достаточно только соответствующим образом сконфигурировать DHCP . Все остальное, даже на этапе загрузочного меню может быть взято из сети.

p.s. Чуть не забыл ;) Архив pxe-mikrotik-disk1.rar со всеми необходимыми загрузчиками и примерами конфигураций (пароль на архив стандартный - decker.su). Также буду рад любым вашим мнениям и отзывам в комментариях. Если у вас уже есть свои конфигурации для PXE загрузки распространенных LiveCD дистрибутивов, например, DrWeb Live CD, Kaspersky Rescue Disc и др. популярных инструментов - делитесь ими в комментариях. Также, если у кого-то есть опыт (или ссылки на соответствующие статьи) о настройке бездисковых RDP клиентов, например на базе Thinstation - это тоже приветствуется.

Как вы уже поняли, я далеко не гуру в Linux'е и по-сути как работает PXE я узнал только вчера. Поэтому в архиве по факту используется несколько загрузчиков: PXELinus (SysLinux) как основной, а из него уже можно загрузить iPXE или Grub4DOS, хотя по факту, в реальной жизни достаточно использовать что-то одно. Все это оставлено просто в качестве примера, чтобы было наглядно понятно как работать и с тем, и с другим, и с третьим. Так что, как говорится, "ногами не пинать", а ценные комментарии всегда приветствуются. 

воскресенье, 28 мая 2017 г.

МТС Smart Race2 4G. Первый операторский смартфон с Android Nougat.

В конце мая 2017 года в розничные торговые точки оператора МТС поступила очередная операторская новинка - МТС Smart Race2 4G. Фактически новый аппарат представляет собой очередное бюджетное устройство на базе уже хорошо знакомого нам по другим моделям SoC от Mediatek - MT6737M с тактовой частотой 1.1 GHz (Quad Core), однако, отличительной особенностью нового гаджета является ОС, Smart Race2 4G - это первое операторское устройство на российском рынке с Android 7.0 (Nougat) на борту. Появление новинки прошло без каких-либо анонсов и т.п., так, что даже на момент написания этого поста в официальном интернет-магазине оператора модель отсутствует в списке в категории "Смартфоны МТС", однако, фактически во многих регионах она уже есть на прилавках. Поэтому я как всегда решил рассказать вам о ней одним из первых.


Для тех кто не любит "длинных и скучных" обзоров - могу сразу перейти к сути. Цена новинки - 3990 руб. без дополнительных условий, т.е. за эту цену вы получаете сам аппарат, без необходимости обязательного подключения пакета услуг, определенного тарифа и т.п., как это обычно бывает у конкурентов. Базовые технические характеристики смартфона вы можете посмотреть на обратной стороне коробки, а также в кратком руководстве пользователя:


Как обычно, для удобства, я решил свести их в единую таблицу, немного дополнив информацией, отсутствующей в руководстве:


МТС Smart Race2 4G
Операционная система: Google Android 7.0 32-bit (Nougat)
Процессор: 1.1 GHz, 4-ядерный, MediaTek MT6737M (Cortex-A53), графическая подсистема - Mali-T720.
Память: 1 Gb (RAM) + 8 Gb (ROM), пользователю доступно ~4 Gb во внутренней памяти, поддержка карт памяти microSDHC (+ возможность форматирования SD как внутренней памяти, Adopted Storage)
Экран: TN, 4.5", 480x854 пикселей, 16 млн. цветов, мультитач (2 точки одновременного касания)
Камера: 5 MPix - основная, 0.3 MPix - фронтальная
Количество SIM: 2 (SIM стандартного размера + micro SIM)
Стандарты и диапазоны: LTE (FDD): 800/1800/2600 MHz (только SIM1)
UMTS: 900/2100 MHz (только SIM1)
GSM: 850/900/1800/1900 MHz
Габаритные размеры, вес: 133 x 66.8 x 9.9 мм, 124.4 гр.
Другое:
  • Simlock (первый слот, SIM1)
  • OTG отсутствует
Батарея: 1800 мА·ч
Цена: 3990 руб.

За исключением Nougat'а, к сожалению, здесь мы не видим ничего нового. А общее впечатление при взгляде на технические характеристики значительно портит TN дисплей, известный своими недостатками в виде маленьких углов обзора и плохой читаемости на солнце. На фоне последних появившихся в продаже аналогичных устройств (имеется ввиду бюджетный / операторский сегмент) с IPS дисплеями - использование TN в новом гаджете выглядит мягко говоря спорным, хотя сомнений в том что даже при этом недостатке аппарат найдет своих "поклонников" - у меня нет.

Комплектация МТС Smart Race2 4G никаких нареканий не вызывает:


Зарядка 5В 1А, micro USB кабель и даже комплектные наушники. Внешне же устройство как две капли воды похоже на другие бюджетки и ничего примечательного в дизайне обнаружить так и не удалось. Для сравнение несколько фото МТС Smart Race2 4G рядом с Smart Surf2:


Органы управления: кнопка включения питания и качелька громкости вынесены на правую кромку аппарата, а разъем для подключения microUSB и наушников находится на верхнем торце:


Под задней крышкой аппарата находятся разъемы для mini-SIM (SIM1), micro-SIM (SIM2), а также разъем для установки microSD:


После включения устройства и завершения работы мастера первоначальной настройки мы видим рабочий стол Android 7.0 Nougat:


Ограничений  на использование в слоте SIM2 сим-карт других операторов по всей видимости не налагается, как видно, в первый слот у меня была вставлена SIM от МТС, во-второй - Tele2, обе симки без проблем зарегистрировались в сети, что несомненно плюс, т.к. в некоторых других МТС'овских устройствах оба слота были simlock. В качестве оболочки по-умолчанию установлен Yandex Launcher, однако, те, кому он по каким-то причинам не нравится, могут включить вместо него привычный Launcher3 через меню Настройки -> Приложения -> [Шестеренка "Настроить приложения"] -> Главное приложение.


Несколько скриншотов из интерфейса:




Здесь мы видим предустановленные приложения в интерфейсе Яндекс.Лаунчера, уже знакомые нам сервисы от МТС: Мой МТС, МТС Книги, МТС Локатор, МТС Пресса и некоторые другие (к слову, в версии прошивки МТС_Race2_UC_TS Rel05 удалить их штатными средствами не представляется возможным, пользователь может лишь отключить их) ... Новую функцию DuraSpeed, которая судя по ее описанию, помогает ускорить работу активного приложения, путем снижения работы фоновых приложений. Интерфейс стандартного (Launcher3) лаунчера, сведения о сертификации устройства в Google, а также средний объем использования оперативной памяти и доступный пользователю объем внутренней памяти. Как видно, из 8 Gb ROM примерно 3.93 Gb занимает система и 4.07 Gb по-умолчанию доступны пользователю.

Для интересующихся результатами синтетических тестов, вот несколько скриншотов из Antutu Benchmark:


Если сравнить полученный результат в 25627 очков у МТС Smart Race2 4G с другими аппаратами на том же чипсете, то мы увидим следующую картинку:

  • Tele2 Maxi LTE - 23789
  • 4Good Light A103 4G - 25987
  • МТС Smart Surf2 4G - 26392 

Другими словами, мы видим что Android 7.0 (Nougat) кардинально на производительность устройства не влияет и те, кто рассчитывал, что более современная ОС потенциально может раскрыть некий "скрытый потенциал" железа, в плане производительности, вынуждены будут разочароваться. 

На многих мобильных форумах в ветках обсуждения различных устройств часто приходится видеть вопросы пользователей "ну когда же выпустят 7.0 под наш девайс", запросы на создание кастомных прошивок (CyanogenMod / LineageOS) на базе Android N и т.п. Т.е. общая тенденция, которую можно наблюдать на данный момент, на мой взгляд выглядит так: "мы хотим Android 7.0, но не совсем понимаем зачем". Буквально недавно я наткнулся на небольшую статью Андрея Подкина на Mobile-Review, которая так и называется - "Для чего нужен Android 7", желающие могут ознакомиться с ней здесь. Спорить о том так ли необходим Android Nougat каждому - я не вижу особенного смысла, однако, с появлением МТС Smart Race2 4G возможность опробовать новую версию этой ОС от Google стала более доступной для большинства, т.к. по факту Race2 4G на данный момент является единственным бюджетным устройством в диапазоне до 4000 руб., официально поставляющимся в РФ с Android N. Вероятно что в будущем доля подобных устройств на рынке будет только увеличиваться.

Говорить о качество фото или GPS в бюджетном устройстве - я также не вижу смысла, т.к. качество 5 Mpix камеры без автофокуса на бюджетках я думаю все прекрасно представляют, что же касается GPS - то MTK, к сожалению, никогда не отличался хорошими результатами в плане геопозиционирования, особенно в бюджетных моделях. Для примера могу сказать что в GPS Test'е МТС Smart Race2 использовал 4-5 спутников из 10 найденных и успешно определил свое местоположение. Однако, я склонен рассматривать камеру и GPS в подобных устройствах как "приятный бонус" в контексте "оно есть и работает", другими словами, при цене устройства в 3990 руб. соотношение цена / качество этих компонентов вполне приемлемое.

Обновлено 28.05.2017 18:46 (MSK)

Cекретные коды Dialer'а:

  • *#787# - Internal Version Display (информация о внутренней версии ПО, в моем случае это была RS630T_Technosew_V09_20170306
  • *#8264# - информация об оборудовании (LCM, сенсорах камеры и т.п.)
  • *#*#15#*#* - Factory Mode (различные тесты)
  • *#*#7548#*#*, *#*#629#*#*, *#*#334766#*#* - Factory Mode (аналогично предыдущему)
  • *#*#3646633*#*# - стандартное инженерное меню Mediatek.

пятница, 26 мая 2017 г.

История одного recovery. На примере МТС Smart Race2 4G.

Не так давно я рассказывал вам о первом операторском смарфтоне с Android 7.0 (Nougat) на борту - МТС Smart Race2 4G, до полноценного обзора нового устройства руки по не дошли, но он обязательно появится на страницах этого ресурса в ближайшее время. Сегодня же я бы хотел поговорить о "кастомизации", а именно особенностях сборки кастомного recovery (TWRP) под этот аппарат. Пост ориентирован скорее не на конечных пользователей, которые используют возможности TWRP в повседневной жизни, а на разработчиков. Честно говоря, начиная собирать TWRP (естественно из исходников) для данного аппарата я и не предполагал, что придется столкнуться с какими-либо сложностями, т.к. по большому счету платформа Mediatek на базе которой построен гаджет, также как и чипсет MT6737M хорошо изучены и никаких потенциальных проблем со сборкой TWRP для подобных устройств никогда не возникало. Однако в случае с МТС Smart Race2 4G, именно из-за Android 7.0, пришлось столкнуться с определенными сложностями и этот пост - небольшое "руководство-размышление" об их решении.

Сразу скажу, что т.к. аппарат построен на базе Nougat, то собирать TWPR для него обязательно на базе исходников из ветки 7.1 OmniROM (можно конечно собрать android_bootable_recovery и в составе CyanogenMod / LineageOS), но опять же, "платформа" 7.1 обязательна. Почему? Если опустить аргумент об идеологической правильности подобного подхода, скажу, что на базе Marshmallow TWRP также прекрасно соберется, но при попытке запуска под его управлением любых стоковых бинарников, например, vold, logcat и т.п. вы неизбежно получите ошибку cannot locate symbol "__write_chk", т.к. все стоковые бинарники используются экспортируемую функцию __write_chk из libc, которой в Marshmallow просто нет. Таким образом собирая TWRP на исходниках от 6.0 вы автоматически собираете libc без __write_chk, что приведет к неработоспособности части бинарников собранных под Nougat внутри получившегося TWRP. Поэтому если вы часто собираете TWRP для различных устройств и еще не успели склонировать репозитарий того же OmniROM 7.1 - сейчас самое время сделать это, т.к. по всей видимости устройств с Nougat на Mediatek будет появляться все больше и вам рано или поздно придется это сделать.

Других особенностей, касающихся именно процесса сборки TWRP - вообщем-то нет, все штатно, также как и в случае с 6.0. Собранный у меня кастомный recovery отлично запустился на аппарате, но вот как раз тут и начались "приключения". Как известно, раздел userdata в Android N является шифрованным, т.к. объявлен в fstab'е как forceencrypt с хранением ключей шифрования в metadata. Вот как раз это и послужило началом всей истории. Загрузившись в только что собранный TWRP я обнаружил что он запрашивает пароль для дешифровки userdata и не монтирует его. При этом пароль в устройстве, т.е. ни PIN-код для разблокировки, либо загрузки Android, ни графический ключ не был явно задан.

Т.е. фактически TWRP по каким-то причинам не смог расшифровать раздел с помощью default_password. Включение отладочных средств TARGET_USES_LOGD и TWRP_INCLUDE_LOGCAT в BoardConfig.mk при сборке также не помогло установить причину проблемы. Вывод logcat и dmesg в этом плане был малоинформативен.

Конечно в данной ситуации можно было поступить проще (подобное решение можно увидеть в многочисленных сборках TWRP, в котором разработчикам было лень разбираться с шифрованием), например, просто разобрав boot и изменив forceencrypt на encryptable с последующим форматированием раздела userdata и потерей всех данных. Но это ведь не наш путь, т.к. в моем понимании у пользователя устанавливающего TWRP на аппарате уже есть какие-то данные и терять их из-за того что TWRP не может справиться с расшифровкой раздела, как минимум не хотелось бы. Другими словами, TWRP должен монтировать существующий на устройстве раздел userdata, все другие варианты (отключение шифрования и т.п.) являются "полумерами", к тому же еще и снижающими безопасность устройства.

Тогда я вспомнил, что начиная с определенной версии TWPR в нем появилась возможность использования стоковых бинарников vold с помощью включения TW_CRYPTO_USE_SYSTEM_VOLD в сборку, информация об этом есть в этом коммите - crypto: Use system's vold for decryption. Бегло изучив все что там говорится, а также проанализировав содержимое исходников в /bootable/recovery/crypto/vold_decrypt/ я включил этот флаг в BoardConfig.mk и пересобрал recovery. Т.е. теперь уже TWRP использовал бинарник vold находящийся в system ... Однако дешифрование раздела и его монтирование все равно не происходило, т.к. при сборке vold в стоковой прошивке разработчиками была включена проверка boot_mode. Что она из себя представляет?

Для лучшего понимания приведу следующий исходник:

int get_boot_mode(void)
{
  int fd;
  ssize_t s;
  char boot_mode[4] = {'0'};
  char boot_mode_sys_path[] = "/sys/class/BOOT/BOOT/boot/boot_mode";

  fd = open(boot_mode_sys_path, O_RDONLY | O_NOFOLLOW | O_CLOEXEC);
  if (fd < 0)
  {
    SLOGE("fail to open %s: %s", boot_mode_sys_path, strerror(errno));
    return 0;
  }

  s = read(fd, boot_mode, sizeof(boot_mode) - 1);
  close(fd);

  if(s <= 0)
  {
    SLOGE("could not read boot mode sys file: %s", strerror(errno));
    return 0;
  }

  boot_mode[s] = '\0';
  return atoi(boot_mode);
}

Здесь get_boot_mode возвращает текущий режим загрузки устройства, который она читает из /sys/class/BOOT/BOOT/boot/boot_mode . Так вот стоковый vold вызывает некий аналог этой get_boot_mode и если устройство загружено в режиме отличном от system, т.е. в recovery mode или в любом другом доступном режиме, то монтирование / дешифрование userdata невозможны в принципе. В логах вы увидите нечто вроде <5>fs_mgr: %s: bootmode(%d) is NOT normal mode, disable 'default encrytion', flag=(0x%x -> 0x%x)". Скачав и установив бесплатную demo версию IDA v6.95.160810 мы можем увидеть эту проверку самостоятельно:


Где в дальнейшем используются результаты этой проверки и как именно - разбираться досконально я не стал, однако, факт отключения default encryption в vold при загрузке в режиме recovery, естественно, нас не устраивал. Из этой сложившейся ситуации есть несколько выходов:

  • Непосредственный патч vold для обхода этой проверки.
  • Написание собственной библиотеки с размещением ее в LD_PRELOAD, которая перехватывала бы попытки обращения в цепочке open("/sys/class/BOOT/BOOT/boot/boot_mode") -> __read_chk -> close от любых приложений и всегда возвращала бы нужное значение (т.е. 0 = normal_mode).
  • Сборка vold из исходников Android N для MT6737M от Mediatek с корректировкой всех проверок в исходниках.

Любая из этих реализаций должна привести к успеху, поэтому какой именно воспользоваться - не имеет большого значения. Здесь главное не забыть, что собранный из исходников или модифицированный vold должен корректно загружаться из init.recovery.vold_decrypt.rc, например так:

service sys_vold /path_to_your_vold/vold \
        --blkid_context=u:r:blkid:s0 --blkid_untrusted_context=u:r:blkid_untrusted:s0 \
        --fsck_context=u:r:fsck:s0 --fsck_untrusted_context=u:r:fsck_untrusted:s0
    socket vold stream 0660 root mount
    socket cryptd stream 0660 root mount
    setenv PATH /system/bin
    setenv LD_LIBRARY_PATH /system/lib64:/system/lib
    disabled
    oneshot

Однако, даже решив эту проблему - мы не получим полноценного решения по дешифрованию userdata в TWRP, т.к. платформа использует еще и teei_daemon для поддержки шифрования. Изучить как он запускается и работает можно посмотрев внутрь init.microtrust.rc из boot'а. И наконец последний шаг на пути к успеху, это обеспечение корректного запуска и работы этого демона при дешифровании, "красивым" и правильным шагом здесь, на мой взгляд, является помещение его инициализации в соответствующий init.recovery.vold_decrypt.$(item).rc (разобраться с этим подробнее вам поможет /bootable/recovery/crypto/vold_decrypt/Android.mk).

В качестве результата проделанной работы я получил незаменимый опыт (что главное), а также полноценной работающий TWRP 3.1.1-0:


Как видно из фото - раздел userdata успешно расшифрован и примонтирован (Data succefully decrypted, new block device: '/dev/block/dm-0') created). Mission accomplished ;)

p.s. Во-избежание наболевшего вопроса "а где можно скачать готовую сборку TWRP" - скажу сразу что дата public релиза пока не определена. Однако все необходимые для сборки моменты уже рассмотрены в этой статье и любой желающий, ориентируясь на мои наработки может пройти тем же путем.