是否可以用 Java 编写设备驱动程序?

发布于 2024-07-15 23:49:18 字数 327 浏览 10 评论 0原文

简介

我听说过一些关于用 Java 编写设备驱动程序的事情(是“用我的耳朵”听到的,而不是从互联网上听到的)并且想知道......我一直认为设备驱动程序在操作系统级别上运行,因此必须以相同的方式编写语言作为操作系统(因此主要是 CI 假设)

问题

  1. 我对此通常是错误的吗 假设? (好像是这样)
  2. 司机怎么可能是“外星人” 操作系统中使用的语言?
  3. 有哪些要求(来自 编程语言的观点) 无论如何,对于设备驱动程序?

感谢您的阅读

Introduction

I heard something about writing device drivers in Java (heard as in "with my ears", not from the internet) and was wondering... I always thought device drivers operated on an operating system level and thus must be written in the same language as the OS (thus mostly C I suppose)

Questions

  1. Am I generally wrong with this
    assumption? (it seems so)
  2. How can a driver in an "alien"
    language be used in the OS?
  3. What are the requirements (from a
    programming language point of view)
    for a device driver anyway?

Thanks for reading

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

温折酒 2024-07-22 23:49:18

有几种方法可以做到这一点。

首先,在“操作系统级别”运行的代码不需要使用与操作系统相同的语言编写。 它只需能够与操作系统代码链接在一起。 几乎所有语言都可以与 C 进行互操作,这确实是所需要的。

所以从语言角度来说,技术上是没有问题的。 Java函数可以调用C函数,C函数也可以调用Java函数。 如果操作系统不是用 C 编写的(假设它是用 C++ 编写的),那么操作系统 C++ 代码可以调用一些中间 C 代码,这些代码转发到 Java,反之亦然。 C 几乎是编程的通用语言。

一旦程序被编译(为本机代码),其源语言就不再相关。 无论编译前源代码是用哪种语言编写的,汇编器看起来都差不多。 只要您使用与操作系统相同的调用约定,就没有问题。

一个更大的问题是运行时支持。 操作系统中提供的软件服务并不多。 例如,通常没有 Java 虚拟机。 (没有理由说技术上不可能存在,但通常情况下,可以安全地假设它不存在)。

不幸的是,在其“默认”表示形式中,作为 Java 字节码,Java 程序需要大量基础设施。 它需要Java VM来解释和JIT字节码,并且需要类库等等。

但有两种方法可以解决这个问题:

  • 在内核中支持 Java。 这将是一个不寻常的步骤,但它是可以做到的。
  • 或者将 Java 源代码编译为本机格式。 Java 程序不必编译为 Java 字节码。 您可以将其编译为 x86 汇编程序。 对于您使用的任何类库也是如此。 这些也可以一直编译为汇编程序。 当然,Java 类库的某些部分需要某些不可用的操作系统功能,但可以避免使用这些类。

所以是的,这是可以做到的。 但这并不简单,也不清楚你会得到什么。

当然,另一个问题可能是 Java 不允许您访问任意内存位置,这将使许多硬件通信变得非常棘手。 但这也可以解决,也许可以通过调用非常简单的 C 函数,这些函数只是将相关内存区域作为数组返回供 Java 处理。

There are a couple of ways this can be done.

First, code running at "OS level" does not need to be written in the same language as the OS. It merely has to be able to be linked together with OS code. Virtually all languages can interoperate with C, which is really all that's needed.

So language-wise, there is technically no problem. Java functions can call C functions, and C functions can call Java functions. And if the OS isn't written in C (let's say, for the sake of argument that it's written in C++), then the OS C++ code can call into some intermediate C code, which forwards to your Java, and vice versa. C is pretty much a lingua franca of programming.

Once a program has been compiled (to native code), its source language is no longer relevant. Assembler looks much the same regardless of which language the source code was written in before compilation. As long as you use the same calling convention as the OS, it's no problem.

