它是如何工作的(Gnu/Linux + X11)

它是如何工作的(Gnu/Linux + X11)

我基本上是想弄清楚如何从头开始制作一个 GUI,除了 Linux 内核和 C 语言编程之外什么都没有。

我不想从头开始创建 GUI 桌面环境,但我想创建一些桌面应用程序,并且在我的知识搜索中,我能够找到的所有信息都是关于 GUI API 和工具包的。我想知道,至少对于我对如何制作 Linux GUI 的基础知识的理解,如何在不使用任何 API 或工具包的情况下制作 GUI 环境或 GUI 应用程序。

我想知道例如:

  1. 现有的 API 和工具包通过对内核的系统调用来工作(内核在最低级别负责以像素或其他方式构建 GUI 图像)

  2. 这些工具包执行的系统调用只是将信息传递给屏幕驱动程序(是否有所有屏幕驱动程序都遵守的发送此信息的标准格式,或者 GUI API 是否需要能够根据特定的屏幕/驱动程序以多种格式输出此信息? )并且如果这大致正确,原始 Linux 内核通常是否仅以 8 位字符的形式将信息发送到屏幕?

我只是想了解 Linux 内核和我在屏幕上看到的内容之间发生的情况(如果您知道的话,通过软件和硬件的控制/信息流,信息采用什么格式等)。我非常感谢详细的解释,我知道这可能很难解释得足够详细,但我认为这样的解释对于其他好奇和学习的人来说将是一个很好的资源。就上下文而言,我是一名三年级的计算机科学学生,最近开始在我的系统编程课程中使用 C 进行编程,并且我对 Linux 和编程有中等程度的了解(或者我会这样描述)。再次感谢所有帮助我的人!

答案1

它是如何工作的(Gnu/Linux + X11)

概述

它看起来像这样(未按比例绘制)

┌───────────────────────────────────────────────┐
│                       User                    │
│     ┌─────────────────────────────────────────┤
│     │             Application                 │
│     │            ┌──────────┬─────┬─────┬─────┤
│     │            │      ... │ SDL │ GTK │ QT  │
│     │            ├──────────┴─────┴─────┴─────┤
│     │            │            xLib            │
│     │            ├────────────────────────────┤
├─────┴───┬────────┴──┐         X11             │
│   Gnu   │ Libraries │        Server           │
│   Tools │           │                         │
├─────────┘           │                         │ 
├─────────────────────┤                         │
│   Linux (kernel)    │                         │
├─────────────────────┴─────────────────────────┤
│                    Hardware                   │
└───────────────────────────────────────────────┘

从图中我们可以看出,X11主要与硬件进行对话。然而,它需要通过内核进行通信,才能最初访问该硬件。

我对细节有点模糊(我认为自从我上次研究以来它发生了变化)。有一个设备/dev/mem可以访问整个内存(我认为是物理内存),因为大多数图形硬件都是内存映射的,所以可以使用该文件(看到一切都是文件)来访问它。 X11会打开文件(内核使用文件权限来查看是否可以执行此操作),然后X11使用mmap将文件映射到虚拟内存(使其看起来像内存),现在内存看起来像内存。之后mmap,内核不再参与。

X11 需要了解各种图形硬件,因为它通过内存直接访问它。

(这可能会发生变化,特别是安全模型,可能不再允许访问全部的记忆。)

Linux

最底层是Linux(内核):系统的一小部分。它提供对硬件的访问并实现安全性。

格努

然后是 Gnu(库;bash;工具:ls 等;C 编译器等)。大多数操作系统。

X11 服务器 (egxorg)

然后是 X11(或者 Wayland,或者...),基本 GUI 子系统。它运行在用户态(内核之外):它只是另一个进程,具有一些特权。除了提供对硬件的访问之外,内核不参与其中。并提供进程间通信,以便其他进程可以与X11服务器通信。

X11库

一个简单的抽象,允许您为 X11 编写代码。

图形用户界面库

接下来是 qt、gtk、sdl 等库 — 它们使 X11 的使用变得更加容易,并且可以在其他系统(例如 wayland、Microsoft 的 Windows 或 MacOS)上工作。

