作者:燕过无痕GY_274 | 来源:互联网 | 2017-06-25 17:36
文章标题:Linux兼容内核的三个重要源泉。Linux是中国IT实验室的一个技术频道。包含桌面应用,Linux系统管理,内核研究,嵌入式系统和开源等一些基本分类
我们要开发、构建的Linux兼容内核并非无源之水,也不需要从零开始“重新发明轮子”。正如牛顿所说要“站在巨人肩膀上”一样,我们也应该充分利用别人已经取得的成就、特别是开源社区已经取得的成就。
除Linux本身以外,兼容内核主要的源泉有三个,那就是Wine、NdisWrapper、以及ReactOS。三者都是在Sourceforge立项的开源项目,源代码可从www.sourceforge.net下载。
下面对三个源泉分别作一简单的介绍。
Wine
按Wine项目自己的说法,Wine是“Wine Is Not an Emulator”的缩写。这使人不免想起GNU的“Gnu is Not Unix”。许多人对此可能一笑了之,觉得这是文字游戏或者幽默。可是笔者却觉得这背后其实自有深意。GNU说它不是Unix,意思是说虽然它基本上就是Unix,或者非常像Unix,可是你不能按Unix的各种标准来要求它,有些地方它与真正的Unix是点差别的。这是一种“有言在先”式的声明。而Wine为什么说它不是仿真器呢?这反映了Wine的设计者生怕别人误以为Wine是个仿真器。这主要是因为“仿真器”这个词容易使人误解,以为是对CPU机器指令的仿真,那是效率非常低的。所以这实际上是在申辩,说Wine的效率不低。当然,Wine的效率比普通意义上的仿真确实要高得多。
那么Wine到底是什么呢?
? 对于Windows应用软件而言,Wine为其提供对Windows运行环境的仿真,所以Wine也可以理解为“WIN Emulator”。这也正是Windows应用软件能够在Linux上运行的条件与原因。不过这种仿真并不是对CPU指令的仿真,而是对Win32 API函数调用的仿真。
?对于Linux及其内核而言,Wine是内核与Windows应用软件之间的一个中间层。它一方面为Windows应用软件提供各种动态连接库(DLL),使应用软件通过Win32 API进行的库函数调用得以落实,一方面将应用软件和动态连接库原本对Windows内核所作的系统调用翻译成对Linux内核的系统调用,把它们转嫁到Linux内核上来。
?对于许多作为Windows操作系统组成部分的动态连接库、服务/守护程序、工具程序而言,Wine是这些软件在Linux上的移植、实际上是仿制。在“关于Linux兼容内核的知识产权问题”一文的第二部分中,笔者把Windows上的软件分成五类,这些软件都属于第五类,即由微软开发,又理应属于操作系统、跟Windows相捆绑的那部分软件。
Wine完全不触及Linux内核,所有的操作都是在内核外面进行。有些操作本来应该在内核中实现,但是因为不触及内核,就只好设法在内核外面、即用户空间中设法补偿。但是,在内核外面用Linux系统调用来实现Windows系统调用,就好像要用一种高级语言来实现另一种高级语言一样(比方说,用Cobol来实现Fortran),往往会导致相当笨拙的实现,有些甚至根本就实现不了。这是因为,Linux或者Windows的每一个特定的系统调用就好像高级语言的一种语句,我们固然可以把它看成是个黑盒子,但是要让两个这样的黑盒子在输入参数和条件,计算结果和副作用等等各方面都完全一样是很困难的。诚然,Linux的系统调用是很丰富、很灵活、“表现力”很强的,有点像是C语言,这给通过Linux系统调用实现Windows系统调用提供了一个良好的基础。但是,即便如此,也还存在不少的困难。下面我们通过一个例子加以说明。
Windows系统在打开文件等等操作中返回一个Handle(翻译成“句柄”,笔者觉得不是很好,但又想不出更好的词),语义上这是用于一个指针数组的下标。每个进程都有这么一个数组,所以Handle原则上不是全局的、而是局限于具体进程的。也许读者马上就会联想到打开文件号,二者似乎完全相同,因而应该可以用Linux的打开文件号来实现Windows的Handle。不过Windows的Handle并不是只用于文件,而是用于所有各种“对象(Object)”,这且不说,这里要说的是个更大的麻烦。在创建子进程时,Windows内核允许有选择地“遗传”Handle。当然,Linux内核在创建子进程时也可以遗传打开文件号,这似乎又是一样的。可是麻烦来了。在Windows系统中,打开一个文件时就通过参数规定,这个打开了的文件以后是否可以遗传;在创建子进程时,则又通过参数规定,是否要遗传那些事先规定可以遗传的已打开文件、即Handle(见“Advanced Windows”,p17)。应该说,这是个不错的主意。而Linux呢?遗传的是1、2、3三个打开文件号。对内核有所了解的朋友不难想到,要在Linux内核中作一些扩充,以实现Windows的这种遗传机制,是不难的,甚至是很容易的。可是,如果要在内核外面实现呢?读者不妨动动脑筋。如果有很简洁的方法,不妨通知一下笔者,让笔者有个表达钦佩和祝贺的机会。
至于设备驱动,既然不触及内核,自然就不可能解决设备驱动的问题。当然,对于Linux上已经有了相应设备驱动程序的那些外设(例如硬盘),可以把Windows应用程序对这些外设的操作“重定向”到相应的Linux设备上来。可是问题在于那些在Windows上有驱动模块(.sys文件),而Linux上还没有相应驱动模块的那些设备,对这些设备怎么办呢?
[1] [2] [3] [4] 下一页