Wine 开发系列之 —— 入门

引言

  • 这篇文章最早写于 2019 年的公司内网,后来经过多方辗转,开始在网络上流传。经过 5 年多的发展,现在的 Wine 和当时相比略有不同,本着负责任的原则,本文在原有基础上进行更新。为了与原始文章作对比,更新的内容添加在文章末尾。

  • 说起 Wine,稍微资深一点的 Linux 用户应该都听过,但是真要说起 Wine 到底是怎么回事,可能大多数人不见得说得清。这篇文章会简单的介绍 Wine 的工作原理,以及如何开始 Wine 的开发。所以如果您属于以下三类读者之一:

    • 想参与 Wine 开发,但是不知如何开始的。
    • 不认同 Wine 技术,仅仅想大致了解 Wine 是如何工作的。
    • 只是想能够愉快的用上最新版本 Wine 的。

    希望在看完本文后,能够有一些收获。

一、Wine 是什么

Wine 是 “Wine Is Not an Emulator” 的递归缩写,如同 “GNU” 一样(GNU’s Not Unix),字面意思就是 Wine 不是一个模拟器。这里的模拟器主要是指 Wine 并不是一个虚拟机,而是一个 Windows API 实现兼容层。这么说可能不太好理解,大家可以把 Windows 应用程序类比成 Android 应用程序,而 Wine 的角色就和 Android 很像了,将操作系统提供的各种功能封装成 API,并让应用程序在隔离的环境内运行。至于 API 长成啥样,隔离的力度如何,这些都是实现相关的,和本质并不冲突。另一方面,Wine 其实又是一个模拟器,不过模拟的对象不是硬件 CPU,而是 Windows 的行为。

二、Wine 原理介绍

  • 本节内容较为枯燥,需要对操作系统有一定的了解。如果只是想编译、运行,对原理不敢兴趣的同学,可以跳过,不影响后面的阅读。
  • Wine 的目的是运行 Windows 上的可执行程序(PE,portable executable)。我们知道,可执行程序的本质其实就是按照某一规则排列的机器码,而机器码是指令集相关的。得益于常见的 PC 机一般是 x86/x64 的,因此 Windows 应用程序从指令集的角度看,是完全可以在 x86/x64 的 Linux 机器上直接运行,而不需要硬件层模拟的。
  • 但是为了能够直接加载运行 PE 文件,需要满足一些 ABI 兼容。最基本的,Windows PE 程序,会假定自己被加载到地址 0x400000 处,因此 Wine 实现自己的 loader 时,需要保证将 PE 镜像加载到同样的位置。对于静态链接的程序,需要做的事情可能不是太多,但是对于动态链接的程序,Wine 需要模仿 Windows loader 的行为,加载依赖的库,并进行相应的重定位工作。
  • 为了最大程序上减少对二进制层面的依赖,Wine 决定实现至少GDI32,KERNEL32,USER32三个动态库,因为其他库都是建立在这三个库的基础之上的。所以理论上来说,除此之外的其他动态库是可以直接使用 Windows 上面现有的库的,但由于各种原因,Wine 还是倾向于尽量实现所有的 API。我们把 Wine 自己实现的 API 库称作 builtin,把 Windows 上现成的库称作 native。当 Wine 在加载 builtin 动态库的同时,还会在内存中建立 PE header,用来模仿 Windows 上的内存布局。更加详细的实现,有机会可以写一篇 Wine loader 相关的文章来介绍 Wine 本身、PE 程序和动态库是如何被加载的。
  • 除开 loader 的功能外,Wine 还需要解决进程间通信(IPC)的问题。Wine 的实现方式是将所有跨进程的对象和机制,
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值