Chinaunix首页 | 论坛 | 博客
  • 博客访问: 49696
  • 博文数量: 23
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2013-12-05 15:34
个人简介

linux c++开发

文章分类

全部博文(23)

文章存档

2013年(23)

我的朋友

分类: LINUX

2013-12-05 15:37:42

原文地址:Linux 发行版制作指南 作者:mxcai2005

Linux发行版制作指南

摘要
  此文档着重介绍了Linux发行版制作过程中的各个步骤。(2002-10-08 13:20:09)

1 2 3 下一页
By Coolee

1.项目整体分析

  制作Linux发布的目的是为了在系统中能够快速,正确地建立Linux系统环境。制作 Linux发布的主要工作是决定各种软件的去留,因为有了RPM(RedHat Package Manager)包对其提供优良的管理能力,所以以目前比较成熟的RedHat 7.1(Linux Kernel Version 2.4.2-12)Linux发布程序作为蓝本,以RPM包作为基本的制定单元,以需求为原则对其进行取舍,得到适合实际需要的Linux系统。

  由此,项目自然而然的以分析RedHat Linux的光盘安装系统为起点,在掌握了其结构和行为的基础上,在包一级(结构部分)和代码一级(行为部分)进行修改,同时建立相应的测试环境,以便对修改进行及时的规范。

2.项目分步骤实施细节

  2.1对Linux光盘安装系统的分析

  ●结构部分

  在安装光盘中,主要的目录结构和文件大致如下:

  images/ 此目录下包含了制作启动盘的映像文件(文件后缀img),

  其中boot.img是当安装介质为CD-ROM时负责引导系统的映像文件

  bootnet.img是当安装介质为FTP,NFS等时负责引导系统的映像文件

  driver.img是由一些特殊设备驱动程序模块组成的映像文件,在当前内核不支持这些设备的情况下,提供了对它们进行访问的一种方法

  其中,boot.img映像文件中主要包含以下文件:


  boot.img
  |----vmlinuz Linux内核
  |----ldlinux.sys 引导Linux的系统文件
  |----syslinux.cfg Linux内核引导参数配置文件
  |----initrd.img 内存虚拟文件系统映像文件
  |----*.msg文件 引导时的各种提示信息文件

  其中,initrd.img为Linux ext2文件系统,构成如下:


  initrd.img
  |----/bin
  |----/dev
  |----/etc
  |----/module
  |----/sbin ------ loader
安装程序装载器
  |----/tmp
  |----/var

  可执行文件/sbin/loader的任务是判断安装介质的有效性,并从中执行安装程序。

  其实正是boot.img,在系统启动时被执行,经解析之后在内存建立起了Linux内核,并根据配置文件syslinux.cfg装载虚拟文件系统,形成了完整的Linux System,为后续的工作提供了必要的操作系统环境。Boot.img映像的文件系统类型为msdos,而其中的initrd.img映像的文件系统类型必为Linux系统自己的ext2,所以对于它们的解析操作是不同的,具体请参考附录A 。

  RedHat/ 此目录是RedHat Linux发布的核心目录,主要的目录结构都在这里,其中

  RPMS/ 包含了RedHat Linux发布的主要部分,即以RPM包的形式将Linux系统中的二进制可执行文件,配置文件,文档等等组织在一起,形成能完成一定功能的比较独立的软件包(文件后缀rpm)。这个目录就是把这些软件包都集合在一起,形成了RedHat Linux发布。

  base/ 包含了在安装过程中要用到的描述组织结构和安装行为的所有文件,其中comps,hdlist和hdlist2是描述RPM包组织结构的文件。

  comps 此文件把各个RPM包按一定的原则组织成若干组,即components,这样在安装过程中就不必对每一个包做出取舍,而以组为单位。comps文件为简单文本格式,它的结构如下所示:


  4 表示RPM包的版本号,当前为4

  1 base { }
   base是此component名,{…}中是此component中所包含的RPM包
    的名称列表,1表示在安装中默认为选中,即默认安装。