应用领域

应用程序位于库之上。

一些用于编程的低级入口点

扩展库

使用 xlib 是了解 X11 的好方法。不过,请先阅读一些有关 X11 的内容。

雪迪龙

SDL 将为您提供低级访问,直接访问位平面,以便您直接绘制。

走低

如果你想走得更低,那么我不确定当前有什么好的选择,但这里有一些想法。

链接

X11

https://en.wikipedia.org/wiki/X_Window_System

现代方式

写这篇文章引起了我的兴趣,所以我研究了现代的快速方法是什么。以下是一些链接:

https://blogs.igalia.com/itoral/2014/07/29/a-brief-introduction-to-the-linux-graphics-stack/

答案2

ctrl-alt-delor 的答案让您对总体架构有一个很好的概述。对于更实际的方法,我给你一个关于“除了 Linux 内核和 C 编程”的答案。

我喜欢时不时地直接写入帧缓冲区。帧缓冲设备驱动程序将为您完成所有繁琐的接近硬件的“这最终将如何出现在屏幕上”的事情。您可以使用 root shell 立即执行此操作:

echo -n -e '\x00\x00\xFF' > /dev/fb0

它将我的 32 位帧缓冲区上的第一个(左上角)像素设置为红色:

左上角像素为红色的帧缓冲区的屏幕截图

您完全可以通过打开 /dev/fb0 并写入字节来从 C 内部执行此操作。内存映射可以成为你的朋友。这仅在没有 X 服务器或虚拟控制台的情况下有效。按 Ctrl+Alt+F1 即可访问它。

PS:可视化随机数据(例如鼠标移动)也很有趣:

cat /dev/input/mouse0 > /dev/fb0

PPS:另请注意,几乎所有现实世界的桌面应用程序都希望更直接地访问硬件,以实现一些奇特的功能,例如绘图、3D 和视频渲染的硬件加速。简单的帧缓冲设备无法很好地完成这些工作。

答案3

我强烈建议从恩诅咒

与更复杂的图形系统不同,它纯粹基于文本,因此无需陷入屏幕驱动程序和图形库的细节。然而,将窗口放在屏幕上、在窗口之间移动焦点等基本原则仍然适用。您仍然可以在单字符块和 ASCII 艺术级别上进行一些绘图。

当然,您仍然在库之上构建它,但它是一个您可以轻松理解的库。更重要的是,它是一个可以免费获取源代码的库,并且有很好的文档记录,如果您想阅读它,也不会太费解。如果您愿意,您甚至可以自己修改它。或者您可以查看其中的所有库函数以找到所需的 API,然后根据该设计自己从头开始编写。

答案4

SunOS 5 有 DGA 库,它提供对不同 cg[3,6,14]、TCX 或 LEO 图形适配器的设备独立访问,这也是在 SPARC 机器上支持 DOOM 的东西。

cg6 是 8 位,通常在 X11 中用作伪彩色视觉效果,但它也可以提供 8 位真彩色,而 tcx 和 leo 是 24 位加速 3D 显示帧缓冲区(伪彩色 = videoram 中的一个字节是一个大的索引)表格给出了 3x8 RGB 值,表格的内容可以轻松更改。)cg3 具有大致相同的能力,但没有加速(cg6 设计师随后成立了另一家公司...... nVidia。)

后来的设备,如基于 ATI Rage Pro 芯片组的 PGX,不能同时支持真彩色和伪彩色,而早期的设备却可以。这迫使用户在为伪彩色模型编写的旧应用程序(或如果可能的话升级软件)和仅运行面向真彩色的应用程序之间进行选择。

伪彩色的存在主要是因为视频在 80 年代中期直到 1992 年左右都非常昂贵。支持可用工作站类型分辨率的彩色显示器也相当昂贵(1984 年的 Sun 2 黑白分辨率为 1152x864,而 1989 年左右的 MG1 的分辨率为 1600x1280,但黑白。)

我写这篇文章是因为我想展示 X11 必须支持的不同要求。

相关内容