为。现代linux系统进行软件开发时,软件和硬件的可移植性是需要考虑的一个非常重要的问题。但可移植性究竟意味着什么?你如何才能实现软件预期的灵活性,?
这些问题常常困扰着开发人员。本章的目的就是为了解决在使用linux时普遍面临的各种硬件和软件可移植性问题。
本章大致被分为两部分。前半部分介绍纯软件的可移植性。在这种情况下,。
最理想的情况是,所有软件都可以被自动安装,而不需要用户干涉,尤其是当该软件属于一个大型项目或是linux发行版的一部分时更需要如此。通过使用本章介绍的工具和技术,你将能够使得你所编写的软件更具可移植性,可以运行在如今的各种linux发行版之上。
本章的后半部分着重介绍为不同的硬件平台编写软件。现代硬件的机器结构相当复杂,虽然本章不会尝试阐述现代计算机的组织结构,但本章会试**决几个根本性的问题,如果你打算为运行linux的不同硬件平台编写软件,这些问题会影响到你。你还将学习大头字节序和小头字节序计算机、编写同时适用于32位和64位机器的**,并简要触及将linux内核作为linux系统中一种可移植硬件抽象层形式的需要。
在阅读完本章之后,你将会对为最终用户编写软件更具信心。虽然你并不会在本章中学习到所有你需要知道的内容,但当你在开发自己软件的过程中遇到这些问题时,你将会为考虑和学习许多其他实际的可移植性问题做好准备。请记住这样一条准则:
软件编写没有什么硬性限制。但你应该记住:要考虑你的决定会如何影响其后的软件可移植性。
可移植性并不是一个新概念。从最初的电脑开始,人们就希望编写的软件能够尽可能地被各种计算机所使用,而不需要在这一过程中对软件进行大的修改。要定义何谓可移植性,我们需要考虑开发一个复杂的现代软件所要花费的平均时间。
如果该软件原本是为某一特定的软件或硬件环境所编写的,那么我们可能需要在不进行大改动的情况下将它移植到其他类似的环境中。
软件具备可移植性的更正式的解释是:如果将一个软件移植并使其适应新环境所需要付出的努力小于从头开始重建同一个软件所需要付出的努力,那我们就说这个软件具备可移植性。
可移植软件可以追溯到数字计算机诞生的那一天。早期的计算机由插板和可以手工编程的开关构成。一个“程序”是由手工安装到专用机器中经过特别配置的电线组成的。
在那个年代(在第一个汇编语言程序出现之前),还没有出现我们如今已很熟悉的许多概念,如型号、微处理器系列等。
随着时间的推移,硬件变得越来越复杂,而用户希望在购买机器上拥有足够的灵活性,无论他购买的是什么类型的机器,它都可以运行已有的软件。所以在2023年,ibm公司公布了system/360机器。它是第一款系列兼容计算机。
这些大型机器虽然彼此结构不同,但它们却可以执行同一段**、运行相同的程序。这是第一次实现一台机器上的软件可以在不做修改的情况下运行在同一系列的另一台机器上。
随着电脑变得更加强大和复杂,编程语言从本质上也变得更加抽象。曾经用汇编语言(或手工机器**)编写过的程序改为使用更高级的语言如c、pascal或fortran来编写。这些编程语言不仅易于被开发者学习和使用,而且它们还允许将开发者编写的**从一台机器移植到另一台机器。
在机器之间移植一个应用程序仅需要修改和机器硬件相关的**并对它进行重新编译。这虽然很费时,但却是朝正确方向迈出的一步。
高级编程语言的不断发展使得诸如unix这样的复杂操作系统的开发成为可能。unix之所以后来被看作是一个可移植的操作系统,就是因为它使用c编程语言(该语言也是由unix创始人发明的)进行了重写。因为我们可以为许多不同的计算机编写c编译器,所以对unix操作系统的移植是完全可能的。
整个过程虽然很繁琐和复杂,但它比从头开始重写整个系统要容易得多,而且它还在很大程度上避免了对单个应用程序的改写,这在以前是决无可能的。
unix是一个强大的操作系统,它为复杂的用户应用程序提供了坚实的软件平台。它引入了一些目前仍然被广泛应用的基本概念和抽象,并极大地改进了编写可移植用户软件的过程。通过对机器中的物理硬件进行抽象,一个程序员可以编写针对unix系统的**,而不是针对来自某一特定厂商的特定机器的**。
当然,其结果是不同的厂商都试图在他们的unix供给上超越其他厂商,这导致了“unix战争”。
在20世纪80年代后期和20世纪90年代,unix市场逐渐(有时也较为动荡)平静下来,面对来自非unix厂商日益激烈的竞争,不同的unix厂商开始携手合作以提供一个共同的unix标准。通过标准化unix,软件开发人员可以更容易地编写可移植软件,使得软件可以运行在许多不同的unix系统之上。这一标准化工作直接导致了可移植操作系统接口(posix)标准的产生。
posix其后又被(可自由获取的)单一unix规范(sus)所补充。
软件可移植性在过去十年里又有了飞跃的发展。在20世纪90年代,sun公司的绿色计划(后来导致了j**a的产生)寻求创建一个完整的虚拟机,用于帮助解决当时在各种不同的嵌入式软件平台上存在的问题。通过使用j**a虚拟机,软件只需一次编译就可以在移植了虚拟机的任意平台之上运行。
j**a虚拟机(jvm)和j**a编程语言现已成为新一代程序员熟知的概念。
随着时间的推移,可移植性的概念已发生了改变。以前,只要软件可以在来自同一厂商的各种机器上使用,我们就称该软件是可移植的,但现在我们期望linux(和unix)软件可以在各种不同的机器、发行版、配置等情况下都可以运行。如今,一个为基本的32位intel架构的计算机所编写的软件可以在不做修改的情况下在itanium、powerpc或sparc机器上重新编译被认为是理所当然的。
本章的其余部分将向你介绍使这一切在linux上成为现实的概念。
可移植性对不同的用户和linux软件开发人员意味着不同的含义。有些人更关心平台之间的可移植性,希望他们的软件可以运行在linux、其他类型的unix和诸如sun solaris或apple mac os x等类unix系统上。其他人则更关心linux发行版之间的可移植性,希望他们的软件可以运行在众多的linux发行版之上。
还有一些人对两种情况都关心,而且希望他们的软件可以自由运行在来自不同厂商发布的各种不同类型硬件平台的32位和64位系统上。
即使你最初的设计目标并不是希望你的软件拥有广泛的可移植性,但想远一点总不是一件坏事。一个不可避免的事实是软件有时会超越其最初的设计目的和生命周期。你可能希望能减轻那些今后需要维护你的软件的用户的负担。
任何linux系统的核心都是linux内核。它的标准版本本身就已支持超过24种不同的硬件平台架构。当你意识到一个普通的pc工作站只是i386架构的一个变体的时候,你已开始看到它所涉及的规模。
linux除了其令人惊异的高度硬件可移植性以外,它还提供了众多的设备驱动程序以支持各种连接到系统上的周边设备。从某种程度来说,linux内核的主要目的就是为了提供在这些不同的机器硬件之上的一个可移植软件抽象。
当为linux编写软件时,将使用到依赖于linux内核中特殊特征的标准化系统函数库。函数库负责提供常用的软件例程,而内核则负责处理繁琐的硬件细节。这样一来,你就不需要在编写普通应用程序时留意机器的底层硬件了。
当然,如果你正在建立定制设备或需要挖掘机器的所有潜能,就需要在应用程序中突破这一抽象以实现一些更大的目标。请看图3-1以了解一个应用程序是如何与一个运行linux的典型系统结合的。
图3-1 应用程序与运行linux的典型系统相结合的图示。
人生是一连串的取舍,linux开发同样如此。与特定的硬件和软件环境相比,抽象程度越高,性能将会越低。不过,现代计算机都很便宜,一般用户所拥有的计算机性能都远远超出他们的最低需求。
但是,如果你是为资源受限系统进行开发,你可能就需要稍微改变一下这些规则。例如,在你所创建的一个嵌入式设备上,你(当然)会假定它是一个特定的硬件平台并在保持一定程度的设计灵活性范围内使用一切可能的技巧来创建产品。
第3章Linux编程基础
本章将带领读者学习在linux中进行c语言编程的基本技能。学习了本章后,读者能够掌握如下内容。熟悉linux系统下的开发环境。熟悉vi的基本操作。熟练emacs的基本操作。熟悉gcc编译器的基本原理。熟练使用gcc编译器的常用选项。熟练使用gdb的调试技术。熟悉makefile基本原理及语法规范。熟...
Linux讲稿 第3课
1.文件 目录的存取权限。ls l etc 长格式显示所有内容 相当于ll命令 补充此选项的第一列内容 存取权限 前十位表示文件 目录的 第1位若为 d 表示目录,表示普通文件,b 表示设备 块文件 2 4位表示文件所有者的权限 5 7位表示群组内其他成员的权限 8 10位表示组外其他所有人的权限 ...
Linux讲稿 第3课
1.ls命令。ls 选项 目录或文件 1 ls home查看 home目录下的文件 不包括隐藏文件 ls a home 显示 root目录下所有文件 包括隐藏文件,隐藏文件前面带 ls l etc 长格式显示所有内容 相当于ll命令 补充此选项的第一列内容 存取权限 前十位表示文件 目录的 第1位若...