0 –hide IDS sensor{
        snort
   libpcap
}
    表示IDS sensor组中包含有snort和lipcap这两个RPM包。0表示
    这个组在安装中默认为不选中即默认不安装,并且由—hide指出
    不在用户界面上显示此组。

  hdlist和hdlist2 这两个文件维护从RPM包名到真实包文件名的映射过程,例如从snort这个RPM包名到真实包文件名snort-1.8.1-1.1.2.i386.rpm的映射。这两个文件是用特殊的程序生成的,无法用简单的方法察看其中的内容和结构。具体的生成方法请参考附录D。

  stage2.img , hdstg1.img , hdstg2.img , netstg1.img 和netstg2.img 是描述安装行为的映像文件,其中

  stage2.img 是当安装介质为CD-ROM时的安装程序映像文件

  hdstg1.img 是当安装介质为HardDisk时的安装程序映像文件

  hdstg2.img 是当安装介质为HardDisk时的安装程序映像文件

  netstg1.img 是当安装介质为FTP,NFS时的安装程序映像文件

  netstg2.img 是当安装介质为FTP,NFS时的安装程序映像文件

这里主要讨论stage2.img的内容


  stage2.img
  |----/etc
|----/modules
|----/proc
|----/usr----/bin----anaconda
安装程序主执行文件
|
|------/lib-----/anaconda
安装程序脚本文件目录
     | |----/installclasses
| |----/iw
| |----/texttw
| |----*.py
|
|------/share---/anaconda
安装程序资源文件目录
| |----/help
| |----/pixmaps

  如上所示,stage2.img映像文件中的主要部分是安装程序anaconda,它的主执行体是/usr/bin下的anaconda,由其调用的大量例程分布在/usr/lib/anaconda下,而安装过程中要用到的资源文件分布在/usr/share/anaconda下。stage2.img 的解析方法请参考附录B。

  ●行为部分

  RedHat 7.1的安装程序被命名为anaconda。如前所述,当boot.img所代表的启动介质被系统引导之后,在内存中就建立了一个完整的Linux系统(包括Linux内核和一个内存虚拟文件系统),之后便执行文件系统中存在的loader命令,从适当的介质中执行安装程序(例:安装介质是CD-ROM,就解析CD-ROM上的stage2.img,并从中执行安装程序),即执行anaconda,完成Linux系统的安装任务。

  此次利用RedHat 7.1的安装程序源代码的SRPM包形式:anaconda-7.1-5.src.rpm来获得anaconda的源程序,经解包后在/usr/src/redhat/SOURCES/anaconda-7.1形成了源代码树。


  anaconda-7.1
  |-------------------/bootdisk
启动盘目录
  |-------------------/docs
文档目录
  |-------------------/help
安装过程帮助系统目录
  |-------------------/installclasses
安装类型分类目录
  |-------------------/iw
安装各步骤响应目录
  |-------------------/loader
安装程序装载器目录
  |-------------------/pixmap
图形资源目录
  |-------------------/utils
工具目录
  |-------------------*.py
各Python脚本文件

  分析如下:

  anaconda安装程序主要用Python语言写成,它是一种解释性的,面向对象的脚本语言。源文件后缀为.py,也可生成可执行的字节码,后缀为.pyc或.pyo。其中:

  installclasses/ 子目录中各文件定义了在安装过程中用户可选择的安装类型,通常由四个文件workstation.py , server.py , laptop.py和custom.py来描述workstation(工作站)安装类型,server(服务器)安装类型,laptop(膝上型电脑)安装类型和custom(自定义)安装类型。每个脚本文件的内部,则是根据自己安装类型的特点对安装步骤,分区策略以及包的取舍做出了不同的方案。

  iw/ 子目录中各文件定义了在图形界面安装状态时各步骤对Next(下一步)和Prev(上一步)的响应函数。

  loader/ 安装程序装载器的源代码目录,用C语言写成。

  pixmap/ 图形资源目录,包括安装过程中使用到的所有位图,图标。

  utils/ 安装程序实用工具目录。

  anaconda 是安装程序的主执行文件,它建立了Python语言的运行环境,提供了程序的入口点并以模块的方式将各个子系统结合在一起。

  gui.py 定义了安装程序图形界面使用的各种窗口类,包括MessageWindow,ProgressWindow,WaitWindow,ExeceptWindow等,和控制这些窗口及图形界面行为的InstallInterface, InstallControlWindow, InstallControlState类。总之,控制gui。

  todo.py 定义了安装程序的各种行为函数,它是图形界面背后真正进行各项操作的函数集合。

  harddrive.py 定义了当安装介质为硬盘时,系统该如何找到安装程序的光盘映像,并从中执行程序。

  安装程序源代码的编译由make和make install组成,完成后在/usr/src/RedHat目录下形成了如下目录结构:


  instimage
