Можно ли закодировать драйвер устройства на Java?

введение

Я слышал что-то о написании драйверов устройств в Java (слышал как в "ушами", а не из интернета) и было интересно... Я всегда думал, что драйверы устройств работают на уровне операционной системы и, следовательно, должны быть написаны на том же языке, что и ОС (таким образом, в основном C, я полагаю)

вопросы

  1. Я вообще ошибаюсь в этом предположение? (кажется так)
  2. как может водитель в "иностранец" язык будет использоваться в ОС?
  3. каковы требования (от a язык программирования точка зрения) для драйвера устройства в любом случае?

Спасибо за внимание

13 ответов


есть несколько способов сделать это.

во-первых, код, работающий на "уровне ОС", не должен быть написан на том же языке, что и ОС. Он просто должен быть связан вместе с кодом ОС. Практически все языки могут взаимодействовать с C, что действительно все, что нужно.

Так язык-мудрый, технически нет никаких проблем. Функции Java могут вызывать функции C, а функции C могут вызывать функции Java. И если ОС не написана на C (давайте скажем, ради аргумента, что он написан на C++), тогда код OS C++ может вызывать какой-то промежуточный код C, который перенаправляет на вашу Java, и наоборот. C в значительной степени a лингва франка программирования.

после компиляции программы (в собственный код) ее исходный язык больше не имеет значения. Ассемблер выглядит примерно одинаково независимо от того, на каком языке был написан исходный код перед компиляцией. Пока вы используете то же соглашение о вызовах, что и ОС, это не проблема.

большая проблема-поддержка времени выполнения. В ОС доступно не так много программных сервисов. Например, обычно нет виртуальной машины Java. (Нет причин, почему технически не может быть, но обычно, но обычно, можно с уверенностью предположить, что его нет).

к сожалению, в своем представлении "по умолчанию", как байт-код Java, программа Java требует много инфраструктуры. Для интерпретации требуется Java VM и JIT байт-код, и ему нужна библиотека классов и так далее.

но есть два способа обойти это:

  • поддержка Java в ядре. Это был бы необычный шаг, но его можно было сделать.
  • или скомпилируйте исходный код Java в собственный формат. Программа Java не должна компилироваться в байт-код Java. Вы можете скомпилировать его в ассемблер x86. То же самое относится к любым библиотекам классов, которые вы используете. Они тоже могут быть скомпилированы вплоть до ассемблер. Конечно, части библиотеки классов Java требуют определенных функций ОС, которые будут недоступны, но тогда можно избежать использования этих классов.

Так что да, это можно сделать. Но это не просто, и неясно, что вы выиграете.

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


запись драйверов устройств Solaris в Java охватывает дисковое устройство RAM, написанное на Java.

еще один для Linux. Идет более подробно о том, почему вы можете захотеть DD в Java (так как некоторые люди задавались вопросом, глядя на другие сообщения и комментарии)


Это не невозможно, но, возможно, трудно и, возможно, не имеет большого смысла.

возможно, потому что Java-это обычный язык программирования, пока у вас есть какой-то способ доступа к данным, это не проблема. Обычно в современной ОС ядро имеет слой, позволяющий каким-то образом получить необработанный доступ к оборудованию. Также уже существуют драйверы в пользовательском пространстве, по крайней мере, часть userspace не должна быть проблемой для реализации в Java.

это, возможно, не слишком много смысла, потому что ядро должно запустить JVM для выполнения драйвера. Также JVM-реализации обычно съедают много памяти.

вы также можете использовать Java-код, скомпилированный для выполнения изначально на платформе (не с помощью JVM). Обычно это не так эффективно, но может быть подходящим для драйвера устройства.

вопрос в том, имеет ли смысл реализовать драйвер на Java? Или по-другому: какую пользу вы надеетесь, если вы используете Java для реализации водитель вместо другой альтернативы? Если вы можете ответить на этот вопрос, вы должны найти способ сделать это возможным.

В конце намек на JNode, проект, который пытается реализовать полную ОС исключительно на основе Java.


У вас слишком узкий взгляд на драйверы устройств.

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

в этих случаях существует общий протокол низкого уровня, который обрабатывается в собственном коде, и драйвер Java обрабатывает специфику устройства (форматы данных, государственные машины,...).


возможно, вы слышали ссылку на JDDK?

