Windows: достучаться до железа
Меня всегда интересовало низкоуровневое программирование – общаться напрямую с оборудованием, жонглировать регистрами, детально разбираться как что устроено. Увы, современные операционные системы максимально изолируют железо от пользователя, и просто так в физическую память или регистры устройств что-то записать нельзя. Точнее я так думал, а на самом деле оказалось, что чуть ли не каждый производитель железа так делает!
В чём суть, капитан?
В архитектуре x86 есть понятие «колец защиты» («Ring») – режимов работы процессора. Чем ниже номер текущего режима, тем больше возможностей доступно исполняемому коду. Самым ограниченным «кольцом» является «Ring 3», самым привилегированным – «Ring -2» (режим SMM). Исторически сложилось, что все пользовательские программы работают в режиме «Ring 3», а ядро ОС – в «Ring 0»:
В «Ring 3» программам запрещены потенциально опасные действия, такие как доступ к I/O портам и физической памяти. По логике разработчиков, настолько низкоуровневый доступ обычным программам не нужен. Доступ к этим возможностям имеют только операционная система и её компоненты (службы и драйверы). И всё бы ничего, но однажды я наткнулся на программу RW Everything:
Эта программа была буквально напичкана именно теми функциями, которые обычно запрещаются программам «Ring 3» — полный доступ к физической памяти, I/O портам, конфигурационному пространству PCI (и многое другое). Естественно, мне стало интересно, как это работает. И выяснилось, что RW Everything устанавливает в систему прокси-драйвер:
Прокси-драйвера
В итоге получается обходной манёвр – всё, что программе запрещено делать, разработчик вынес в драйвер, программа устанавливает драйвер в систему и уже через него программа делает, что хочет! Более того – выяснилось, что RW Everything далеко не единственная программа, которая так делает. Таких программ не просто много, они буквально повсюду. У меня возникло ощущение, что каждый уважающий себя производитель железа имеет подобный драйвер:
- Софт для обновления BIOS (Asrock, Gigabyte, HP, Dell, AMI, Intel, Insyde…)
- Софт для разгона и конфигурации железа (AMD, Intel, ASUS, ASRock, Gigabyte)
- Софт для просмотра сведений о железе (CPU-Z, GPU-Z, AIDA64)
- Софт для обновления PCI устройств (Nvidia, Asmedia)
Во многих из них практически та же самая модель поведения – драйвер получает команды по типу «считай-ка вот этот физический адрес», а основная логика – в пользовательском софте. Ниже в табличке я собрал некоторые прокси-драйвера и их возможности:
- Mem – чтение / запись физической памяти
- PCI – чтение / запись PCI Configuration Space
- I/O – чтение / запись портов I/O
- Alloc – аллокация и освобождение физической памяти
- Map – прямая трансляция физического адреса в вирутальный
- MSR – чтение / запись x86 MSR (Model Specific Register)
Жёлтым обозначены возможности, которых явно нет, но их можно использовать через другие (чтение или маппинг памяти). Мой фаворит из этого списка – AsrDrv101 от ASRock. Он устроен наиболее просто и обладает просто огромным списком возможностей, включая даже функцию поиска шаблона по физической памяти (!!)
Неполный перечень возможностей AsrDrv101
- Чтение / запись RAM
- Чтение / запись IO
- Чтение / запись PCI Configuration Space
- Чтение / запись MSR (Model-Specific Register)
- Чтение / запись CR (Control Register)
- Чтение TSC (Time Stamp Counter)
- Чтение PMC (Performance Monitoring Counter)
- Чтение CPUID
- Alloc / Free физической памяти
- Поиск по физической памяти
Самое нехорошее в такой ситуации — если подобный драйвер остаётся запущенным на ПК пользователя, для обращения к нему не нужно даже прав администратора! То есть любая программа с правами пользователя сможет читать и писать физическую память — хоть пароли красть, хоть ядро пропатчить. Именно на это уже ругались другие исследователи. Представьте, что висящая в фоне софтина, красиво моргающая светодиодиками на матплате, открывает доступ ко всей вашей системе. Или вирусы намеренно ставят подобный драйвер, чтобы закрепиться в системе. Впрочем, любой мощный инструмент можно в нехороших целях использовать.
Через Python в дебри
Конечно же я захотел сделать свой небольшой «тулкит» для различных исследований и экспериментов на базе такого драйвера. Причём на Python, мне уж очень нравится, как просто выглядит реализация сложных вещей на этом языке.
Первым делом нужно установить драйвер в систему и запустить его. Делаем «как положено» и сначала кладём драйвер (нужной разрядности!) в System32:
#puts the driver into Windows/System32/drivers folder def SaveDriverFile(self): winPath = os.environ['WINDIR'] sys32Path = os.path.join(winPath, "System32") targetPath = os.path.join(sys32Path, "drivers\\" + self.name + ".sys") file_data = open(self.file_path, "rb").read() open(targetPath, "wb").write(file_data)
Раньше в похожих ситуациях я извращался с папкой %WINDIR%\Sysnative, но почему-то на моей текущей системе такого алиаса не оказалось, хотя Python 32-битный. (по идее, на 64-битных системах обращения 32-битных программ к папке System32 перенаправляются в папку SysWOW64, и чтобы положить файлик именно в System32, нужно обращаться по имени Sysnative).
Затем регистрируем драйвер в системе и запускаем его:
#registers the driver for further startup def RegisterDriver(self): serviceManager = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) driverPath = os.path.join(os.environ['WINDIR'], 'system32\\drivers\\' + self.name + '.sys') serviceHandle = win32service.CreateService(serviceManager,self.name,self.name, win32service.SERVICE_ALL_ACCESS, win32service.SERVICE_KERNEL_DRIVER, win32service.SERVICE_DEMAND_START, win32service.SERVICE_ERROR_NORMAL, driverPath, None,0,None,None,None) win32service.CloseServiceHandle(serviceManager) win32service.CloseServiceHandle(serviceHandle) #starts the driver def RunDriver(self): win32serviceutil.StartService(self.name)
А дальше запущенный драйвер создаёт виртуальный файл (кстати, та самая колонка «имя» в таблице с анализом дров), через запросы к которому и осуществляются дальнейшие действия:
Тоже ничего особенного, открываем файл и делаем ему IoCtl:
#tries to open the driver by name def OpenDriver(self): handle = win32file.CreateFile("\\\\.\\" + self.name, win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, 0, None, win32file.OPEN_EXISTING, win32file.FILE_ATTRIBUTE_NORMAL | win32file.FILE_FLAG_OVERLAPPED, None) if handle == win32file.INVALID_HANDLE_VALUE: return None return handle #performs IOCTL! def IoCtl(self, ioctlCode, inData, outLen=0x1100): out_buf = win32file.DeviceIoControl(self.dh,ioctlCode,inData,outLen,None) return out_buf
Вот здесь чутка подробнее. Я долго думал, как же обеспечить адекватную обработку ситуации, когда таких «скриптов» запущено несколько. Не останавливать драйвер при выходе нехорошо, в идеале нужно смотреть, не использует ли драйвер кто-то ещё и останавливать его только если наш скрипт «последний». Долгие упорные попытки получить количество открытых ссылок на виртуальный файл драйвера ни к чему не привели (я получал только количество ссылок в рамках своего процесса). Причём сама система точно умеет это делать — при остановке драйвера с открытым файлом, он остаётся висеть в «Pending Stop». Если у кого есть идеи — буду благодарен.
В конечном итоге я «подсмотрел», как это делают другие программы. Выяснилось, что большинство либо не заморачиваются, либо просто ищут запущенные процессы с тем же именем. Но одна из исследованных программ имела кардинально другой подход, который я себе и перенял. Вместо того, чтобы переживать по количеству ссылок на файл, просто на каждый запрос открываем и закрываем файл! А если файла нет, значит кто-то остановил драйвер и пытаемся его перезапустить:
#perform IOCTL! def IoCtl(self, ioctlCode, inData, outLen=0x1100): #open driver file link driverHandle = self.OpenDriver() if driverHandle is None: self.ReinstallDriver() driverHandle = self.OpenDriver() #second try if driverHandle is None: return None #perform IOCTL out_buf = win32file.DeviceIoControl(driverHandle,ioctlCode,inData,outLen,None) #close driver file link win32file.CloseHandle(driverHandle) return out_buf
А дальше просто реверсим драйвер и реализуем все нужные нам вызовы:
class PmxInterface: def __init__(self): self.d = PmxDriver("AsrDrv101") def MemRead(self, address, size, access=U8): buf = ctypes.c_buffer(size) request = struct.pack("
PCI Express Config Space
Немного отвлечёмся на один нюанс про PCIE Config Space. С этим адресным пространством не всё так просто - со времён шины PCI для доступа к её конфигурационному пространству используется метод с использованием I/O портов 0xCF8 / 0xCFC. Он применён и в нашем драйвере AsrDrv101:
Но через этот метод доступны только 0x100 байт конфигурационного пространства, в то время как в стандарте PCI Express размер Config Space у устройств может быть достигать 0x1000 байт! И полноценно вычитать их можно только обращением к PCI Extended Config Space, которая замаплена где-то в адресном пространстве, обычно чуть пониже BIOS:
На чипсетах Intel (ну, в их большинстве) указатель на эту область адресного пространства можно взять из конфига PCI устройства 0:0:0 по смещению 0x60, подробнее описано в даташитах:
У AMD я такого не нашёл (наверняка есть, плохо искал), но сам факт неуниверсальности пнул меня в сторону поиска другого решения. Погуглив стандарты, я обнаружил, что указатель на эту область передаётся системе через ACPI таблицу MCFG
А сами ACPI таблицы можно найти через запись RSDP, поискав её сигнатуру по адресам 0xE0000-0xFFFFF, а затем распарсив табличку RSDT. Отлично, здесь нам и пригодится функционал поиска по памяти. Получаем нечто такое:
rsdp = self.PhysSearch(0xE0000, 0x20000, b"RSD PTR ", step=0x10) #use rsdt only for simplicity rsdt = self.MemRead32(rsdp + 0x10) (rsdtSign, rsdtLen) = struct.unpack("
На всякий случай оставляем вариант для чипсетов Intel
if self.PciRead16(PciAddress(0,0,0,0)) == 0x8086: #try intel way pciexbar = self.PciRead64(PciAddress(0,0,0,0x60)) if pciexbar & 1: self.pciMmTopBus = (1 > 1) & 3))) - 1 self.pciMmAddress = pciexbar & 0xFFFF0000
Всё, теперь осталось при необходимости заменить чтение PCI Express Config Space через драйвер на чтение через память. Теперь-то разгуляемся!
Читаем BIOS
В качестве примера применения нашего "тулкита", попробуем набросать скрипт чтения BIOS. Он должен быть "замаплен" где-то в конце 32-битного адресного пространства, потому что компьютер начинает его исполнение с адреса 0xFFFFFFF0. Обычно в ПК стоит флеш-память объёмом 4-16 МБ, поэтому будем "сканировать" адресное пространство с адреса 0xFF000000, как только найдём что-нибудь непустое, будем считать, что тут начался BIOS:
from PyPmx import PmxInterface pmx = PmxInterface() for i in range(0xFF000000, 0x100000000, 0x10000): data = pmx.MemRead(i, 0x20) if data != b"\xFF"*0x20 and data != b"\x00"*0x20: biosLen = 0x100000000-i print("BIOS Found at 0x%x" % i) f = open("dump.bin", "wb") for j in range(0, biosLen, 0x1000): data = pmx.MemRead(i + j, 0x1000) f.write(data) break
В результате получаем:
Но подождите-ка, получилось всего 6 мегабайт, а должно быть 4 или 8 что-то не сходится. А вот так, у чипсетов Intel в адресное пространство мапится не вся флешка BIOS, а только один её регион. И чтобы считать всё остальное, нужно уже использовать SPI интерфейс.
Не беда, лезем в даташит, выясняем, что SPI интерфейс висит на PCI Express:
И для его использования, нужно взаимодействовать с регистрами в BAR0 MMIO по алгоритму:
- Задать адрес для чтения в BIOS_FADDR
- Задать параметры команды в BIOS_HSFTS_CTL
- Прочитать данные из BIOS_FDATA
Пилим новый скрипт для чтения через чипсет:
from PyPmx import PmxInterface, PciAddress, U32 spi = PciAddress(0, 31, 5) pmx = PmxInterface() spiMmio = pmx.PciRead32(spi + 0x10) & 0xFFFFF000 f = open("dump.bin", "wb") for i in range(0, 0x800000, 0x40): # write BIOS_FADDR pmx.MemWrite32(spiMmio + 0x08, i) # write BIOS_HSFTS_CTL # read 0x40 bytes start clear fcerr & fgo cmd = (0
Исполняем и вуаля - в 20 строчек кода считаны все 8 МБ флешки BIOS! (нюанс - в зависимости от настроек, регион ME может быть недоступен для чтения).
Точно так же можно делать всё, что заблагорассудится - делать снифер USB пакетов, посылать произвольные ATA команды диску, повышать частоту процессора и переключать видеокарты. И это всё - с обычными правами администратора:
А если написать свой драйвер?
Некоторые из вас наверняка уже подумали - зачем так изворачиваться, реверсить чужие драйвера, если можно написать свой? И я о таком думал. Более того, есть Open-Source проект chipsec, в котором подобный драйвер уже разработан.
Зайдя на страницу с кодом драйвера, вы сразу наткнетесь на предупреждение:
. !! !! Chipsec should only be run on test systems! !! It should not be installed/deployed on end-user systems! !! !! There are multiple reasons for that: !! !! 1. Chipsec kernel drivers provide raw access to HW resources to !! user-mode applications (like access to physical memory). This would !! allow malware to compromise the OS kernel. !! 2. The driver is distributed as a source code. In order to load it !! on OS which requires signed drivers (e.g. x64 Microsoft Windows 7 !! and higher), you'll need to enable TestSigning mode and self-sign !! the driver binary. Enabling TestSigning (or equivalent) mode also !! turns off important protection of OS kernel. !! !! 3. Due to the nature of access to HW resources, if any chipsec module !! issues incorrect access to these HW resources, OS can crash/hang. !! !! If, for any reason, you want to production sign chipsec driver and !! deploy chipsec on end-user systems, !! DON'T! !! .
В этом предупреждении как раз и описываются все опасности, о которых я рассказывал в начале статьи - инструмент мощный и опасный, следует использовать только в Windows режиме Test Mode, и ни в коем случае не подписывать. Да, без специальной подписи на обычной системе просто так запустить драйвер не получится. Поэтому в примере выше мы и использовали заранее подписанный драйвер от ASRock.
Если кто сильно захочет подписать собственный драйвер - понадобится регистрировать собственную компанию и платить Microsoft. Насколько я нагуглил, физическим лицам такое развлечение недоступно.
Точнее я так думал, до вот этой статьи, глаз зацепился за крайне интересный абзац:
У меня под рукой нет Windows DDK, так что я взял 64-битный vfd.sys , скомпилированный неким critical0, и попросил dartraiden подписать его «древне-китайским способом». Такой драйвер успешно загружается и работает, если vfdwin запущена с правами администратора
Драйвер из статьи действительно подписан, и действительно неким китайским ключом:
Немного поиска этого имени в гугле, и я натыкаюсь на вот эту ссылку, откуда узнаю, что:
- есть давно утёкшие и отозванные ключи для подписи драйверов
- если ими подписать драйвер - он прекрасно принимается системой
- малварщики по всему миру используют это для создания вирусни
Основная загвоздка - заставить майкрософтский SignTool подписать драйвер истёкшим ключом, но для этого даже нашёлся проект на GitHub. Более того, я нашёл даже проект на GitHub для другой утилиты подписи драйверов от TrustAsia, с помощью которого можно подставить для подписи вообще любую дату.
Несколько минут мучений с гугл-переводчиком на телефоне, и мне удалось разобраться в этой утилите и подписать драйвер одним из утекших ключей (который довольно легко отыскался в китайском поисковике):
И точно так же, как и AsrDrv101, драйвер удалось без проблем запустить!
Из чего делаю вывод, что старая идея с написанием своего драйвера вполне себе годная. Как раз не хватает функции маппинга памяти. Но да ладно, оставлю как TODO.
Выводы?
Как видите, имея права администратора, можно делать с компьютером практически что угодно. Будьте внимательны - установка утилит от производителя вашего железа может обернуться дырой в системе. Ну а желающие поэкспериментировать со своим ПК - добро пожаловать на низкий уровень! Наработки выложил на GitHub. Осторожно, бездумное использование чревато BSODами.
В Windows есть фича "Изоляция ядра", которая включает I/O MMU, защищает от DMA атак и так далее (кстати об этом - в следующих сериях)
Так вот, при включении этой опции, некоторые драйвера (в том числе RW Everything и китайско-подписанный chipsec_hlpr) перестают запускаться:
Тем не менее, рассмотренный пример утилиты на базе AsrDrv работает:
На каком языке пишутся драйвера?
Драйвера пишутся на компилируемых языках, поддерживающих бинарные интерфейсы соостветствующих ОС. Это C, C++, assembler, кое-где psacal.
Python этим требованиям не соответствует.
Встречный вопрос: драйвером какого устройства хотите нас порадовать?
Ответ написан более трёх лет назад
Комментировать
Нравится 6 Комментировать
Влад Животнев @inkvizitor68sl
Linux-сисадмин с 8 летним стажем.
Драйвера чего к чему) ?
Если драйвера устройств к винде - то да, C/C++
Если драйвера стораджа к openstack - то они бывают и на python.
Ответ написан более трёх лет назад
Комментировать
Нравится 1 Комментировать
Frontend developer
Нельзя, нужен низкоуровневый язык.
Ответ написан более трёх лет назад
> Если нет, то почему ?
Прям вот только низкоуровневый? То есть на C++ писать уже нельзя, только на ассемблере?
Ваш ответ на вопрос
Войдите, чтобы написать ответ
- Python
Можно ли оптимизировать этот код?
- 1 подписчик
- час назад
- 59 просмотров
- Python
- +1 ещё
Почему не удаляются сообщения в vk_api?
- 1 подписчик
- 11 часов назад
- 21 просмотр
Верно ли что python идеально подходит для написания драйверов устройств
Advertisement
Document details
Linuxformat 86
Published on Feb 10, 2008
Follow this publisher
Magazine about Linux (russian edition)
Read more
Advertisement
Advertisement
Advertisement
Advertisement
Advertisement
Advertisement
Create once. Share everywhere.
- Company - About us
- Company - Careers
- Company - Blog
- Company - Webinars
- Company - Press
Issuu Features
- Issuu Features - Fullscreen Sharing
- Issuu Features - Social Posts
- Issuu Features - Articles
- Issuu Features - Embed
- Issuu Features - Statistics
- Issuu Features - InDesign Integration
- Issuu Features - Cloud Storage Integration
- Issuu Features - GIFs
- Issuu Features - Canva Integration
- Issuu Features - Add Links
- Issuu Features - Teams
- Issuu Features - Video
- Issuu Features - Web-ready Fonts
- Solutions - Designers
- Solutions - Content Marketers
- Solutions - Social Media Managers
- Solutions - Publishers
- Solutions - Education
- Solutions - Salespeople
- Solutions - Use Cases
Industries
- Industries - Internal Communications
- Industries - Marketing and PR
- Industries - Publishing
- Industries - Real Estate
- Industries - Sports
- Industries - Travel
Products & Resources
- Products & Resources - Plans
- Products & Resources - Partnerships
- Products & Resources - Developers
- Products & Resources - Digital Sales
- Products & Resources - Elite Program
- Products & Resources - Publisher Directory
- Products & Resources - Redeem Code
- Products & Resources - Support
Explore Issuu Content
-
- Explore - Arts & Entertainment
- Explore - Business
- Explore - Education
- Explore - Family & Parenting
- Explore - Food & Drink
- Explore - Health & Fitness
- Explore - Hobbies
- Explore - Home & Garden
- Explore - Pets
- Explore - Religion & Spirituality
- Explore - Science
- Explore - Society
- Explore - Sports
- Explore - Style & Fashion
- Explore - Technology & Computing
- Explore - Travel
- Explore - Vehicles
OpenLinux в составе модулей SIM7600E-H
Механизм разработки пользовательского приложения и загрузки его в модуль доступен как под операционной системой Linux, так и Windows. В данной статье мы подробно рассмотрим то, как воспользовавшись примерами из SDK предоставляемого SIMCom Wireless Solutions скомпилировать и загрузить пользовательское приложение в модуль.
Перед написанием статьи один мой знакомый, далекий от разработки под Linux, попросил максимально детально подойти к вопросу описания процесса разработки собственного приложения под модуль SIM7600E-H. Критерием оценки доступности подачи материала стала фраза «так чтобы Я понял».
Приглашаю ознакомиться с тем, что получилось.
Статья регулярно дополняется и обновляется
Прелюдия
Обычно модули сотовой связи используются только для передачи данных, голосовых вызовов, передачи СМС и подобного. Все это делается посредством АТ-команд, отправляемых с внешнего управляющего микроконтроллера. Но есть категория модулей, которые позволяют выполнять пользовательский код, загружаемый извне. В некоторых случаях это значительно сокращает общий бюджет устройства позволяя поставить на плату более простой (а равно бюджетный) микроконтроллер или отказаться от него вовсе. С появлением LTE модулей, управляемых ОС Android или Linux и их мощными ресурсами, можно решать любые задачи, которые доступны популярным процессорам. В этой статье пойдет речь о SIM7600E-H, управляемый ОС Linux. Мы рассмотрим, как загрузить и запустить исполняемое приложение.
Во многом материал базируется на документе “SIM7600 Open Linux development quide”, но некоторые дополнения и в первую очередь русскоязычная версия будут полезны. Статья поможет разобраться тем, кто только начинает освоение модуля дойти до загрузки демонстрационного приложения и даст необходимые навыки для последующей работы.
Коротко о том, кто такой SIM7600E-H
SIM7600E-H – это модуль построенный на базе процессора ARM Cortex-A7 1.3GHz от Qualcomm, имеющий операционную систему Linux (ядро 3.18.20) внутри, способный работать с европейскими (в т.ч. и российскими) диапазонами частот 2G/3G/LTE, поддерживающий Cat.4, обеспечивающий максимальную скорость скачивания до 150Mbps и выгрузки до 50Mbps. Богатая периферия, индустриальный температурный диапазон и наличие встроенной навигации GPS/ГЛОНАСС перекрывают любые требования к современному модульному решению в М2М тематике.
Обзор системы
Модуль SIM7600E-H базируется на операционной системе Linux (ядро 3.18.20). В свою очередь, файловая система построена на базе журналируемой файловой системы UBIFS (Unsorted Block Image File System).
К важным особенностям этой файловой системы относятся:
- работает с разделами, позволяет создавать, удалять, или менять их размер;
- обеспечивает выравнивание записи по всему объему носителя;
- работает с Bad-блоками;
- минимизирует вероятность потери данных при аварийном отключении питании или других сбоях;
- ведение журналов.
Описание взято отсюда , там же более подробно рассказано о таковой файловой системе.
Т.е. данный тип файловой системы идеально подходит для жестких условий работы модуля и возможных проблемах с питанием. Но это не значит, что условия нестабильного питания будут являться ожидаемым режимом работы модуля, это говорит только о большей жизнеспособности устройства.
Память
Распределение областей памяти построено следующим образом:
Нужно выделить три основных области:
ubi0:rootfs – доступен только для чтения и содержит само ядро Linux
ubi0:usrfs – используется преимущественно для пользовательской программы и хранения данных
ubi0:cahcefs – зарезервировано для FOTA обновлений. Если доступного пространства будет недостаточно для загрузки обновления – система удалит неиспользуемые файлы и таким образом высвободит место. Но из соображений безопасности – не стоит располагать там свои файлы.Все три раздела распределены следующим образом:
Filesystem
Size
Used
Available
Use%
Mounted onubi0:cachefs
50.3M
20K
47.7M
0%
/cacheДоступная функциональность
Как уже было упомянуто выше, модуль построен на базе чипсета Cortex A7 от Qualcomm. Было бы неправильно не предоставить такое высокопроизводительное ядро для обработки пользовательской программы и разгрузки основного процессора устройства, переложив на модуль некоторую часть программы.
Для пользовательской программы нам будут доступны следующие режимы работы периферии:
Pin No.
Name
Sys GPIO No.
Default action
Func1
Func2
Pull
Wakeup interrupt33
GPIO3
GPIO_1020
MIFI_POWER_EN
GPIO
MIFI_POWER_EN
B-PU
—34
GPIO6
GPIO_1023
MIFI_SLEEP_CLK
GPIO
MIFI_SLEEP_CLK
B-PD
—48
SD_DET
GPIO_26
GPIO
GPIO
SD_DET
B-PD
X49
STATUS
GPIO_52
Status
GPIO
Status
B-PD
X50
GPIO43
GPIO_36
MIFI_COEX
GPIO
MIFI_COEX
B-PD
—Согласитесь, перечень внушительный и обратите внимание: часть периферии используется для работы модуля в качестве роутера. Т.е. на базе такого модуля можно сделать небольшой роутер, который будет раздавать интернет по Wi-Fi. Кстати, есть уже готовое решение, называется SIM7600E-H-MIFI и представляет собой miniPCIE карточку, с напаянным модулем SIM7600E-H и несколькими антенными выводами, один из них является антенной Wi-Fi. Впрочем, это уже тема для отдельного материала.
Среда (не день недели)
SIMCom Wireless Solutions предоставляют возможность разработчикам выбрать самостоятельно наиболее знакомую среду разработки под Linux или Windows. Если речь идет об одном исполняемом приложении на модуле, то лучше выбрать Windows, так получится быстрее и проще. Если предполагается сложная архитектура приложения и последующие апгрейды – лучше использовать Linux. Также нам потребуется Linux для компиляции исполняемых файлов для последующей загрузки в модуль, для компиляции вполне достаточно виртуальной машины.
Из того что вам потребуется, недоступного для скачивания в свободном доступе – SDK, которую можно запросить у своего дистрибьютора.
Установка утилит для работы с модулем
Здесь и далее мы будем работать под Windows как наиболее знакомой ОС большинству пользователей.
Нам потребуется за несколько простых шагов установить необходимое ПО для последующего освоения работы с модулем:
Установка GNU/Linux
Для сборки приложения можно воспользоваться любым совместимым с ARM-Linux компилятором. Мы же воспользуемся SourceryCodeBenchLiteARM GNU/Linuxtranslater доступным для скачивания по ссылке .
Чтобы все компоненты были установлены верно, оставлю несколько скриншотов процесса установки. В принципе, в установке нет ничего сложного.
Чтобы все компоненты были установлены верно, оставлю несколько скриншотов процесса установки. В принципе, в установке нет ничего сложного.
- Принимаем лицензионное соглашение
- Указываем папку установки
- Необходимые компоненты оставляем без изменений
- Оставляем как есть
- Несколько раз “Next”, “Install” и в принципе все
Установка Cygwin
Далее для разработки на потребуется набор библиотек и утилит из набора предоставляемого Cygwin . Тут все просто, актуальную версию Cygwin можно скачать бесплатно на официальном сайте проекта, на момент написания статьи была доступна версия 3.1.5, ее мы и использовали при подготовке материала.
В установке Cygwin нет ничего сложного, единственное что нужно будет выбрать – зеркало, с которого установщик скачает необходимые файлы, выбираем любое и устанавливаем, а также набор утилит и библиотек, оставляем выбранными все доступные библиотеки и утилиты.
Установка драйверов
После того, как модуль будет подключен к ПК потребуется установить драйвера. Их можно запросить у своего дистрибьютора (рекомендуется). Искать в сети Интернет самостоятельно не рекомендую, т.к. может потребоваться много времени на поиск с чем был связан конфликт устройств.
Среди выделенных портов мы видим следующие:
Windows
Linux
ОписаниеSimTech HS-USB Diagnostics
USB Serial
Diagnostic InterfaceSimTech HS-USB NMEA
USB Serial
GPS NMEA InterfaceSimTech HS-USB AT Port
USB Serial
AT port InterfaceSimTech HS-USB Modem
USB Serial
Modem port InterfaceSimTech HS-USB Audio
USB Serial
USB Audio InterfaceSimTech HS-USB WWAN Adapter
USB Net
NDIS wwan InterfaceAndroid Composite ADB Interface
USB ADB
Android add debug portКак вы наверняка обратили внимание, среди портов на скриншоте нет USB ADB, это по причине того, что ADB порт в модуле по умолчанию закрыт и его нужно включить, отправив команду ‘AT+CUSBADB=1’ в АТ-порт модуля и перезагрузить его (это можно сделать командой ‘AT+CRESET’).
В итоге получим нужный интерфейс в диспетчере устройств:
С драйверами закончили, переходим к ADB.
Установка ADB
Заходим на официальный сайт Android Developer по ссылке . Не будем качать громоздкий Android Studio, нам достаточно командной строки, доступную для скачивания по ссылке «Download SDK Platform-Tools for Windows».
Качаем и распаковываем полученный архив в корень диска C.
Переменные среды
После установки Cygwin потребуется добавить путь Cygwin/bin/ в переменные среды разработки (Классическая Панель управления → Система → Дополнительные параметры системы → Дополнительно → Переменные среды → Системные переменные → Path → Изменить) так как показано на скриншоте ниже:
Аналогичным образом добавляем путь к скачанному и распакованному архиву ADB в корень диска C.
Несколько раз нажимаем ОК и перезагружаем компьютер.
После перезагрузки можно легко проверить корректно ли работает ADB, открыв командную строку (Win+R → cmd) и набрав команду ‘adb version’. Получим примерно такой результат:
Подключим модуль к ПК (если так случилось что отключили) и проверим видит ли его ADB командой ‘adb devices’:
Готово, на этом настройка подключения к модулю завершена и мы можем запустить shell для работы с модулем.
Распаковка и компиляция SDK
После того как мы получили доступ к shell и можем начать работу с командной строкой модуля, попробуем скомпилировать наше первое приложение для загрузки в модуль.
С этим у многих могут возникнуть сложности! Т.к. модуль работает на операционной системе Linux, во избежание коллизий при компиляции кода под Windows – лучше всего компилировать в родной среде – Linux.
Не будем подробно останавливаться на том, как в отсутствие Linux и желания устанавливать его на свою машину, можно установить его на виртуальную. Мы же воспользуемся VirtualBox, установим Ubuntu версии 20.04 (актуальная версия на момент написания статьи) и уже под ней начнем работу с компиляторами, SDK и т.п.
Переходим в среду Linux и распаковываем архив, полученный от дистрибьютора.
simcom@VirtualBox:~/Desktop/OpenLinux$ sudo tar -xzf MDM9x07_OL_2U_22_V1.12_191227.tar.gz
Переходим в каталог sim_open_sdk и добавляем окружение:
simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ cd sim_open_sdk simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ source sim_crosscompile/sim-crosscompile-env-init
Остаемся в этой же папке и последующие команды выполняем находясь в ней.
Устанавливаем библиотеку libncurses5-dev, если она не была установлена:simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ sudo apt-get update && sudo apt-get install libncurses5-dev -y
Python, если он так же не был установлен:
simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ sudo apt-get install python -y
simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ sudo apt-get install gcc
Компиляция:
Теперь нам потребуется скомпилировать несколько файлов, последовательно выполняем следующие команды.
Если при компиляции выскочит окно настройки ядра – просто выбираем Exit и возвращаемся в консоль, у нас сейчас нет необходимости конфигурировать ядро.
simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ make
simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ make aboot
simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ make kernel_menuconfig simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ make kernel
Компилируем корневую файловую систему:
simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ make rootfs
Для пользователей Linux будет актуальным скомпилировать драйвер модуля:
simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ make kernel_module
simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ make demo
После чего в директории sim_open_sdk/output появится несколько новых файлов:
simcom@VirtualBox:~/Desktop/OpenLinux/sim_open_sdk$ ls output/ appsboot.mbn boot.img demo_app helloworld system.img
Демо
Попробуем загрузить демонстрацию в наш модуль и посмотрим, что из этого получится.
Загрузка
В директории sim_open_sdk мы можем увидеть файл demo_app. Забираем его и переносим в корень диска C на ПК к которому подключен модуль. После чего запускаем командную строку Windows (Win+R -> cmd) и вводим:
C:>adb push C:demo_app /data/
Консоль нам сообщит:
C:demo_app: 1 file pushed, 0 skipped. 151.4 MB/s (838900 bytes in 0.005s)
Это значит, что файл был успешно отправлен на модуль и нам остается только запустить его. Не будем медлить.
C:>adb shell
Расширяем права загруженного файла:
/ # cdhmod 777 /data/demo_app
/ # /data/demo_app
В этой же консоли модуль нам сообщит следующее:
SDK_VER : SIM_SDK_VER_20191205 DEMO_VER: SIM_SDK_VER_20191205 Please select an option to test from the items listed below. 1. WIFI 2. VOICE CALL 3. DATA CALL 4. SMS 5. WDS(APN) 6. NAS 7. AT 8. OTA 9. TTS 10. GPIO 11. GPS 12. Bluetooth 13. TCP/UDP 14. Timer 15. ADC 16. I2C 17. UIM(SimCard) 18. DMS(IMEI,MEID) 19. UART 20. SPI 21. Version 22. Ethernet 23. FTP 24. SSL 25. HTTP(S) 26. FTP(S) 27. MQTT(S) 28. ALSA 29. DEV 30. AUDIO 31. JSON 32. LBS 99. EXIT Option >
Давайте посмотрим IMEI модуля, введем 7 (переход в командный режим) и после введем 5:
Please select an option to test from the items listed below. 1. WIFI 2. VOICE CALL 3. DATA CALL 4. SMS 5. WDS(APN) 6. NAS 7. AT 8. OTA 9. TTS 10. GPIO 11. GPS 12. Bluetooth 13. TCP/UDP 14. Timer 15. ADC 16. I2C 17. UIM(SimCard) 18. DMS(IMEI,MEID) 19. UART 20. SPI 21. Version 22. Ethernet 23. FTP 24. SSL 25. HTTP(S) 26. FTP(S) 27. MQTT(S) 28. ALSA 29. DEV 30. AUDIO 31. JSON 32. LBS 99. EXIT Option > 7 Please select an option to test from the items listed below. 1. get Module Version 2. get CSQ 3. get CREG 4. get ICCID 5. get IMEI 6. get CIMI 99. back Option > 5 IMEI: 867584030090489 Please select an option to test from the items listed below. 1. get Module Version 2. get CSQ 3. get CREG 4. get ICCID 5. get IMEI 6. get CIMI 99. back Option >
Таким образом мы увидим IMEI модуля.
В качестве заключения
Надеюсь, нам удалось составить общее представление о том, как начать работу с модулем. В следующих статьях мы подробнее рассмотрим возможности, которые предоставляет платформа SIM7600E-H, а также то, каким образом можно удаленно обновить собственное приложение в модуле.
Приглашаю задавать вопросы в комментариях, а также указать какой аспект возможностей модуля следует отразить в последующих статьях.
Добавить комментарий Отменить ответ
Для отправки комментария вам необходимо авторизоваться.