【问题标题】:System libraries in Linux vs. WindowsLinux 与 Windows 中的系统库
【发布时间】:2020-04-27 19:43:46
【问题描述】:

我的背景是 Windows,我是 Linux 菜鸟。仍在尝试围绕一些基本概念,特别是系统库:

  1. Windows 具有包装系统调用的 ntdll.dll 和 CRT dll C 语法与 ntdll OS 公开的接口之间的哪个接口 服务。
    (为简化起见,我忽略了中间层 user32、kernel32、kernalbase 等。我也意识到 CRT 是几个 dll,这不是重点)。
  2. 似乎 Unix/Linux 几乎只有 libc,它包装了系统调用直接从您的应用程序代码调用。

这是正确的类比吗? (ntdll + CRT) libc ?

我意识到 C 和 Unix 是一起发展的,但我仍然感到惊讶。是否可以将 C 接口硬连接到 Unix/Linux 的操作系统中?在 Windows 中,非 C 程序链接到底层操作系统提供的 dll。是否有可能在 Linux 中没有 OS/C 运行时边界?

【问题讨论】:

  • libc 的边界,是的​​。它将open() 之类的函数转换为适当的内核系统调用。
  • Windows C 运行时中的 POSIX 系统函数通常不适合并且过于局限。大多数本机程序直接使用 Windows API,例如CreateFileW -> NtCreateFile。或者他们使用 C++ 标准模板库和 Windows API。将 WINAPI DLL 称为“中间层”严重歪曲了典型用法。
  • 此外,内核中的系统服务表由 Windows 子系统内核驱动程序 win32k.sys 扩展,这些系统调用在用户模式下由 win32u.dll 包装,而不是由基本系统 DLL 包装, ntdll.dll。在 Windows 10 之前,这些 win32k 系统调用是直接在 user32.dll 和 gdi32.dll 中进行的。

标签: linux windows shared-libraries


【解决方案1】:

一般来说,大多数程序都链接到 libc,即使它们是用另一种语言编写的。它提供了 C 标准库接口(如 MSVCRT)、POSIX 功能(相当于 Win32 子系统的某些部分)以及围绕系统调用的包装器。例如,Rust 使用 libc,因为它提供了一个可移植的链接环境。

但是,在 Linux 上,您不必必须链接到 libc。 Go 选择直接进行系统调用,这意味着它可以发布没有运行时依赖的静态二进制文件。这是可能的,因为 Linux 保证了稳定的内核 ABI,但并非所有操作系统都这样做(例如 macOS)。因此,除非您拥有大量资源(例如整个编程语言团队),否则这通常不是明智之举,除非您只使用少数系统调用。

我应该指出,即使是 Windows 在本质上也是与 C 语言相关联的:它使用 C 字符串(被授予,通常是宽 C 字符串)进行系统调用,并且大部分内核都是用 C 编写的。即使你刚开始从头开始一个内核,你仍然需要一个通用的 C 接口,因为几乎每种编程语言都有与 C 交互的方法。

【讨论】:

  • Windows API 使用 C 以 null 结尾的字符串,但 NTAPI(例如内核和原生 NT 应用程序,例如 smss.exe、csrss.exe 等)通常使用计数字符串,例如 @987654321 @。 NT 主要是用 C 和汇编语言编写的。但是,与 Linux 不同的是,NT 没有稳定的系统调用接口(系统调用需要使用 ntdll.dll 和 win32u.dll 中的存根函数),甚至没有稳定的 API,除了为驱动程序开发人员发布的子集。
【解决方案2】:

Linux system calls 记录在 syscalls(2) 中,是用户级程序的基础。 calling conventions 记录在 ABI 规范中。 ELF 可执行格式已记录在案,例如在elf(5).

另请阅读Advanced Linux ProgrammingUnix philosophy

您可以直接在汇编程序中进行系统调用。 Linux Assembly HowTo 解释了这一点。您会更喜欢使用 C 接口,因此libc 更可取。实际上,libc.so 是大多数 Linux 系统的基石。

ldd(1)pmap(1)strace(1)BusyBox一起玩

GCC 编译器启用有用的language extensionsmixing C and assembler 代码。

一些编程语言实现几乎不使用 C 并且可以直接调用系统调用(查看 SBCLGo ...)

Linux 的kernel 和通常的GNU libc(或musl-libc),还有GCC 编译器和binutils 都是free softwareopen source,你可以研究它们源代码

systemdvdso(7) 让事情变得更加棘手。

另见http://linuxfromscratch.org/

图形应用程序正在使用一些display server,通常是XorgWayland。阅读X11。您可能希望使用GTKQt 之类的GUI 工具包对其进行编码。

【讨论】:

  • 感谢所有资源。
猜你喜欢
  • 2017-09-26
  • 2020-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-15
  • 2017-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多