запись драйвера устройства 100% в Java-это невозможно без собственного кода для обеспечения взаимодействия между (1) точками входа и соглашениями драйвера для конкретной ОС и (2) экземпляром JVM. Экземпляр JVM может быть запущен "в процессе" (и "в процессе" может иметь разные значения в зависимости от ОС и от того, является ли драйвер драйвером режима ядра или пользовательского режима) или как отдельный процесс "пользователь-земля", с которым может взаимодействовать тонкий, родной адаптационный слой драйвера и на который указанный адаптационный слой драйвера может разгрузить фактическую работу пользователя-земля.


драйвер устройства может быть много чего

Я на самом деле пишу драйверы устройств на java для жизни:драйверы для промышленных устройств, как масштабы или веся приборы, упаковывая машины, блоки развертки штрихкода, веся мосты, принтеры сумки и коробки ... Java-действительно хороший выбор здесь.

промышленные устройства очень отличается от ваших домашних / офисных устройств (например, сканеры, принтеры). Особенно в производство (например, еда), компании выбирают все больше и больше для централизованного сервера, который запускает приложение MES (например, разработанное на Java)сервер MES должен взаимодействовать с устройствами производственной линии, но также содержит бизнес-логику. Java-это язык, который может делать и то, и другое.

где ваши домашние / офисные устройства часто встроены в ваш компьютер или подключены к USB-кабелю, эти промышленные приборы обычно используют локальные сети или разъемы RS232. Таким образом, по сути, практически каждый язык может выполнить эту работу.

в этой области пока не так много стандартизации. большинство поставщиков предпочитают создавать свой собственный протокол для своих устройств. В конце концов, они строители оборудования, а не гении программного обеспечения. В результате существует большое разнообразие протоколов. Некоторые поставщики предпочитают простые текстовые протоколы, но другие предпочитают сложные двоичные протоколы с CRC-кодами, фреймингом,... Иногда им нравится складывать несколько протоколы (например, алгоритм рукопожатия конкретного поставщика поверх слоя OPC). сильный язык ООП имеет много преимуществ.

например. Я видел java-печать с непрерывной скоростью 100 мс / цикл. Это включает в себя создание уникальной этикетки, отправку ее на принтер, получение подтверждения, печать на бумаге и нанесение ее на изделие с использованием давления воздуха.

таким образом, мощность java:

  • это полезно как для бизнес-логики, так и для сложного взаимодействия.
  • оно как раз как надежно в сообщении с гнездами как C.
  • некоторые драйверы могут извлечь выгоду из мощности ООП Java.
  • Java достаточно быстро.

Это можно для компиляции java-кода в аппаратные собственные (т. е. не байт-код JVM) инструкции. См., например,GCJ. С этим в руке вы намного ближе к возможности компиляции драйверов устройств, чем раньше.

Я не знаю, насколько это практично.


возможно?

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

вероятно?

не может. По крайней мере, не в мире Windows или MacOS или даже Linux... По крайней мере, не в ближайшее время. Потому что такие языки, как C# и Java, зависят от среды CLR и JVM. Способ работы этих языков означает, что они не могут быть эффективно загружены в ring0.

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


для мотивации, пожалуйста, помните, что есть много быстрых языков, которые лучше, чем C для программирования; они могут быть не так быстро, как C, но они являются безопасными языками: если вы сделаете ошибку, вы не получите неопределенное поведение. И "неопределенное поведение" включает выполнение произвольного кода, предоставленного некоторым злоумышленником, который форматирует ваш HD. Многие функциональные языки обычно компилируются в собственный код.

драйверы устройств содержат большинство ошибок в ядре ОС - я знаю, что для Linux (Линус Торвальдс и другие продолжают говорить так), и я слышал, что для Windows. В то время как для диска или драйвера Ethernet вам нужна первоклассная производительность, и в то время как в драйверах Linux сегодня are узкое место для 10G Ethernet или SSD-дисков, большинству драйверов не нужна такая большая скорость - все компьютеры ждут с одинаковой скоростью.

вот почему существуют различные проекты позволяют писать драйверы, которые работают вне ядра, даже если это вызывает замедление, когда вы можете сделать это, вы можете использовать любой язык; вам понадобятся привязки Java для используемой библиотеки аппаратного управления - если вы пишете драйвер на C, у вас все равно будет библиотека с привязками C.