|------/etc
|------/usr
|------/bin
|------/sbin
|------/lib
| |------/anaconda
| | |------installclasses
| | |------iw
| | |------texttw
| | |------*.py
| |
| |------/anaconda-runtime
| |------/boot/loader
|
|------/share------/anaconda
|------/help
|------/pixmaps

  此目录结构基本与stage2.img的文件结构相同。

  2.2调试环境的建立:

  ●对源程序的修改

  在分析完安装程序的基本构成之后,就要建立相应的调试环境。建立此环境的目的是为了可以方便地对修改过的安装程序及裁减后的RPM包进行随时的确认。显然,可以选用CD-ROM或本地硬盘作为调试介质,下表比较了两者的差别:
CDROM 硬盘
对应的安装界面 图形界面 菜单界面
对应的映像文件 stage2.img *.iso中的hdstg1.img , hdstg2.img
优点 图形界面,直接使用映像文件stage2.img 随改随调,调试周期短,效率高
缺点 每次改动都要求刻盘,调试效率低 菜单界面,每次调试都要求提供光盘映像文件*.iso,效率上打折扣

  在两者各有优缺点的情况下,考虑折衷的方案,即为了首先保证调试的效率,采用硬盘作为调试介质,但对应的映像文件选取stage2.img,这样能达到效率最大化,同时调试界面采取图形方式。采用此方案时,须修改源代码,以达到预期的效果。

  从前面对安装系统的分析,可以看出在initrd.img中的/sbin/loader程序负责判断安装介质的有效性,并从中执行安装程序。所以要首先修改它的源代码文件loader.c,从中找出硬盘安装时默认读出光盘映像文件*.iso的函数setupIsoImages,并注释掉其中在硬盘目录中寻找映像文件*.iso的相关操作,具体对应Line 582 至 Line590行中包含sprintf和if(){}循环的语句,以避免打开子目录,并在其后加入mountLoopback("/tmp/hdimage/RedHat/base/stage2.img","/mnt/runtime", "loop0");一句以便实现直接使用stage2.img的目的,并注释掉其后从errno=0开始的代码,经过整个while循环到closedir(dir),但保留umount(“/tmp/hdimage”);注释掉if(!net) return NULL;一句。以上操作目的是防止程序读出光盘映像文件*.iso。在loader.c的主函数main()中的结尾部分,注释掉if (!FL_TESTING(flags)) { 和 }的条件判断的两条语句,让程序毫无疑问地执行硬盘上的安装程序。至此,对loader.c修改完毕。

  同时还要对Python脚本的一些相关文件进行修改以保证对stage2.img文件的支持。具体的,在harddrive.py的类class HardDriveInstallMethod中,注释掉函数 mountMedia(self, cdNum)中的所有内容并加Pass语句的方法使此函数失效,同样方法处理umountMedia函数,mountDirectory函数和umountDirectory函数,为了保险起见,在其他函数中注释掉有关上面函数的调用。并在类的构造函数(初始化)中的# Go ahead…语句之前加self.tree=”/tmp/hdimage/”语句,并注释掉后面的所有语句。这样做仍然是要保证废弃iso映像转而对stage2.img实现控制。不仅如此,最好还注释掉todo.py中的Line1781至Line1783调用self.method.systemMounted一段,以确保不出差错。接着进行make和make install,重新编译程序,使修改生效,并把新的loader程序从编译的目标目录中copy到boot.img




