Solaris 和 Linux 都与 Unix 多少有些关系,那么它们应该有很多共同之处吧? 然而事实却并非如此 — 它们之间的不同之处引出了很多“gotcha”问题。就让我们用这篇移植技术指导向您展示如何将 Solaris 应用程序移植到 Linux 平台上吧。 |
移植过程本身非常简单:
- 1. 清理代码和头文件,并删除与体系结构相关的部分和非标准做法。
2. 编译代码,并修正在编译过程中发现的问题。
3. 如果需要,则修正段故障及未对齐的访问。
4. 重新编译代码,如果需要,则重复上面的过程。
移植 Solaris 应用程序至少需要两个平台:一个源平台和一个(或多个)Linux 目标平台。在将应用程序移植到 Linux 目标平台上运行时,您应该考虑很多因素:
- 要移植到哪个 Linux 目标平台?举例来说,有很多种硬件平台都支持 Linux,而字节顺序是以目标系统(如大尾数和小尾数)为基础来决定的。要使用哪个 Linux 分发版和内核版本?(Red Hat、TurboLinux、Caldera、SuSE,还是其它的?)
- Linux 目标平台必须支持所有硬件需求吗?举例来说,是否要依赖第三方网卡?您是否需要支持网络和存储需求?
- Linux 目标平台上是否具备所有所需的第三方包(如类库)、中间件软件、应用程序服务器工具以及应用程序开发工具?目标平台是否支持这些产品的相同(或兼容)版本?
- 在移植到目标平台的过程中是否要作出某些改变?举例来说,应用程序是否要改为使用其它数据库系统?
- 32 位的 Solaris 应用程序是否需要移植到 64 位的 Linux 平台上?
- Solaris 应用程序是否利用亲和处理器集?Solaris 有内核 hook(一种库)和用于将进程分配到特定处理器集的命令行工具。而 Linux 中没有与此相当的东西。
- 是否需要单独的公共源代码库?举例来说,您是否需要支持多个平台?
- 理解应用程序体系结构将使移植过程容易一些。举例来说,它是客户机/服务器模型还是 n 层应用程序组件?您需要决定先移植哪个软件组件。
如果只有硬件和操作系统被改变了,那么您进行的就是真正的移植。您可以使用不同的方法来实现目标。下面的选项描述了移植方法的两个步骤:
- 选项 A:因为 Sparc 平台也支持 Linux,所以被修改的代码可以在移植到 Linux 目标平台上之前在 Sparc 平台上测试和执行。您可以从 Sun 免费获得一套全面的用于 Solaris 操作环境的软件,它们在 Linux 和 Solaris 环境中都能够提供互操作性和通用性。
Sun 的开发工具使创建兼容的源代码更容易,并有助于迁移极为重要的实用程序代码以避免重写,还可以减少安装时间。这个选项可以帮助 Linux 经验有限的开发者将 Solaris 源代码移植到 Linux 目标平台上。下面的 Web 站点提供了 Solaris GNU 工具:
http://www.sun.com/solaris/freeware.html
http://www.sunfreeware.com/
在构建和测试了被移植的代码之后,您就可以遵循下一个选项来将代码移植到 Linux 目标平台了。
- 选项 B:将代码移植到 Linux 目标平台。将测试结果与 Solaris 平台作比较,以验证操作是否正确。修改过的代码必须是与尾数无关的,或者必须使用条件编译以支持小尾数平台。
要开始移植,请仔细检查 Solaris 源代码,并测试这些代码以保证其运行无误。检查过程应该包括完整的编译、重构建以及测试周期。大多数情况下,代码在 Linux 目标系统上会出错,因为最初的源代码树中安装了有错误的软件更新。因此,除非您亲自测试过代码,否则不能轻信在移植时通常会听到的断言(“它在源系统上没有问题!”)。
下面的参考资料也有助于您进行 Linux 移植:
- 由 Malcom Zung 和 Brian Thomas 撰写的 Solaris 移植指导文章,它位于:
ibm.com/developerWorks/library/l-solar/
- Red Hat 的 Solaris-to-Linux Porting Guide 是一份对移植信息的很好的总结,它位于:http://www.redhat.com/devnet/whitepapers/solaris_port/book1.html
- 关于 zSeries 平台的文章 Porting Unix applications to Linux,它位于:
ibm.com/servers/eserver/zseries/library/techpapers/gm130115.html
下面的建议不是将 Solaris 应用程序移植到 Linux 环境的唯一方法。您可以运用自己的移植经验来建立自己的移植方法。
选择移植开发平台
Sparc 平台:这种方法能够让 Solaris 开发者轻松地实现迁移,将 Linux 应用程序移植到其它目标平台上。因为 Sun 提供了公共库和构建环境,从而将开发在 Linux 和 Solaris 操作环境上兼容的源代码的过程流水线化,所以第一步是修改 Solaris 平台上的移植代码。这些工具包括下面的使用指南:
- 如何识别出 C/C++ 源代码中可能出现的库调用区别。
- 如何转换 shell 脚本。
- 如何在 Solaris 下重新创建 Linux 系统配置数据。要了解更多信息,请参阅:
http://www.sun.com/software/linux/compatibility/ultralinux/
在 Solaris 平台上测试和构建了 Linux 应用程序之后,您就可以移植到 Linux 目标平台上了。这种方法有下面几个优势:
- 它使改变之处减到最少,从而让这些改变更容易理解,更容易管理,也更容易推广。
- 它使移植过程中产生的新问题的数目减到最少。
- 每一处改变都修正了某个已知的问题。
Linux 目标平台:经验丰富的 Linux 开发者可以在 Linux 目标平台上修改要移植的代码。您需要确保安装了正确版本的库和编译器,如 gcc、tcl/tk、glib、GNOME 和 KDE。
使用 grep 命令
在确定移植开发平台之后,您需要搜索下面内容,它们可能会导致源代码中出现移植问题:
- 正则表达式
- printf、sprintf、scanf 和 sscanf 例程的宏
- 可能改变数据排列的结构和联合
- #else .... #endif 语句
- 系统头文件(如 limits.h、types.h 等等)
搜索了可能产生的问题之后,您需要决定是否希望保留单独的源代码库,以支持多平台(Solaris、Linux 及其它平台)。
找出潜在的问题
在使用 grep 命令之后,您还需要检查是否存在低效率或不可移植的代码。下面的列表可以帮助您找出移植问题:
- 找出源代码和库中不兼容的地方。
- 实行比编译器所用的更严格的类型检查规则。
- 找出潜在的与变量有关的问题。
- 找出潜在的与函数有关的问题。
- 找出与流程控制有关的问题。
- 找出可能产生错误或降低效率的合法构造。
- 找出未使用的变量和函数声明。
- 找出有可能不可移植的代码。
使用移植工具
下面的工具已经可供使用,或者已在开发之中:
- 移植管理器(Porting Manager)是一个 Perl 脚本,它接受源代码树作为输入。它扫描 C/C++ 代码以找出仅用于 Solaris 的 API,并将它们标记出来。它还提供了文档,描述如何将 Solaris API 移植为 Linux 上与其相当的 API。扫描过程是基于表的(工具提供了要检查的 API 的表以及标记)。它将生成工具要检查的 API 的列表。它还会检查头文件和某些编译指示(pragma)。移植管理器有一个 GUI 前端,而且因为它是用 Perl 编写的,所以能够同时在 Solaris 和 Linux 上运行,估计在 Perl 运行的任何平台上都能够运行。
- developerWorks Solaris-to-Linux 移植工具是一种 Web 应用程序,它检查 Solaris 应用程序使用的 API 在 Linux 上的兼容性如何。下面的 Web 站点提供对该 Web 应用程序工具的访问:
ibm.com/developerWorks/linux/tools/l-solar.html
- MigraTEC 移植套装由 MigraTEC 开发,这家公司专门开发在平台之间迁移应用程序的工具。该移植套装包括 Migration WorkBench,它提供了一个完整的从 Solaris 到 Linux 的 API 映射:
http://www.migratec.com/MigraTEC/migration_suite.htm
修正编译时找出的问题
通常,要重复好几次才能够编译出没有问题的代码。请确保使用了 -Wall 选项,以捕获所有警告消息。
测试和调试程序
您可以使用 gdb 工具来调试修改过的代码。要了解更多关于 gdb 的信息,请参阅 GNU gdb 调试程序。
这一部分将讨论目录、文件系统、信号、尾数问题、系统派生的数据类型以及绝对地址。
目录
Linux 目录的结构是标准化的。每个目录都有定义精确的任务。典型的 Solaris 和 Linux 安装将创建如下表所示的目录:
Solaris 目录 | 功能 | Linux 目录 | 功能 |
/bin | 用户命令。 | /bin | 包含普通用户启动时和启动后所需的二进制文件。 |
/boot | 包含开始启动过程的 LILO 引导程序所需的文件。内核文件驻留在 /boot 中。 | ||
/dev | 包含 /devices 中的符号链接条目,大多数真正的设备条目都是在 /devices 中创建的。 | /dev | 包含真正的块、字符和其它指向设备的设备文件,如 fd0(第一个软盘驱动器)和 hda1(第一个硬盘驱动器上的第一个分区)。 |
/devices | 对于系统中的每个真正的设备来说,都应该在该目录中为其创建一个条目。 | ||
/etc | 其它命令、网络配置文件和脚本等等。 | /etc | 预留给属于机器本身的配置文件。/etc 中没有二进制文件。X-Windows 配置文件 XF86Config 存储在 /etc/X11 中。 |
/home | 通常用作用户主目录。 | /home | 通常用作用户主目录。 |
/kernel | 包含内核模块。 | 对应的内核文件在 /boot 和 /lib 模块中。 | |
/opt | 应用程序包。 | ||
/platform | 特定于平台的 Unix 和用于启动的设备驱动程序。 | ||
/proc | 包含关于活动进程和线程的信息,还提供一个接口来控制这些进程和线程。每个进程目录都有一些文件条目,包含该进程的内核结构。 | /proc | 包含深入到内核的文件系统视图。对于每个进程,都有多个目录,另外,还有对应于系统计数器和限制的目录和文件。 |
/lib | 只包含那些需要执行 /bin 和 /sbin 中的二进制文件的库。/lib/modules 包含可装入的内核模块。 | ||
/lost&found | |||
/mnt | 系统管理员进行临时安装所用的安装点。 | ||
/root | 这是 root 用户的主目录,除了 root 用户的概要文件信息之外,里面通常没有任何重要文件。 | ||
/sbin | 系统控制命令,例如 mount 和 umount。 | /sbin | 只被 root 用户使用的可执行文件,而且只是那些需要安装 /usr 并执行系统恢复操作的可执行文件。 |
/tmp | 它也是一个映射到系统内存的特殊文件系统。 | /tmp | 与 Solaris 系统相同 |
/usr | 编译器,管理性质的。 | /usr | 多数应用程序软件安装所在的位置。 |
/var | 包括 lpd 和 mail spool。也被各种需要记录日志文件的应用程序(如系统消息)所使用。 | /var | 包括 lpd 和 mail spool。也被各种需要记录日志文件的应用程序所使用。 |
文件系统
Linux 可以使用几种类型的文件系统。每种文件系统都有自己的格式和一组特征(如文件名长度、文件大小的最大值等等)。Linux 还支持几种第三方文件系统类型,如 MS-DOS 文件系统。下面的表列出了 Linux 可以使用的各种文件系统类型:
文件系统 | 类型名 | 注释 |
Second Extended Filesystem | ext2fs | 最常见的 Linux 文件系统 |
Third Extended Filesystem | ext3fs | ext2fs 的日志记录文件系统 |
Extended Filesystem | ext | 已被 ext2fs 取代 |
Minix Filesystem | minix | 最早的 Minix 文件系统 |
Xia Filesystem | Xia | 与 ext2 类似 |
UMSDOS Filesystem | umsdos | 用于在 DOS 分区上安装 Linux |
MS-DOS Filesystem | msdos | 使用 tp 处理 MS-DOS 文件 |
/proc Filesystem | proc | 提供系统信息 |