для драйверов в режиме ядра есть две проблемы, которые я еще не видел:

  • сборка мусора, и это жесткое требование. Вам нужно написать сборщик мусора в ядре; некоторые алгоритмы GC полагаются на виртуальную память, и вы не можете их использовать. Кроме того, вам, вероятно, нужно сканировать всю память ОС, чтобы найти корни для GC. Наконец, я бы доверял только алгоритму, гарантирующему (мягкий) GC в реальном времени, что сделало бы накладные расходы еще больше. Читая статью, которая упоминалась о драйверах устройств Java поверх Linux, они просто сдаются и требуют от программистов вручную освободить память. Они пытаются утверждать, что это не поставит под угрозу безопасность, но я не думаю, что их аргумент убедителен - это даже не ясно понимают ли они, что сбор мусора необходим для безопасного языка.

  • отражение и загрузка класса. Полная реализация Java, даже при запуске собственного кода, должна иметь возможность загружать новый код. Это библиотека, которую вы можете избежать, но если у вас есть интерпретатор или JIT-компилятор в ядре (и нет реальной причины, которая делает это технически невозможным).

  • производительность. Статья о JVM на Linux очень плохая, и их номера производительности не убедительны-действительно, они тестируют сетевой драйвер USB 1.1, а затем показывают, что производительность не так уж плоха! Однако, если приложить достаточно усилий, наверняка можно сделать что-то лучшее.

две последние вещи:

  • Я хотел бы упомянуть Singularity, которая является полной ОС, написанной в варианте C#, только с аппаратным уровнем абстракции на родном языке.
  • о picoJava, это плохая идея использовать его, если ваша система это действительно ограниченная память, как смарт-карта. Клифф клик уже объяснил, почему: это дает лучшую производительность, чтобы написать хороший JIT, и в настоящее время даже смартфоны могут это поддержать.

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

в Linux существует несколько пользовательских (т. е. неядерных) реализаций файловых систем, использующих общую абстракцию слой называется (fuse), который позволяет программам user-land реализовывать вещи, которые обычно выполняются в ядре.


Windows Driver Foundation (WDF) является Microsoft API, который позволяет как пользователей и ядро драйверы устройств режима для записи. Это делается сегодня, и он теперь совместим с w2k и позже (раньше не было w2k в качестве мишени). Нет причин, по которым звонки JNI не могут быть сделаны для выполнения некоторой работы в JRE . . . (предполагая, что JNI по-прежнему является способом вызова Java из C/C++ . . . мои знания датируются в этой области). Это может быть интересный способ иметь алгоритмы высокого уровня непосредственно жевать данные из USB-канала для чего-то в этом роде . . . классная штука!


драйверы устройств PCIe user space могут быть написаны на чистом Java. См.JVerbs для получения подробной информации о прямом аппаратном доступе на основе памяти в контексте OFED. Это метод, который может быть использован для создания очень высокопроизводительных систем.

вы можете проверить шину PCI, чтобы определить области памяти для данного устройства, какие порты у него есть и т. д. Области памяти могут быть сопоставлены с процессом JVM.

конечно, вы несете ответственность за реализацию все себя.

Я не сказал легко. Я сказал Возможно. ;)

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


прежде всего, обратите внимание, что я не эксперт по драйверам устройств (хотя я сам написал несколько в тот день), а тем более эксперт по Java.

давайте оставим тот факт, что написание драйверов устройств на языке высокого уровня не является хорошей идеей (для производительности и, возможно, по многим другим причинам) в стороне на мгновение, и ответим на ваш вопрос.

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

, большинство драйверы устройств должны делать много низкоуровневых вещей, таких как обработка прерываний и общение с ОС с помощью API ОС и системных вызовов, которые, я считаю, вы не можете сделать на Java.

но, если ваше устройство взаимодействует, используя, скажем, последовательный порт или USB, и если ОС не обязательно должна знать об устройстве (только ваше приложение будет иметь доступ к устройству*), то вы можете написать драйвер на любом языке, который предоставляет необходимые средства для доступа к устройству устройство.

Так, например, вы, вероятно, не можете написать драйвер карты SCSI на Java, но вы можете написать драйвер для проприетарного устройства управления, USB lava lamp, лицензионного ключа и т. д.

* очевидный вопрос здесь, конечно, это считается как водитель?