Hacking Red Hat Kickstart
By Brett Schwarz on Tue, 2003-04-01 02:00. Software
How to create a single CD for fast and easy customized installation.
Installing Linux is a relatively easy task. However, I was faced with the task of installing it on multiple machines repeatedly, which is time consuming and prone to errors. This problem affected our whole group and other groups that relied on us. So I started using Red Hat Kickstart to automate the installs. This helped, but there still was room for improvement. What I ultimately wanted was an automated installation that would fit on one CD, dynamically partition the hard drives and contain all of the updated packages. I wanted to be able to start an installation then walk away from the machine, returning only when it was done. To accomplish this, I supplemented Kickstart with a customized version of the Red Hat installation program, Anaconda.
Although not officially supported, Red Hat has made available several tools and documentation to assist in customizing an installation. I describe a few of the possible ways to do this here, which should give the reader enough information to get started.
The following topics are covered in this article: replacing packages with updates, reducing the installation size to fit on one CD, utilizing Kickstart in the custom installation and creating a custom message screen.
The reader should have a good understanding of Linux installations in general. I also assume that no esoteric hardware is being used, as other customizations may be needed to accommodate such hardware.
Setting Up the Build Machine
The first step is to prepare the build computer. Because the installer tools are specific to a particular release, the build computer needs to have the same Red Hat release as the one used on the target(s). For our example, Red Hat 8.0 is being used. There are some differences between Red Hat 8.0 and previous versions, and you need to investigate them if you use a previous version.
Once the build computer has the correct release installed, the Anaconda packages need to be installed. These usually are not installed by default, so they need to be manually installed. They are located on the second CD of the standard Red Hat distribution and are named anaconda, anaconda-runtime and anaconda-help (optional).
The next step is to create a directory structure where the installation files will be located. The partition should have adequate space available, approximately 3GB. The actual location is based on your preference; for this article, the base directory is located at /RH80. Under this directory, we create directories for each of the CDs:
mkdir -p /RH80/CD{1,2,3}

We are not concerned with the source packages, so CD4 and CD5 are not included.
We make an additional directory where we can create the custom installation:
mkdir /RH80/ONE_CD

