全面系统移植Linux
发表于:2007-05-26来源:作者:点击数:
标签:
现在, Linux系统 已广泛地应用于科技和商业领域。在中高端领域,Linux系统除了支持包括文件、电邮、 网络 服务器 在内的企业架构外,还支持诸如防火墙、VPN服务器、路由器和网关等业务单元架构;在低端领域,Linux通常用于 嵌入式 系统中,例如进程控制系统
现在,Linux系统已广泛地应用于科技和商业领域。在中高端领域,Linux系统除了支持包括文件、电邮、网络服务器在内的企业架构外,还支持诸如防火墙、VPN服务器、路由器和网关等业务单元架构;在低端领域,Linux通常用于嵌入式系统中,例如进程控制系统、PDA、家用网关和机顶盒等。
在系统启动和管理方面,Linux系统在企业中的应用与桌面应用十分类似,它们使用同样的启动机制。这一点在下文中将予以介绍。
由于嵌入式系统需要迅速启动,因此它所启动的进程数量有限,操作的资源也有限。用于嵌入式系统的存储设备和小型硬件限制了系统的存储空间。有限的存储空间决定了嵌入式系统必须采用专门的文件系统和硬件解决方案,例如磨损持平技术(Wear-Leveling)。该系统并不适用于普通系统,只可在一些以特定存储设备为目标的文件系统中实施。这些存储设备的写入次数是特定的,因为磨损持平技术的目标就是确保所有的目标存储器的写入次数大体相同。
嵌入式系统核心构件
所有Linux套件都包含同样的核心构件:一个内核和一个根文件系统。后者包含着系统使用的软件和库,以及所有用来为用户提供支持架构和用户使用的应用软件。在标准的开发系统中,根文件系统中的许多应用软件都是编译软件和用于应用软件开发的相关软件(习惯上被称为工具链)。
嵌入式 Linux系统通常也包括同样的核心构件,只是它们有一些特殊之处。由于嵌入式系统的开发通常是在桌面系统环境下完成的,并且它的目标是特定的嵌入式开发主板。诸如TimeSys Linux之类的嵌入式Linux套件为嵌入式主板提供了特殊的内核、根文件系统和多套工具链。其中一套工具链集成在文件系统的内部,另一套则安装在桌面系统的文件系统中。后者被称为交叉编译程序,可以产生可以在嵌入式主板上执行的二进制命令。TimeSys Linux还包括第三套工具链,可以在Windows系统中运行,并产生运行于嵌入式主板的二进制命令。
宿主系统和目标系统对于大多数嵌入式系统开发是十分重要的概念。交叉编译程序经常用于嵌入式系统开发的原因是嵌入式主板一般没有对应用软件进行编译和优化所需要的资源。同样,它们也没有足够的空间进行全面开发或纠错。常用的解决方案是使用诸如NFS (网络文件系统)之类的技术,获取实际上存储于桌面开发系统的文件系统。因为桌面系统可以提供交叉编译程序和用于开发的存储空间,该系统环境被称为宿主系统。由于嵌入式系统开发主板是应用程序最终的存储和运行场所,因此它又被称为目标系统。
总之,宿主系统用来建立最终用于嵌入式系统的文件系统。对于大多数嵌入式系统来说,它包括一些压缩的、存储于内存中的文件系统,通常被称为初始RAM磁盘,以及其它存储于闪存中的压缩文件系统镜像。这些可以加载到内存中,也可直接调用。
与嵌入式Linux套件相关的各类工具链和文件系统组件增加了嵌入式系统移植的复杂程度。例如,为了给嵌入式主板编译2.6内核,必须先升级用户使用的交叉编译程序。但是,在此之前用户也许还要先升级用来开发交叉编译程序的桌面系统编译程序。
升级嵌入式系统
如果用户安装了一个与TimeSys Linux 2.6一样的商业Linux套件,那么它能提供一整套已经过验证、可以共同工作的核心Linux组件。然而,即使是在这种情况下,用户在已有系统上所做的改动也无法全部自动移植给新的SDK(系统设计成套工具)。通常情况下向基于2.6内核进行系统移植包括以下过程:
◆升级所有强制性套装软件以适应编译程序,在与嵌入式系统相关联的任意桌面系统上建立系统环境。
◆升级所有强制性套装软件以适应为目标系统开发应用软件的所有交叉编译程序。
◆ 将已定制的内核设置移植到2.6内核下。
◆ 将所有硬件驱动程序修改为2.6内核下可用的驱动程序。
◆升级所有强制性套装软件,以便与用于现有根文件系统或初始RAM磁盘的应用软件和工具软件相适应。
◆ 将所有系统管理和设置变化由现有根文件系统移植到2.6内核下的新根文件系统中。
◆ 将已定制的应用软件由现有根文件系统移植到2.6内核下的新根文件系统中。
初始RAM磁盘和根文件系统
文件系统是供系统读写数据的存储媒介所在的区域。Linux系统使用文件系统的目的多种多样,即包括存储系统、用户文件和文件目录,也包括作为用来支持虚拟内存的对换空间。Linux系统中最主要的文件系统是根文件系统,用户可以通过“/ ”目录安装。
将内核加载入内存的第一步是Linux系统的启动。许多Linux系统在启动时,内核都会使用一个已存入内存的文件系统——初始RAM磁盘。初始RAM磁盘未经任何压缩,可直接加载入内存,并且在启动过程中可作为一个暂时的根文件系统使用。通过初始RAM磁盘用户可以执行命令,也可以在用户使用系统硬件前,预先加载后续步骤所需的模块。在桌面系统中,初始RAM磁盘几乎是一个通用的过度过程。在内存充足的嵌入式Linux系统中,初始RAM磁盘是Linux 系统运行中实际使用根文件系统。
TimeSys的Target Configurator工具软件作为TimeStorm Linux开发套件中的一员,可以大大简化初始RAM磁盘的创建过程,Target Configurator创建的初始RAM磁盘包含有启动时间和运行时间所需的所有系统软件。Target Configurator还可以简化向用作根文件系统的初始RAM磁盘和诸如JFFS 2或ext 3等用于不同类型存储设备的文件系统增加应用软件的过程。
TimeSys Linux 2.6 Reference Distributions包含有预先汇编的、用于所有支持平台和架构的初始RAM磁盘。大多数Linux套件可提供一些小型程序(如用于Red Hat Linux的mkinitrd),以便用户建立自己的初始RAM磁盘。然而,如果用户正在向基于2.6的内核移植,并且想继续使用用户已编制好的初始 RAM磁盘,那么用户需要对它的内容进行检验以便与新内核兼容。
用户可以将初始RAM磁盘作为一个Linux系统中的回送硬件进行安装,从而对它进行检验。虽然回送硬件是一种虚拟硬件,但是Linux系统可以像访问真实硬件一样访问它。在安装初始RAM磁盘前,用户必须确定当前的内核支持回送硬件设备。对于2.6内核来说,用户可以通过内核设置编译程序中的Device Drivers→Block Devices→Loopback device support选项为回送硬件提供支持。在2.4内核下,该选项在Block Devices→Loopback device support。
在使用GRUB引导程序的桌面Linux系统中,系统的初始 RAM磁盘通常作为一个分离的内核外部文件而存储。该文件一般在/boot目录下,且可以在GRUB设置文件(/etc/grub.conf)中进行识别。在大多数的嵌入式系统中,初始RAM磁盘是作为内核外部文件创建的,但是却作为内核搭建的最后一步与内核捆绑在一起。图1是用Target Configurator创建初始RAM磁盘的屏幕显示画面。Target Configurator可以简化不同类型的根文件系统的创建及维护过程。
图1 创建初始RAM磁盘
桌面Linux系统通常使用在初始RAM磁盘中使用ext 2文件系统,而大多数嵌入式Linux系统作用更小、更简单的文件系统,例如CRAMFS、ROMFS或Minix。无论初始RAM磁盘中包含的是什么类型的文件系统,初始RAM磁盘通常使用gzip对文件进行压缩,以便节省更多的空间。Linux初始RAM磁盘加载程序可以对压缩后的文件进行识别,并在安装前自动对其进行解压缩。
如果用户已有一个初始RAM磁盘并希望将它移植到2.6内核下,那么用户需要解压缩、安装并对其进行检测。因为初始RAM磁盘通常都是处于压缩状态的,所以用户需要对文件进行重命名才能成功解压。初始RAM磁盘常用的解压缩和安装命令如下:
# gunzip initrd.img.gz
# mount -t ext2 -o loop initrd.img /mnt/initrd
为了完成文件系统的安装,用户使用的目录必须已作为一个安装点(例如/mnt/initrd)而存在。安装命令的-t选项用来确定文件系统的类型,除非用户的初始RAM磁盘不是ext 2格式的,否则这一选项是可以选择的。一旦初始RAM磁盘安装完毕,它便会在磁盘列表中显示出来。显示如下:
Filesystem 1K-blocks Used Available Use% Mounted on
/tmp/initrd.img 2948 510 2288 19% /mnt/initrd
同时,初始RAM磁盘也可以像其它文件系统一样被展开、进行研究分析,示例如下:
# cd /mnt/initrd
# ls -al
total 13
drwxr-xr-x 9 root root 1024 Feb 16 13:31 .
drwxr-xr-x 16 root root 4096 Mar 3 08:58 ..
drwxr-xr-x 2 root root 1024 Feb 16 13:31 bin
drwxr-xr-x 2 root root 1024 Feb 16 13:31 dev
drwxr-xr-x 2 root root 1024 Feb 16 13:31 etc
drwxr-xr-x 2 root root 1024 Feb 16 13:31 lib
-rwxr-xr-x 1 root root 340 Feb 16 13:31 linuxrc
drwxr-xr-x 2 root root 1024 Feb 16 13:31 loopfs
drwxr-xr-x 2 root root 1024 Feb 16 13:31 proc
lrwxrwxrwx 1 root root 3 Feb 16 13:31 sbin -> bin
drwxr-xr-x 2 root root 1024 Feb 16 13:31 sysroot
Linux启动顺序
内核加载完成后,传统的Unix和Linux系统会执行一个系统应用软件作为初始化进程。该应用软件在系统的/sbin/init目录下。一般情况下,初始化进程是所有进程的第一步,是系统所有进程的铺路石,用户可以使用“ps”命令调出进程状态列表。初始化进程可以对/etc/inittab文件进行读取,从而识别系统启动、进程和程序列表的方法。
使用初始RAM磁盘启动
如果用户系统使用初始RAM磁盘作为根文件系统,系统的启动程序便多了一步。系统的第一步不是执行初始进程,而是对初始RAM磁盘进行解压并安装,并执行/linuxrc文件。该文件必须是可以执行的,可以作为一个提供其它可执行命令列表的命令文件。另外该文件还必须是一个像BusyBox一样的复调用二进制命令,或者作为一个连接复调用二进制命令或/sbin/init进程自身的符号链接。
/linuxrc文件执行完毕便可进入初始RAM磁盘的安装进程。这一进程由内核源代码文件init/do_mounts_initrd.c来指定。/linuxrc文件实际上是一个命令程序,其形式如下(出自无devfs 文件系统或udev的Red Hat 9.0):
#!/bin/nash
echo Mounting /proc filesystem
mount -t proc /proc /proc
echo Creating block devices
mkdevices /dev
echo Creating root device
mkrootdev /dev/root
echo 0x0100 > /proc/sys/kernel/real-root-dev
echo Mounting root filesystem
mount -o defaults --ro -t ext3 /dev/root /sysroot
pivot_root /sysroot /sysroot/initrd
umount /initrd/proc
由此可见,使用初始RAM磁盘的Red Hat系统中的缺省/linuxrc文件可执行一系列系统初始化命令。
如果用户正在对一个拥有本地存储器的Linux系统进行移植,并且该系统并不局限于初始RAM磁盘,那么命令文件中的最后一组命令可将根文件系统安装到存储设备中,并使用“pivot_root”命令改变“/”目录下的系统主旨。linux-utils套件中的“pivot_root”命令可以将系统的根目录由初始RAM磁盘改为可提供长期存储器的硬件设备。如果用户正在使用GRUB,该硬件可以通过系统中的根参数root=value进行识别。
在升级使用初始RAM磁盘的定制Linux系统时,用户需要完成下列工作:
安装并检验初始RAM磁盘,检查它是如何使用/linuxrc文件的。如果/linuxrc文件是一个命令程序,用户需要检验它所执行的命令,从而确定这些命令与2.6内核相适应。如果它特别引用了一些诸如“modprobe”或“insmod”之类的命令,那么用户必须确定已经在初始RAM磁盘和其它文件系统中安装了这些工具软件与2.6内核相兼容的版本。用户的初始RAM磁盘必须包括一些为2.6内核搭建的内核模块,并且遵循2.6内核使用的命名规则,即使用.ko扩展名,而不是.o扩展名。
如果/linuxrc文件是一个连接/sbin/init程序的符号链接或硬链接,那么用户需要确定初始程序使用的命令文件不是2.4内核专用的。用户同样要遵循上述原则进行检测和重名命。
假设用户的系统可以正确地执行/linuxrc文件,系统通常可以将系统文件的根改变到一个新的“/”目录下,或者手动执行/sbin/init进程。Linux内核为了寻找初始进程而执行一次顺序搜索。较旧版本的内核需要用户来确定作为启动进程的一部分而执行的文件名称,方法是使用启动加载程序中的initrd=value参数。如果用户使用初始RAM磁盘或/linuxrc文件中的“exec”命令,可自动启动初始化进程而不需要以上步骤。
标准的Linux初始化次序
在桌面Linux系统或较大的Linux系统中,大多数系统使用一整套的应用软件(SysVInit套装软件)和一套相关的小程序(initscripts套装软件)对系统启动进程和启动次序进行识别。
大多数桌面Linux系统使用“运行级别”这一概念识别系统执行的应用程序和执行顺序。不同的运行级别是定义系统使用模块所对应的某组应用软件的简单方法。例如,运行级1通常被称为单一用户模式,主要用来对系统进行维护。当系统处于第一运行级时,处理运行状态的只有系统管理员用来与系统进行交互和维护所需的核心应用程序。
同时使用SysVInit和initscripts套装软件的系统启动过程是:当内核加载完毕并开始运行时,它会调用初始化进程进行工作。该进程将读取/etc/inittab文件,并识别该命令文件启动的基本进程和程序。
在/etc/inittab文件中,缺省的运行级由包含“initdefault”字符串的命令行来识别,例如 id:2:initdefault:。
在此例中,缺省的运行级是2。/etc/inittab文件中的额外入口将对初始化系统所运行的命令程序进行识别,例如 si::sysinit:/etc/rc.d/rc.sysinit。
系统初始化程序运行后,使用SysVInit和initscripts的Linux套件将对系统进入某一特定运行级时发生的事件进行定义。例如,用户在 /etc/inittab文件结尾部分的一些命令行中,可能会看到有关运行级2的额外信息,例如 l2:2:wait:/etc/init.d/rc 2。
此命令行指明,当系统进入运行级2时,/etc/init.d/rc命令将随参数“2”一起被执行。结果导致“rc”命令执行所有在/etc/rc2.d目录下的适当文件。此目录下的文件名都为S+NN+名称或K+NN+名称,且这些文件都是可执行的外壳程序。这些程序中还包含有其它系统命令的列表。当系统进入某一特定的运行级时,名称以“S”打头的文件便会被执行。系统离开某一特定运行级时,名称以“K”打头的入口命令便会被执行。命令的执行次序依照NN所代表的两位数字的大小进行排列。至于名称则由用户自己定义,但一般应能够被文件启动的程序和子系统调用。
对启动次序中的定制进行检查
在向2.6内核进行移植过程中,用户要确定进行如下修改:
◆ 用户必须将所有强制可加载内核模块复制到用户所使用的初始RAM磁盘中。为了能与2.6内核一起工作,这些模块必须使用新的.ko命令规则。
◆ 初始RAM磁盘中的/linuxrc文件或正常启动次序中的其它文件不能包含任何使用旧模块命名规则的模块加载索引信息。
Target Configurator工具的一大优势就是它可以自动建立一个初始RAM磁盘和一个适应2.6内核的根文件系统。如果用户手工建立根文件系统或初始RAM磁盘,那么用户需要先确定根文件系统中包含有适当的初始化命令。
如果用户正在将一个基于2.4内核的TimeSys Linux系统移植到一个2.6内核下,而且用户已经对系统的启动次序或所需执行的应用软件进行了定制,那么用户必须同时对2.6内核下的系统启动次序做同样的定制。正如上文提到的,如果用户的2.4系统为特定的驱动程序或子系统加载了内核模块,那么用户必须确定已安装了这些工具软件适用于2.6内核的版本。用户的初始RAM磁盘和文件系统必须包含有为2.6内核建立的内核模块,并且以2.6内核的命名规则进行命名。
如果用户的2.6 系统使用的是devfs文件系统,而不是标准的Linux文件系统或udev,那么用户也许还需要对硬件或文件系统索引进行升级。例如,如果用户正在使用 2.4内核下标准的dev文件系统,并且要升级到适用于2.6内核的devfs文件系统,那么用户需要升级硬件的索引,例如将dev文件系统中的硬件名/dev/md0改为devfs文件系统中的硬件名/dev/md/0。
2.4和2.6内核之间的另一个重要区别是,在2.6内核下,许多应用程序由于升级已无法支持GLIBC或uClibc库。在这种情况下,用户还需要确定用户的初始RAM磁盘或根文件系统中还包含有应用程序所需的新版共享库。如果用户正在创建新的初始RAM磁盘或根文件系统,那么就不必担心这一问题了。但是如果用户是对已有的初始RAM 磁盘或根文件系统进行升级,那么这一点十分重要。
小结
不同内核下的Linux系统启动过程并未发生变化,但是值得注意的是,在进行内核移植过程中,用户必须了解系统是如何初始化的。尽管启动过程本身没发生变化,但是一些与内核模块相关的规则发生了变化。因此明确现在启动命令是否还能正确运行是十分重要的。用户还必须了解系统启动时所执行的文件和应用程序,以便决定哪儿需要做相应的修改。总之,只要用户了解系统的启动次序并仔细检验系统启动进程中执行的文件,移植任何定制Linux系统的实施方案都是可行的
原文转自:http://www.ltesting.net
|