Мне захотелось добавить в свой ноутбук ThinkPad X1 Nano внутренний USB-разъём, что должно было стать довольно простой задачей, но не стало.
Разумеется, если бы я всё ещё работал на Framework Laptop, то для этого было бы достаточно подключить модуль, но я уже довольно долгое время использую в качестве основного ноутбука X1 Nano.
▍ Мышь Logitech
Несмотря на удобство TrackPoint на моём ThinkPad, очень удобно иметь мышь с колёсиком прокрутки и четырьмя клавишами. Я пользуюсь мышкой Logitech, которая может подключаться по беспроводному каналу к радиочастотному USB-донглу, который обеспечивает меньшую задержку и энергопотребление, чем Bluetooth. Мышь также поддерживает Bluetooth, но его не поддерживает OpenBSD, так что USB-донгл — единственный вариант. Это могло бы мешать на ноутбуке со всего двумя USB-разъёмами, но донгл обычно подключен к находящемуся под столом доку USB-C, который также подаёт питание на ноутбук, так что всё передаётся по одному кабелю USB-C, и я даже не замечаю этот донгл.
Однако когда я отключаю ноутбук от питания, эта как бы беспроводная мышь теряет соединение, и мне нужно таскать с собой адаптер USB-A-USB-C. Это очень неудобно.
Та же проблема у меня возникает при использовании AirPods с ноутбуком. Так как OpenBSD не может подключаться к ним нативно по Bluetooth, я использую для работы с этим протоколом Creative BT-W3, предоставляющий OpenBSD интерфейс USB-аудио. К сожалению, я не могу оставлять его подключенным постоянно, потому что, как только я переподключаю AirPods к телефону, BT-W3 перехватывает соединение примерно спустя десять секунд после того, как я оказываюсь поблизости от ноутбука.
Очевидно, моя жизнь была бы проще, если бы у OpenBSD снова был стек Bluetooth, но для этого нужно много потрудиться, а я не хочу его писать. Наверно, проще спрятать внутри ноутбука USB-разъём, чтобы хотя бы засунуть туда мышиный донгл.
▍ M.2
У X1 Nano есть свободный разъём M.2 (B-Key) для подключения опциональной карты WWAN. На многих других ноутбуках достаточно просто купить USB-карту M.2, вставить её в этот разъём и мгновенно получить внутренний USB-разъём (а то и пару).
Интересный факт: наряду с интерфейсом PCIe разъёмы M.2 также имеют контакты для предоставления USB-соединения. Многие карты Wi-Fi с интегрированным Bluetooth задействуют оба этих набора контактов, чтобы предоставлять интерфейс Wi-Fi по PCI и Bluetooth по USB. Есть четыре контакта конфигурации, которые карта использует, чтобы сообщить хосту, какие типы интерфейсов используются. USB-картам M.2 даже не требуется предоставлять собственный USB-контроллер, им всего лишь нужно подключить USB-контакты M.2 к USB-разъёму, сдвинуть напряжение с 3,3 В на требуемые стандарту USB 5 В и заземлить отдельные контакты конфигурации. На схеме такой карты показано только, как подключаются контакты SSIC
, CONFIG
, VBAT
и GND
USB.
К сожалению, Lenovo продолжает использовать дурацкий белый список сетевых карт, который начала применять IBM более двадцати лет назад на своих моделях ThinkPad. Если карта в разъёме M.2 не передаёт ID производителя PCI и продукта, известного белому списку, хранящемуся в BIOS (теперь прошивка UEFI), то ThinkPad отказывается запускаться:
Подключённая USB-карта M.2...
… вызывает ошибку
Я ненадолго задумался об изготовлении собственной PCI-карты M.2, которая бы перенаправляла контакты USB, но также добавляла бы микроконтроллер, чтобы притворяться известной картой WWAN (по крайней мере в том, что касается ID производителя и продукта). Ещё я думал о карте с каким-нибудь чипом-таймером, который бы разъединял контакты конфигурации на достаточно долгое время, чтобы машина загружалась, думая, что в разъёме ничего нет, после чего контакты бы подключались к USB-разъёму. Обе идеи показались слишком сложными, поэтому я пошёл по другому пути.
▍ Взлом прошивки?
Для исследования белого списка мне сначала нужна была подходящая карта WWAN, чтобы знать, какого поставщика и ID продукта искать. Для этого потребовалось много проб и ошибок, но, в конце концов, я выяснил, что подходит карта Qualcomm X55, ID изготовителя которой 105b
(Foxconn), а ID продукта — e0ab
.
Далее мне нужно было изучить код прошивки, чтобы узнать, как работает белый список. Порывшись на материнской плате, я обнаружил чип флэш-памяти прошивки под пластмассовой крышкой прямо рядом с разъёмом M.2; это оказался Winbond W25R256JV на 32 мегабайта размером 8 мм x 6 мм.
Чип флэш-памяти прошивки
Winbond W25R256JV
Так как этот флэш-чип очень низкопрофильный, мои обычные зажимы SOIC-чипа не позволили к нему подключиться. Я не хотел отпаивать его, чтобы не повредить, поэтому купил щуп с подпружиненными контактами, который справился с работой; однако это было довольно утомительно, потому что для полного чтения и записи требовалось твёрдой рукой прижимать его в течение восьми минут.
Подключив щуп через считыватель CH341A к AsProgrammer на ноутбуке с Windows (забавно, что это мой Framework), я смог считать образ прошивки и поискать в нём 5B 10 AB E0
(идентификаторы производителя и продукта в формате little-endian).
Содержимое прошивки в AsProgrammer
Я заменил в обоих случаях E0
на E1
, понадеявшись, что в этом случае система при загрузке выдаст ошибку «неавторизованная карта», и тогда я пойму, что нашёл нужный белый список. К сожалению, машина при запуске выдала такую ошибку:
Самостоятельное восстановление BIOS
Очевидно, Lenovo использует функцию Secure Flash Authentication, вычисляющую контрольную сумму образа прошивки и сверяющую её с подписанным значением; в случае неудачи прошивка заменяется на последнюю хорошую версию. Однако я не совсем понимаю, как это работает. Где хранится хорошая копия? На ещё одном флэш-чипе размером 32 МБ? Кто занимается верификацией флэш-памяти? Это не может быть сама прошивка на флэш-чипе, потому что она может быть повреждена, но всё равно самовосстановиться. Код верификации выполняется с последней хорошей флэш-памяти? Проходит ли эта верификация при каждой загрузке и все 32 МБ считываются до процедуры POST?
Потратив на это одну-две недели и поэкспериментировав с очень подозрительным ПО для Windows, позволяющим модифицировать полезные нагрузки UEFI, я сдался и отказался от этого пути.
▍ Считыватель отпечатков пальцев
Внимательно изучив материнскую плату со снятым аккумулятором, я вспомнил, что считыватель отпечатков пальцев, находящийся прямо рядом с тачпадом, подключён по USB, хотя я обычно и отключаю его в прошивке. Я задался вопросом, можно ли будет подключить к тому соединению, которое использует плата, произвольное USB-устройство.
Плата считывателя отпечатков пальцев (под металлической крышкой)
Контакты считывателя отпечатков пальцев
На плате считывателя отпечатков пальцев используется 8-контактный разъём FFC, но подключены только четыре из его контактов, то есть ровно то количество, которое необходимо для простого соединения USB 2.0. Я купил коммутационную плату 8-контактного FFC толщиной 0,5 мм и выяснил, что контакт 1 — это VCC
USB, контакт 2 — это DATA-
, контакт 3 — это DATA+
, а контакт 4 — GND
.
Коммутационная плата рядом со считывателем отпечатков
Подключенный USB-разъём
Удобно, что к корпусу по обеим сторонам разъёма дисплея приклеены резиновые/пенопластовые прямоугольники. Если убрать один из них, останется как раз достаточно места для размещения USB-разъёма:
Расположение USB-разъёма
Поэтому у меня появилась (не сразу) идея изготовить новую гибкую плату, которую можно установить вместо считывателя отпечатков. Она будет иметь 8-контактный разъём FFC для кабеля материнской платы, а затем соединит четыре контакта USB с USB-разъёмом у разъёма дисплея. Хотя обычно USB-разъёмы плохо держатся на гибких платах, к этому будет подключено USB-устройство, которое практически всегда остаётся на месте, поэтому никаких нагрузок к нему прилагаться не будет.
Припаяв временный USB-разъём, я скрестил пальцы, включил машину, и, к счастью, ничего не загорелось. После запуска OpenBSD я подключил несколько устройств USB 2.0, и большинство из них распозналось… кроме того, которое мне и нужно: приёмника Logitech Bolt. Ошибок разъёма не было, он просто не распознавался, как будто и не включался.
USB-соединения в OpenBSD
▍ Питание USB
Проверив всё мультиметром, я осознал, что кабель FFC, идущий к считывателю отпечатков, подаёт только 3,3 В вместо обычных 5 В для USB. Очевидно, считыватель сконструирован так, что требует для USB-соединения только 3,3 В (вероятно, он берёт питание от соседних компонентов i2c, использующих 3,3 В), и большинство USB-устройств, которые я пробовал, тоже работало на 3,3 В. Так как Logitech Bolt требуется больше 3,3 В, мне нужно было поднять напряжение до 5 В.
Проведя исследования, я нашёл платы повышающих преобразователей на основе ME2108, повышающие напряжение с <5 В до 5 В. Я купил несколько плат и подключил одну к внешнему USB-разъёму; он действительно давал необходимые 5 В для работы Logitech Bolt, поэтому я просто встроил эту цепь в свою гибкую плату.
▍ Проектирование печатной платы
Побаиваясь проектировать плату и снова пользоваться EAGLE, я нашёл EasyEDA, предоставляющий бесплатную браузерную платформу для проектирования печатных плат (она заработала в Firefox в OpenBSD), которая имеет привязку к JLCPCB для печати и сборки платы.
Я вооружился штангенциркулем и измерил плату считывателя отпечатков, в том числе её различные овальные отверстия, а затем спроектировал в EasyEDA похожую плату. Я отпаял компоненты с одной из повышающих плат, разобрался, как они были соединены, и встроил их в свою плату.
3D-вид в EasyEDA
Я решил воспользоваться сервисом сборки печатных плат JLCPCB, чтобы они привезли мне готовые платы с припаянными компонентами разъёмов FFC и USB. Это избавило меня от необходимости покупать их отдельно и заниматься пайкой SMD.
Спустя несколько недель я получил собранные гибкие платы, оставалось только выдавить их из пластин с перфорацией и обрезать ножки USB-разъёма. Чёрное покрытие на плате предназначено для экранирования от электромагнитных помех.
Платы
SMD-компоненты
Верхняя часть платы заменяет модуль считывания отпечатков под металлической крышкой:
Дальше плата проходит под другими кабелями, аккумулятором, тепловой трубкой и кабелем дисплея, наконец, выводя USB-разъём там, где он мне нужен. USB-мультиметр подтвердил, что питание действительно повышено чётко до 5 В:
Пришлось сошлифовать показанную выше опору с отверстием под винт на нижней крышке рядом с USB-разъёмом, чтобы освободить место под USB-устройство. На эту опору не приходилось особой нагрузки, как на остальные винты нижней крышки.
Теперь, когда никаких внешних устройств к ноутбуку не подключено, мой адаптер Logitech Bolt подключён к корневому USB-концентратору, а беспроводная мышь снова стала беспроводной:
nano:~$ usbdevs -v
Controller /dev/usb0:
addr 01: 8086:0000 Intel, xHCI root hub
super speed, self powered, config 1, rev 1.00
driver: uhub0
Controller /dev/usb1:
addr 01: 8086:0000 Intel, xHCI root hub
super speed, self powered, config 1, rev 1.00
driver: uhub1
addr 02: 046d:c548 Logitech, USB Receiver
full speed, power 98 mA, config 1, rev 5.00
driver: uhidev0
driver: uhidev1
driver: uhidev2
addr 03: 13d3:5411 Azurewave, Integrated Camera
high speed, power 500 mA, config 1, rev 61.01, iSerial 0000
driver: uvideo0
driver: uvideo1
driver: ugen0
addr 04: 8087:0026 Intel, Bluetooth
full speed, self powered, config 1, rev 0.02
driver: ugen1
▍ 3D-печать прокладки
Так как считыватель отпечатков имел приподнятую площадку, а гибкая плата просто плоская, в месте, где изначально был считыватель, есть небольшая впадина. Я спроектировал 3D-модель, чтобы вставить прокладку и выровнять плату, но пока не добился идеала. Наверно, потребуется матовый филамент и обработка ацетоном, чтобы избавиться от линий 3D-печати.
Ещё я подумал, что в это отверстие неплохо было бы вставить Yubikey, или, может, крошечный светодиодный экранчик.
Автор: ru_vds