为我自己的操作系统创建SDK/neneneba API(用于应用程序开发)



我创建了一个简单的操作系统。我想为它创建外部应用程序,应该已经编译为精灵可执行文件,可以在我的操作系统上运行,我不想创建API或SDK来成功编译应用程序。如何使应用程序能够使用操作系统内置的类和函数而不包括操作系统的头文件。

类似于Windows或其他应用程序。

我需要像.dll这样的动态库吗(在windows中)?那我该怎么做呢?

如果你所说的应用程序是指设备驱动程序,那么它相当复杂,因为你需要在启动时将它们与内核链接。例如,在Linux上,大多数驱动程序都是作为放置在特定目录中的模块编写的。这些模块是特殊的elf文件,在启动时与内核链接。内核知道它的不同函数在哪里,所以它在启动时使用文件中的重定位条目将特殊elf文件中的函数调用与内核链接起来。

对于应用程序来说,它更简单,但要使其与在Linux上编译的elf文件兼容,您需要遵循System V ABI,该ABI说明了内核的系统调用接口。要么就是这样,要么你必须为你的操作系统编写自己的编译器。

我自己正在编写一个小内核。我会给你一些我的设计选择。通过这种方式,我可以告诉你我计划如何做事,同时提供有关它如何工作的信息。

编译C++

我的计划是为内核编写一个全新的系统调用接口。因此,我必须编写一个完整的C++编译器才能运行C++应用程序。通常情况下,操作系统提供的库包含C++函数的定义。因此,C++头部中的所有函数(可以从g++或其他地方获得)都与操作系统提供的C++库相链接。这些函数定义特定于一个操作系统或一组特定的操作系统,这些操作系统遵循某些约定,如System V。由于我不打算遵循任何约定,我必须重新发明轮子,并制作一个新的编译器来处理我的操作系统。

C++应用程序还链接了几个启动应用程序所必需的文件。crt0.s程序集文件提供了_start符号。这个crt0.s文件包含一些内容,其中包括对C++应用程序的全局构造函数的调用。您可以阅读以下内容了解更多信息:https://wiki.osdev.org/Creating_a_C_Library.

必须调用全局构造函数,否则将永远不会构造全局对象。全局对象构造不在函数的路径中。因此,它永远不会被执行。在我的内核中,我没有添加任何启动文件,因为我将内核的入口点指定为main,并且我没有全局对象。因此,我决定不需要它们。我确实计划通过实现这些启动文件,让这些文件在用户模式下可用。

用户输入

每个操作系统都需要一种将用户输入传递给应用程序的方法。大多数时候,它是特定于操作系统的,因为C++的用户输入功能还不够好。例如,在我的内核中,我计划使用类似于windows的东西。Windows上的每个应用程序都在循环调用一些函数。这些函数将轮询消息队列中的消息,然后调用程序员提供的过程,并将消息作为参数。

基本上,当操作系统检测到输入时,它会在应用程序的消息队列中放置一条消息,该消息队列当前具有声明输入内容的焦点。然后,此应用程序正在轮询此队列中的消息。当它找到一个时,它将使用消息作为参数来调用过程。然后,该过程会根据消息在应用程序中执行某些操作。

帧缓冲区

对于绘图来说,这是相当复杂的,尤其是如果你想支持图形卡。我计划实现的方式是只支持UEFI提供的帧缓冲区模式。基本上,我的操作系统将只使用GOP提供的帧缓冲区。

我的操作系统将提供一个以操作系统名称命名的库,该库将具有DrawFramebuffer()函数。用户模式应用程序在用户模式下只需有一个大缓冲区,其中包含每个像素的RGB颜色,然后调用DrawFramebuffer()函数,该函数在内核中以用户模式缓冲区的地址和大小为参数进行系统调用。它还将提供GetFramebufferSize()函数来获取帧缓冲区的大小。因此,内核将根据用户应用程序可以访问屏幕的哪个部分来决定要绘制用户模式缓冲区的哪个部分,以及不绘制哪个部分

在这种情况下,它相当简单,但要支持更多的显卡,它就更复杂了。你需要对显卡驱动程序的支持,可能还需要某种将桌面写入屏幕的方法。最后,如果你不知道驱动程序是如何工作的,你应该如何将桌面绘制到屏幕上?这就是为什么我计划在我的最小内核中只支持帧缓冲区。

为了回答您的问题,一切都是特定于操作系统的,除非您提供一种传统的方式来调用内核(比如遵循System V ABI)。此外,用户输入和绘图始终是特定于操作系统的。例如,在Linux上,它与X服务器的工作方式类似于windows。您为X服务器创建一个客户端,并轮询服务器以确定是否有消息(如键盘输入)用于您的应用程序。

最新更新