如果您对Linux兼容模式是如何工作的感到好奇,这节正是您所需要的。 下面的绝大部分内容是由
Terry Lambert<tlambert@primenet.com>
(Message ID:
<199906020108.SAA07001@usr09.primenet.com>
)发表在邮件列表FreeBSD 闲聊邮件列表上的内容组成的。
FreeBSD有一个“可执行类加载器”。它主要是嵌入了execve(2)系统调用。
碰巧的是FreeBSD有一个引导器(loader)的列表,而不是一个简单的返回一个
符号 #!
的引导器!
从历史上来讲,只有UNIX®平台的引导器会检查魔术(magic)数 (通常是文件的前4个或8个字节)是否是二进制的, 如果是,就调用二进制引导程序。
如果它不是二进制类型的execve(2)调用就会返回一个错误,shell就试图用shell命令执行它。
缺省是使用“当前设定的shell”。
随后,进行了一些hack, sh(1)开始检查前两个字符,如果它们是:\n
,
那它就调用csh(1)(我们相信是SCO最先做这个hack的)。
FreeBSD现在所做的是用一个普通的#!
引导器仔细检查引导器的列表,
然后由解释程序一个接一个地解释,返回给/bin/sh
。
为了支持Linux ABI,FreeBSD就把魔术数看作为一个二进制ELF程序。( 这样一来,它就使得在FreeBSD, Solaris™,Linux和其他任何操作系统之间只要使用ELF格式就都可以顺利运行)。
ELF引导器会寻找一个专门的标记, 它是在ELF映像中的一个注释部分,但在SVR4/Solaris™的ELF中没有。
为了执行Linux程序,它们必须被打上Linux
类型的标记;
使用brandelf(1):
做完之后,ELF引导器就会看到文件上的Linux
的标记。
当ELF引导器看到Linux
的标记,
引导器就会在proc
结构中替换一个指示器。
所有的系统调用就会通过这个指示器来索引(在一个传统的 UNIX®系统中,
这就是sysent[]
结构队列,包含系统调用)。
此外,为了解决由于信号杂乱所造成的陷阱向量的问题,会造成线程的剧增,
需要切断其他(或较小的)由Linux内核模块产生的修正。
Linux系统调用向量包含一个sysent[]
记录的列表,
它的地址位于内核模块之中。
当一个系统调用被Linux程序调用时,有缺陷的代码会把系统调用功能的指示器从proc
结构中解除,
然后获得Linux,而不是FreeBSD,系统调用入口点。
另外,Linux模式动态地reroots查找;这和启动文件系统的union
选项是等效的(即时不是unionfs
文件系统)。
首先会试图在/compat/linux/original-path
目录查找文件,如果失败了,就会在/original-path
目录下查找。这使得需要其它程序的程序可以运行(例如,Linux工具链都可以在Linux ABI的支持下工作)。
也就是说Linux程序可以加载和执行FreeBSD程序,如果当前没有相应的Linux程序,
那您可以在/compat/linux
目录树中放置一个uname(1),使 Linux 程序不易察觉它们并没有运行在 Linux 系统上。
在FreeBSD内核中有一个Linux内核;由内核提供的能够提供所有服务的各种潜在功能
在FreeBSD系统调用表记录和Linux系统调用表记录之间是一样的:
文件系统操作,虚拟内存操作,信号发送,System V IPC,…等等。
唯一的不同是FreeBSD会得到FreeBSD的胶合功能,
而Linux程序会得到Linux的胶合功能
(大部分老的操作系统只有它们自己的胶合函数,
函数地址在静态全局变量sysent[]
结构数据里面,
而不是动态的初始化到进程的proc
结构)。
哪一个是FreeBSD自己的ABI呢?这无关紧要。基本上, 唯一的不同是FreeBSD的胶合功能是被静态连接到内核, 而Linux的胶合功能可能是被静态连接到内核, 也可能它们通过一个内核模块来访问。
有一个真正的模拟器吗?没有,它只不过是一个ABI执行机制,不是一个模拟器。
为什么有时它被叫做“Linux模拟器”? 只是为了更容易地卖出FreeBSD罢了! 实际上,历史上从来没有描述这样一种执行机制的名字,FreeBSD并不是真正地运行Linux程序,如果您不编译进代码, 或加载一个模块。 就需要有一个名字来描述这样一种加载功能--因此就想出了“Linux模拟器”这样一个名字。
本文档和其它文档可从这里下载: ftp://ftp.FreeBSD.org/pub/FreeBSD/doc/.
如果对于FreeBSD有问题,请先阅读
文档,如不能解决再联系
<questions@FreeBSD.org>.
关于本文档的问题请发信联系
<doc@FreeBSD.org>.