Now we can copy the contents of the CDs to the respective directories. Mount the first CD, then issue this command:
cp -a /mnt/cdrom/* /RH80/CD1/

Repeat this step for CD2 and CD3.
Copy the contents of the CD directories to the ONE_CD directory, but hard link them instead of actually copying the files. This saves space and is quicker:
cd /RH80
cp -al CD1/* ONE_CD/
cp -al CD{2,3}/RedHat/RPMS/* ONE_CD/RedHat/RPMS/

You'll get an overwrite TRANS.TBL message; you can answer no.
Selecting the Packages
Next we trim down the contents of the ONE_CD directory so it fits on one CD. I assume the CD size to be 700MB. I will not go into detail on how to do this, as the list of files to remove from the distribution is different from one installation to another. However, here are some tips for trimming down the distribution:
? Don't include the source RPMs.
? Remove the dosutils directory, as these will be automated installs.
? Remove any unnecessary packages. This can be complicated, because you need to make sure that the dependencies are still intact.
You should keep a record of the files that were removed. You can use this list in case you need to back out, and you will need it later if you edit the comps.xml file.
For the package selection, I logged to a file all of the base and core group packages with their dependencies (according to the comps.xml file). In order to find this information, I used the script getGroupPkgs.py (see Resources):
cd /RH80/ONE_CD/RedHat/base
getGroupPkgs.py comps.xml > /RH80/pkglist

Any additional package names can be appended to the end of this file. After my list was complete, I removed the packages not on the list by using the syncRpms.py script (see Resources). The arguments are the package directory and the list of packages is generated from getGroupPkgs.py. This script removes the packages not listed in the package list and prints out the package names. We redirect that to a file so we have a log:
cd /RH80
syncRpms.py ONE_CD/RedHat/RPMS/ pkglist > pkgs_rem

We can monitor the installation size by using the du command. The -h option displays the result in human readable format, and the -s option gives a summary of the whole directory tree:
du -hs /RH80/ONE_CD

The hdlist files actually decrease in size after they are regenerated (see below), because we removed many of the packages. This in turn reduces the size of the CD image.
The tricky part about removing packages is they may break dependencies. Even though getGroupPkgs.py resolved the dependencies base on the comps.xml file, they are not guaranteed to be accurate. Adding additional packages may break dependencies as well. One way to verify their accuracy is to create a temporary RPM database, and then do a test install on that database with the packages you have selected:
cd /RH80/ONE_CD/RedHat/RPMS
mkdir /tmp/testdb
rpm --initdb --dbpath /tmp/testdb
rpm --test --dbpath /tmp/testdb -Uvh *.rpm

Look for any error messages regarding failed dependencies. If any appear, resolve the dependencies by either adding or removing files that caused the discrepancy, and repeat the above test.
Once the package dependencies have been resolved, you can download the package updates pertinent for your installation. Put these files under a separate directory:
mkdir -p /RH80/updates/RPMS/

Remove the old files from the build directory and then link the updated files to the build directory. Do this for each updated package (where old_rpmfile is the previous version of the package):
cd /RH80/ONE_CD/RedHat/RPMS/
rm
# ... remove each old rpm
cd /RH80/updates/RPMS/
cp -l
# ... do this for each rpm

You should keep a record of the updated packages, in case you need to back them out. It's also a good idea to check the dependencies and size one more time, in case they changed after the packages were updated.
Next, we check the internal checksum of each package with the -K option to rpm. First we need to import the key:
cd /RH80/ONE_CD/RedHat/RPMS
rpm --import /usr/share/rhn/RPM-GPG-KEY
rpm -K *.rpm | grep "NOT *OK"

This isn't strictly necessary, but because we downloaded package updates, this verifies they are valid.
Preparing the Installation Files
Once all of the packages have been updated, we need to regenerate the hdlist files. They contain only the headers of the packages, which allows Anaconda to retrieve the header information more quickly. Because we updated packages, we need to regenerate these files with the genhdlist tool, which is part of the anaconda-runtime package:
/usr/lib/anaconda-runtime/genhdlist /RH80/ONE_CD/

Next we need to handle the comps.xml file. This file defines package groups and package dependencies (although they are not guaranteed). The file structure was changed in Red Hat 8.0 to be XML-based; in previous releases it was only a simple text file with some obscure tags. We need to ensure that packages defined within groups are included in our installation. We need to be concerned only with groups we are installing. If packages are missing (or if packages were added), we need to edit the comps.xml file (see Resources). Because we chose all of the packages in the Core and Base groups, however, we don't need to edit this file. We simply need to specify those groups under the %packages directive in the Kickstart file. See Listing 1 for an excerpt from the Kickstart file.
Listing 1. Excerpt from the Kickstart File
Technically, we can leave out the @Core and @Base groups, as they are installed by default. They are included here for illustrative purposes.
Creating a Custom Message Screen
We also want to create a custom message screen to give the user special instructions. The message screens are kept in the boot.img file (for CD-ROM installs) under the images directory. This is a DOS filesystem, so we can mount it to get to the contents:
cd /RH80/ONE_CD/images
mount -o loop -t msdos boot.img /mnt/boot

Looking in /mnt/boot, you see six message files: boot.msg, options.msg, general.msg, param.msg, rescue.msg and snake.msg. We create our own message file and call it custom.msg, an arbitrary name. Because snake.msg isn't really used, we replace that entry within syslinux.cfg with custom.msg. Edit syslinux.cfg in /mnt/boot and replace F7 snake.msg with F7 custom.msg.
A few other modifications were made to the syslinux.cfg file; refer to Listing 2. The default entry was changed from linux to ks. If the timeout occurs or if the user presses Enter at the boot prompt, then the ks label is used. Additionally, the timeout value was decreased from 600 to 60, so the installation can start sooner if there is no input from the user. The display entry was changed as well. Instead of boot.msg being the initial message screen, we wanted our custom message to be displayed. For the append line under the ks label, we added two things. The first is the keyword text, to enable text-based installs. Then we changed the keyword ks to ks=cdrom:/ks.cfg. This hard codes the Kickstart location so the user doesn't have to specify it at the boot prompt.
Listing 2. Modified syslinux.cfd File
Next we create our custom.msg file. Listing 3 shows our custom.msg. The contents of the file can be marked up, such as adding color around words. For example, ^O09Custom^O02 changes the color of Custom to blue, and ^O02 changes it back. See the syslinux reference in the Resources section for more information.
Listing 3. Custom Message
Once we have composed the custom message, we need to umount the boot image:
umount /mnt/boot

Building the CD
Before actually creating the CD, you may want to test it by doing a network install. See the Red Hat Kickstart documentation on how to do this.
We want this custom installation to be automated, so we put the Kickstart file on the CD itself. You can create the Kickstart file with any text editor, or you can use the GUI tool called Kickstart Configurator.
In the %pre section, add a shell script to probe the hard drives and dynamically create the partition information based on the number of drives. We take advantage of the fact that Kickstart executes the %pre section and then re-reads the Kickstart file. When it reads it for the second time, it includes the /tmp/partinfo file where the %include directive is located (see Listing 1). The /tmp/partinfo file is the output from the script. We use the list-harddrives command, which lists the available hard drives and their sizes. Having the partition created dynamically frees us from having to create multiple Kickstart files that hard code the partition information.
Once the Kickstart file is created, name it ks.cfg and place it in the root directory of our installation tree (/RH80/ONE_CD/). It is possible to create more than one Kickstart file and place all of them on the CD. Different Kickstart files might address different hardware configurations.
We can now create the ISO image. From our previous steps, the distribution should be small enough to fit on one CD and contain all of the updated packages. The mkisofs program creates the image, and then we can copy the image to the CD. The command to create the ISO image is:
cd /RH80/ONE_CD
mkisofs -r -T -J \
-V "My Custom Installation CD" \
-b images/boot.img \
-c images/boot.cat \
-o /RH80/mydist.iso \
/RH80/ONE_CD

Refer to Table 1 for a description of the options.
Table 1. Options Used for mkisofs
The last parameter to mkisofs is the source directory of the contents that need to be included in the image file (e.g., our custom installation directory). Several other parameters are available that you may want to use. For example, the -A, -P and -p options add additional labeling information to the image. The -m and -x options also allow you to exclude certain directories and file patterns from the image. See the mkisofs man page for additional information.
Next, add a checksum to the ISO image. This is not strictly necessary, but it provides a way for end users to check the integrity of the CD. The tool to add a checksum to the ISO image is called implantisomd5. To add a checksum to the ISO image, use the following command:
implantisomd5 /RH80/mydist.iso

A companion tool, checkisomd5, can be used to verify the checksum for you:
checkisomd5 /RH80/mydist.iso

The CD also can be verified during the installation. After booting from the CD, the user can issue this command:
linux mediacheck

Now we can burn the image to the CD. I assume the CD writer is already set up on your system. We use cdrecord below, but you can use other programs as well. The command is invoked as:
cdrecord -v speed=4 dev=0,0,0 /RH80/mydist.iso

The speed and dev options depend on your system. The device for the dev argument can be determined by using the -scanbus option to cdrecord:
cdrecord -scanbus


Using the CD
Once the image is burned onto the CD, insert the CD into the target machine and boot the machine. You should get the custom message that you created earlier. At this point, you can either press Enter at the boot prompt or let it timeout. When it times out it uses the default label, which we specified as ks (Kickstart).
If we did everything right, the installation should proceed without user interaction. In my experience, the installation takes approximately ten minutes. This may differ depending on your exact configuration.
Conclusion
With a combination of Kickstart and a customized Anaconda, a powerful and flexible installation can be created. This installation greatly improved cycle time and reduced errors for my project. I was able to install multiple machines, multiple times almost effortlessly. In this article, I touched on only a few ways to take advantage of Kickstart and Anaconda, but there are many other possibilities. I encourage those interested to read the documentation in the Resources section and to join the Kickstart and Anaconda mailing lists for further information.
Resources





1、 Distribution Hacking 101: disecting anaconda

2、Editing comps.xml

3、Burning a RedHat CD HOWTO

4、The (unofficial) RedHat 7 Customised Installer mini-HOWTO

5、 Customized RedHat Linux Kickstart Installation Cdrom





你可以看下面这篇文章,我记得几年以前好像还有一个从头做起的howto。你还可以找找中文的。我也看到过。 最近我也想搞自己的一个发行版,针对没用过电脑的,或不想学电脑的。不过今天看到这个才发现已经有很多人搞了,我放弃了。我现在只想贡献点子。

原文:

http://molinux.blog.51cto.com/2536040/548247

阅读(850) | 评论(0) | 转发(0) |
0

上一篇:C 语言程序优化

下一篇:Koji平台搭建

给主人留下些什么吧!~~