A bigger problem is runtime support. Not a lot of software services are available in the OS. There usually is no Java virtual machine, for example. (There is no reason why there technically couldn't be, but usually, but usually, it's safe to assume that it's not present).

Unfortunately, in its "default" representation, as Java bytecode, a Java program requires a lot of infrastructure. It needs the Java VM to interpret and JIT the bytecode, and it needs the class library and so on.

But there are two ways around this:

  • Support Java in the kernel. This would be an unusual step, but it could be done.
  • Or compile your Java source code to a native format. A Java program doesn't have to be compiled to Java bytecode. You could compile it to x86 assembler. The same goes for whatever class libraries you use. Those too could be compiled all the way to assembler. Of course, parts of the Java class library requires certain OS features that won't be available, but then use of those classes could be avoided.

So yes, it can be done. But it's not straightforward, and it's unclear what you'd gain.

Of course another problem may be that Java won't let you access arbitrary memory locations, which would make a lot of hardware communication pretty tricky. But that could be worked around too, perhaps by calling into very simple C functions which simply return the relevant memory areas as arrays for Java to work on.

心意如水 2024-07-22 23:49:18

用 Java 编写 Solaris 设备驱动程序 涵盖了用 Java 编写的 A RAM 磁盘设备。

另一个适用于 Linux 的。 更深入地说明为什么您可能也需要 Java DD(因为有些人对其他帖子和评论的外观感到好奇)

Writing Solaris Device Drivers in Java covers a A RAM disk device written in Java.

Another one for Linux. Goes more in depth on why you might want a DD in Java as well (since some people were wondering by the looks of the other posts and comments)

蓝梦月影 2024-07-22 23:49:18

设备驱动程序可以是很多东西

我实际上以java编写设备驱动程序为生:工业设备驱动程序,例如秤或称重设备、包装机、条形码扫描仪、秤桥、袋子和盒子打印机…… Java 是一个非常好的选择。

一些示例

工业设备与您的家庭/办公室设备非常不同(例如扫描仪、打印机)。 特别是在制造业(例如食品),公司越来越多地选择运行 MES 应用程序(例如用 Java 开发)的集中式服务器MES 服务器需要与生产线的设备进行交互,但也包含业务逻辑.Java 是一种可以做到这两点的语言。

您的家庭/办公室设备通常内置于计算机或通过 USB 电缆连接,而这些工业设备通常使用以太网或 RS232 连接器。因此,从本质上讲,几乎每种语言都可以实现工作。

该领域还没有太多标准化。大多数供应商更喜欢为其设备创建自己的协议。 毕竟他们是硬件建造者,而不是软件天才。 结果是协议具有高度多样性。 一些供应商更喜欢简单的纯文本协议,但其他供应商更喜欢带有 CRC 代码、帧的复杂二进制协议……有时他们喜欢堆叠多个协议(例如,在 OPC 层之上的供应商特定握手算法)。 强大的 OOP 语言在这里有很多优势。

例如,我见过 java 以 100ms/cycle 的连续速度打印。 这包括生成独特的标签、将其发送到打印机、接收确认、将其打印在纸上并使用气压将其粘贴到产品上。

总之,java 的强大之处:

  • 它对于业务逻辑和复杂的接口都很有用。
  • 它在与套接字通信方面与 C 语言一样可靠。
  • 一些驱动程序可以从 Java 的 OOP 功能中受益。
  • Java 足够快。

A device driver could be a lot of things

I actually write device drivers in java for a living: drivers for industrial devices, such as scales or weighing devices, packaging machines, barcode scanners, weighing bridges, bag and box printers, ... Java is a really good choice here.

Some examples

Industrial devices are very different from your home/office devices (e.g. scanners, printers). Especially in manufacturing (e.g. food), companies opt more and more for a centralized server which runs an MES application (e.g. developed in Java) The MES server needs to interface with the devices of the production line, but also contains business logic. Java is a language that can do both.

Where your home/office devices are often built-in to your computer or connected with an USB cable, these industrial devices usually use Ethernet or RS232 connectors. So, in essence, pretty much every language could do the job.

There is not much standardisation in this area yet. Most vendors prefer to create their own protocol for their devices. After all they are hardware builders, not software geniuses. The result is that there is a high diversity of protocols. Some vendors prefer simple plain-text protocols, but others prefer complex binary protocols with CRC codes, framing, ... Sometimes they like to stack multiple protocols (e.g. a vendor specific handshaking algorithm on top of an OPC layer). A strong OOP language has a lot of advantages here.

E.g. I've seen java print at a continuous speed of 100ms/cycle. This includes generating a unique label, sending it to the printer, receiving a confirmation, printing it on paper and applying it to the product using air pressure.

In summary, the power of java:

  • It is useful for both business logic as complex interfacing.
  • It is just as reliable in communication with sockets as C.
  • Some drivers can benifit from Java's OOP power.
  • Java is fast enough.
烟花肆意 2024-07-22 23:49:18

这并非不可能,但可能很难,而且可能没有多大意义。

有可能,因为Java是一种普通的编程语言,只要你有某种方式访问​​数据,就没有问题。 通常,在现代操作系统中,内核有一个层允许以某种方式对硬件进行原始访问。 用户空间中也已经存在驱动程序,至少用户空间部分在Java中实现应该没有问题。

这可能没有多大意义,因为内核必须启动 JVM 来执行驱动程序。 而且 JVM 实现通常会消耗大量内存。

您还可以使用编译为在平台上本机执行的 Java 代码(而不是借助 JVM)。 这通常效率不高,但它可能适合设备驱动程序。

问题是,用Java实现驱动程序有意义吗? 或者换句话说:如果您使用 Java 来实现驱动程序而不是其他替代方案,您希望获得什么好处? 如果你能回答这个问题,你就应该找到一种方法让它成为可能。

最后提示JNode,一个试图实现一个完全基于Java的完整操作系统的项目。

It's not impossible, but possibly hard and possibly makes not much sense.

Possible is it, because Java is a normal programming language, as long as you have some way to access the data, it's no problem. Normally in a modern OS the kernel has a layer to allow raw access to hardware in some way. Also already exist drivers in userspace, at least the userspace-part should be no problem to implement in Java.

It makes possibly not too much sense, because the kernel has to start a JVM to execute the driver. Also JVM-implementations normally eat up much memory.

You could also use Java-code compiled to be executed natively on the platform (not with the help of a JVM). This is usually not that efficient, but it could be suitable for a device-driver.

The question is, does it make sense to implement the driver in Java? Or stated in another way: What is the benefit you hope for, if you use Java for implementing the driver instead of another alternative? If you can answer this question, you should find a way to make it possible.

At the end the hint to JNode, a project that tries to implement a complete OS purely based on Java.

深居我梦 2024-07-22 23:49:18

您对设备驱动程序的看法太狭隘了。

我在汽车应用程序中的 MOST 之上编写了此类设备驱动程序。 如果 Java 获得了一个像样的 USB 库,那么更广泛的用途可能是 USB 设备的驱动程序。

在这些情况下,有一个在本机代码中处理的通用低级协议,并且 Java 驱动程序处理设备细节(数据格式、状态机等)。

You have a too narrow view of device drivers.

I have written such device drivers on top of MOST in an automotive application. A more widespread use might be drivers for USB devices if Java ever gets a decent USB library.

In these cases there is a generic low-level protocol which is handled in native code, and the Java driver handles the device specifics (data formats, state machines, ...).

赠我空喜 2024-07-22 23:49:18

出于动机,请记住,有很多快速语言比 C 更适合编程; 它们可能不如 C 语言快,但它们是安全语言:如果您犯了错误,您不会得到未定义的行为。 “未定义的行为”包括执行某些攻击者提供的格式化您的硬盘的任意代码。
许多函数式语言通常被编译为本机代码。

设备驱动程序包含操作系统内核中最多的错误 - 我知道 Linux 是这样(Linus Torvalds 和其他人一直这么说),我听说 Windows 也是如此。 虽然对于磁盘或以太网驱动程序,您需要一流的性能,而在当今的 Linux 驱动程序中,是 10G 以太网或 SSD 磁盘的瓶颈,但大多数驱动程序不需要那么高的速度 - 所有计算机都在等待以相同的速度。

这就是为什么有各种项目允许编写在内核之外运行的驱动程序,即使这会导致速度变慢; 当你能做到这一点时,你可以使用任何你想要的语言; 然后您将需要您使用的硬件控制库的 Java 绑定 - 如果您用 C 编写驱动程序,您仍然会有一个带有 C 绑定的库。

对于内核模式下的驱动程序,有两个问题我还没有看到提到:

  • 垃圾收集,这是一个严格的要求。 您需要编写一个内核内垃圾收集器; 有些 GC 算法依赖于虚拟内存,您无法使用它们。 此外,您可能需要扫描整个操作系统内存才能找到 GC 的根。 最后,我只相信保证(软)实时GC的算法,这会使开销更大。
    阅读了有关 Linux 上的 Java 设备驱动程序的论文,他们只是放弃了,并要求程序员手动释放内存。 他们试图争辩说这不会损害安全性,但我认为他们的论点没有说服力 - 甚至不清楚他们是否理解安全语言需要垃圾收集。

  • 反射和类加载。 完整的 Java 实现,即使在运行本机代码时,也需要能够加载新代码。 这是一个您可以避免的库,但如果您在内核中有一个解释器或 JIT 编译器(并且没有真正的原因使其在技术上不可能)。

  • 性能。 关于 Linux 上的 JVM 的论文非常糟糕,而且它们的性能数据也没有说服力 - 事实上,他们测试了 USB 1.1 网络驱动程序,然后表明性能并没有那么糟糕! 然而,只要付出足够的努力,肯定可以做得更好。

最后两件事:

  • 我想提一下 Singularity,它是一个用 C# 变体编写的完整操作系统,只有一个用本机语言编写的硬件抽象层。
  • 关于 picoJava,除非您的系统确实是内存受限的系统(例如智能卡),否则使用它是一个坏主意。 Cliff Click 已经解释了原因:编写好的 JIT 可以提供更好的性能,现在甚至智能手机也可以支持这一点。

For the motivation, please remember that there is plenty of fast languages which are better than C for programming; they might not be as fast as C, but they are safe languages: if you make a mistake you don't get undefined behavior. And "undefined behavior" includes executing arbitrary code supplied by some attacker which formats your HD.
Many functional languages are usually compiled to native code.

Device drivers contain the most bugs in an OS kernel - I know that for Linux (Linus Torvalds and others keep saying so) and I heard that for Windows. While for a disk or Ethernet driver you need top-notch performance, and while in Linux drivers today are the bottleneck for 10G Ethernet or SSD disks, most drivers don't need that much speed - all computers wait at the same speed.

That's why there are various projects to allow writing drivers which run outside of the kernel, even if that causes a slowdown; when you can do that, you can use whatever language you want; you will just then need Java bindings for the hardware control library you use - if you were writing the driver in C, you would still have a library with C bindings.

For drivers in kernel mode proper, there are two problems that I've not yet seen mentioned:

  • Garbage Collection, and that's a tough requirement. You need to write an in-kernel Garbage Collector; some GC algorithms rely on Virtual Memory, and you cannot use them. Moreover, you probably need to scan the whole OS memory to find roots for the GC. Finally, I would only trust an algorithm guaranteeing (soft) real-time GC, which would make the overhead even bigger.
    Reading the paper which was mentioned about Java Device Drivers on top of Linux, they just give up, and require programmers to manually free memory. They try to argue that this will not compromise safety, but I don't think their argument is convincing - it's not even clear whether they understand that Garbage Collection is needed for a safe language.

  • Reflection and class loading. A full Java implementation, even when running native code, needs to be able to load new code. This is a library you can avoid, but if you have an interpreter or JIT compiler in kernel (and there's no real reason that makes it technically impossible).

  • Performance. The paper about a JVM on Linux is very bad, and their performance numbers are not convincing - indeed, they test a USB 1.1 network driver, and then show that performance is not so bad! However, given enough effort something better can surely be done.

Two last things:

  • I'd like to mention Singularity, which is a complete OS written in a C# variant, with just a Hardware Abstraction Layer in a native language.
  • About picoJava, it's a bad idea to use it unless your system is a really memory constrained one, like a smart card. Cliff Click already explained why: it gives better performance to write a good JIT, and nowadays even smartphones can support that.
滥情稳全场 2024-07-22 23:49:18

您是否听说过对 JDKK 的引用?

如果没有本机代码,100% 用 Ja​​va 编写设备驱动程序是不可能的,以提供 (1) 特定于操作系统的驱动程序入口点和约定与 (2) JVM 实例之间的交互。 JVM 实例可以“进程内”启动(“进程内”可能具有不同的含义,具体取决于操作系统以及驱动程序是内核模式还是用户模式驱动程序),或者作为单独的用户态启动薄的本机驱动程序适配层可以与该进程进行通信,并且所述驱动程序适配层可以将实际的用户态工作卸载到该进程上。

Have you perhaps heard a reference to the JDDK?

Writing a device driver 100% in Java is not possible without native code to provide the interaction between (1) the OS-specific driver entry points and conventions, and (2) the JVM instance. The JVM instance could be started "in-process" (and "in-process" may have different meanings depending on the OS and on whether the driver is a kernel-mode or user-mode driver), or as a separate user-land process with which a thin, native driver adaptation layer can communicate and onto which the said driver adaptation layer can offload actual user-land work.

抱着落日 2024-07-22 23:49:18

可以将java代码编译为硬件本机(即不是JVM字节码)指令。 例如,请参见 GCJ。 有了这个,您就比以前更接近能够编译设备驱动程序了。

不过我不知道它有多实用。

It is possible to compile java code to hardware native (i.e. not JVM bytecode) instructions. See for instance GCJ. With this in hand, you're a lot closer to being able to compile device drivers than you were before.

I don't know how practical it is, though.

虫児飞 2024-07-22 23:49:18

可能吗?

可以,但仅限于特殊情况。 因为你可以用Java和C#编写一个操作系统,然后,应该能够为其编写设备驱动程序。 这些驱动程序和操作系统的内存占用将是巨大的。

可能?

不太可能。 至少在 Windows 或 MacOS 甚至 Linux 的世界里不会……至少在短期内不会。 因为像 C# 和 Java 这样的语言依赖于 CLR 和 JVM。 这些语言的工作方式意味着它们无法有效地加载到ring0中。

此外,如果在设备驱动程序中使用托管语言,性能损失将会相当大。

Possible?

Yes but only in special circumstances. Because you can write an operating system in Java and C#, and then, should be able to write device drivers for it. The memory hit to these drivers and operating systems would be substantial.

Probable?

Not likely. Atleast not in the world of Windows or MacOS or even Linux... At least not anytime soon. Because languages like C# and Java depend on the CLR and JVM. The way these languages work means that they cannot effectively be loaded into ring0.

Also, the performance hit would be rather large if managed languages were employed in device drivers.

我为君王 2024-07-22 23:49:18

设备驱动程序必须用可以在内核中执行的语言编写,可以编译到内核中,也可以在运行时作为模块加载。 这通常会妨碍用 Java 编写设备驱动程序,但我想理论上您可以在设备驱动程序中实现 JVM 并让它执行 Java 代码。 并不是任何一个理智的人都愿意这样做。

在 Linux 上,有几种文件系统的用户态(即非内核)实现,它们使用称为(熔丝)的通用抽象层,它允许用户态程序实现通常在内核中完成的事情。

Device drivers have to be written in a language which can execute in the kernel, either compiled into it, or loaded as a module at runtime. This usually precludes writing device drivers in Java, but I suppose you theoretically could implement a JVM inside a device driver and let it execute Java code. Not that any sane person would want to do that.

On Linux there are several user-land (i.e. non-kernel) implementations of filesystems which uses a common abstraction layer called (fuse) which allows user-land programs to implement things which are typically done in the kernel.

疧_╮線 2024-07-22 23:49:18

Windows Driver Foundation (WDF) 是一个 Microsoft API,它允许 用户 和要编写的内核 模式设备驱动程序。 今天正在完成此操作,现在它与 w2k 及更高版本兼容(以前不将 w2k 作为受支持的目标)。 没有理由不能进行 JNI 调用来在 JRE 中完成某些工作。 。 。 (假设 JNI 仍然是从 C/C++ 调用 Java 的方式……我在该领域的知识已经过时了)。 这可能是一种有趣的方式,可以让高级算法直接咀嚼来自 USB 管道的数据以达到这种效果。 。 。 很酷的东西!

The Windows Driver Foundation (WDF) is a Microsoft API that does allow both User and Kernel mode device drivers to be written. This is being done today, and it is now compatible with w2k and later (used to not have w2k as a supported target). There is no reason that JNI calls can't be made to do some work in the JRE . . . ( assuming that JNI is still the way to call Java from C/C++ . . . my knowledge is dated in that arena). This could be an interesting way to have high level algorithms directly munch on data from a USB pipe for something to that effect . . . cool stuff!

将军与妓 2024-07-22 23:49:18

PCIe 用户空间设备驱动程序可以用纯 Java 编写。 有关基于内存的直接硬件的详细信息,请参阅 JVerbs访问,在 OFED 的背景下。 这是一种可用于创建非常高性能的系统的技术。

您可以检查 PCI 总线以确定给定设备的内存区域、它具有哪些端口等。内存区域可以映射到 JVM 的进程中。

当然,您有责任自己实施一切

我没说容易。 我说有可能。 ;)

另请参阅用户空间中的设备驱动程序,讨论使用UIO框架构建用户空间驱动程序。

PCIe user space device drivers can be written in Pure Java. See JVerbs for details about memory-based direct hardware access, in the context of OFED. This is a technique that can be used to create very high performance systems.

You can examine the PCI bus to determine the memory regions for a given device, what ports it has, etc. The memory regions can be mapped into the JVM's process.

Of course, you're responsible for implementing everything yourself.

I didn't say easy. I said possible. ;)

See also Device Drivers in User Space, which discusses using the UIO framework to build a user space driver.

杀手六號 2024-07-22 23:49:18

首先,请注意,我不是设备驱动程序方面的专家(尽管我当时自己写了一些驱动程序),更不用说 Java 方面的专家了。

让我们暂时搁置以下事实:用高级语言编写设备驱动程序不是一个好主意(出于性能和可能的许多其他原因),并回答您的问题。

可以用几乎任何语言编写设备驱动程序,至少在理论上是这样。

但是,大多数设备驱动程序需要执行大量低级操作,例如处理中断以及使用操作系统 API 和系统调用与操作系统进行通信,我相信您在 Java 中无法做到这一点。

但是,如果您的设备使用串行端口或 USB 进行通信,并且操作系统不一定需要知道该设备(只有您的应用程序会访问该设备*),那么您可以在任何位置编写驱动程序提供访问设备的必要方法的语言。

例如,您可能无法用 Java 编写 SCSI 卡驱动程序,但您可以为专有控制设备、USB 熔岩灯、许可证加密狗等编写驱动程序。

* 当然,这里明显的问题是,这算不算作为司机?

First of all, note that I'm not an expert on device drivers (though I wrote a few myself back in the day), much less an expert on Java.

Let's leave the fact that writing device drivers in a high-level language is not a good idea (for performance and possibly many other reasons) aside for a moment, and answer your question.

You can write device drivers in almost any language, at least in theory.

However, most device drivers need to do plenty of low-level stuff like handling interrupts and communicating with the OS using the OS APIs and system calls, which I believe you can't do in Java.

But, if your device communicates using, say, a serial port or USB, and if the OS doesn't necessarily need to be aware of the device (only your application will access the device*), then you can write the driver in any language that provides the necessary means to access the device.

So for example you probably can't write a SCSI card driver in Java, but you can write a driver for a proprietary control device, USB lava lamp, license dongle, etc.

* The obvious question here is, of course, does that count as a driver?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文