<>

2.4. 一些为方便操作而准备的脚本

2.4.1. $WORK/mkbootcd

$WORK/mkbootcd 这个脚本主要完成:

  • 卸载 initrd.img,以便对 initrd.img 进行操作

  • 压缩 initrd.img

  • 生成 bootcd.iso

  • 上传 bootcd.iso 以便观察结果

  • 重新加载 initrd.img 以便进一步调整

增加上传这个步骤是考虑到每前进一步都可以生成 bootcd.iso,方便测试,看到进展。

执行以下命令创建此脚本:

cat > $WORK/mkbootcd << 'EOF' && chmod +x $WORK/mkbootcd
#!/bin/sh
cd $WORK
umount tmpfs
#compress initrd.img to iso/boot/initrd.img
gzip -9 -c initrd.img > iso/boot/initrd.img
#create bootcd.iso
mkisofs -R \
        -b boot/grub/stage2_eltorito  \
        -no-emul-boot \
        -boot-load-size 4 \
        -boot-info-table \
        -o $WORK/bootcd.iso \
        $WORK/iso
#upload bootcd.iso
ftp ftpserver

EOF

2.4.2. ~/.netrc

[Note] Note

此文件为可选项。

如果 $WORK/mkbootcd 中使用了 ftp 上传 $WORK/bootcd.iso,则创建此文件可以让 ftp 非交互自动运行以简化操作; 如果不需要用 ftp 上传 $WORK/bootcd.iso,请跳过此节。

执行命令:

cat >> ~/.netrc << EOF && chmod 600 ~/.netrc
machine ftpserver login YOURFTPUSERNAME password YOURFTPPASSWORD
macdef init
hash
binary
cd iso
put bootcd.iso
bye

EOF
[Caution] Caution
  • 注意 “bye” 后面的空行

  • 根据实际情况更改 YOURFTPUSERNAME

  • 根据实际情况更改 YOURFTPPASSWORD

2.4.3. $WORK/gld.pl

我们需要复制一些可执行文件及其依赖的库文件。

一般的做法是:

  1. 执行 ldd 这个命令。例如要查找 /bin/bash 所依赖的库文件,我们需要执行 ldd /bin/bash

    root@domain:~/# ldd /bin/bash
    

    结果是:

            linux-gate.so.1 =>  (0xffffe000)
            libreadline.so.5.0 => /lib/libreadline.so.5.0 (0xb7fbc000)
            libhistory.so.5.0 => /lib/libhistory.so.5.0 (0xb7fb5000)
            libncurses.so.5 => /lib/libncurses.so.5 (0xb7f74000)
            libdl.so.2 => /lib/libdl.so.2 (0xb7f70000)
            libc.so.6 => /lib/libc.so.6 (0xb7e56000)
            /lib/ld-linux.so.2 (0xb7feb000)
    
  2. 复制这些文件到相应的 tmpfs 目录结构。

请相信,这绝对是个令人崩溃的过程。但是不要担心,我们可以写个脚本。

以下这个脚本复制所需要的可执行文件以及所依赖的库到 tmpfs 目录中。感谢 DawnFantasy 提供的这个 perl 脚本! (本来自己写了个 php 的脚本)

请用 vi 等编辑器建立此脚本。

cat > $WORK/gld.pl << 'EOF' && chmod +x $WORK/gld.pl
#!/usr/bin/perl 
#===============================================================================
#
#  DESCRIPTION:  Get library
#
#       AUTHOR:  DawnFantasy, <goldenshore999 # gmail # com>
#      VERSION:  1.1
#         DATE:  2008-02-04
#
#===============================================================================

use strict;
use warnings;

use Getopt::Long;

my %opts;
$opts{target} = 'tmpfs';
usage(), exit -1
    if ( not GetOptions( \%opts, 'import=s', 'verbose', 'target|t=s' )
);
usage(), exit -1
    if ( ( not @ARGV ) xor ( defined $opts{import} ) );

sub usage {
    print <<EOU;
Usage:
    $0 file1 [file2...fileX]  [-t DIR]  [-v]
    or 
    $0 -i list  [-t DIR]  [-v]

Options:
    -i, --import=FILE       Process files listed in FILE
    -t, --target=DIR        Use DIR as root. (Default ./initrd)
    -v, --verbose           Be verbose.
EOU
    return;
}


## files to process
my @files;
{
    my @filess;
    {
        ## files in @ARGV
        if ( not defined $opts{import} ) {
            push @filess, @ARGV;
            last;
        }

        ## import list
        open my $fh, '<', $opts{import}
            or die "$!\n";
        @filess = (<$fh>);
        @filess = map { chomp; $_ } @filess;
        close $fh;
    }
    print "File to process: (! means file NOT found.)\n";
    foreach (@filess) {
        print " !  $_ \n" and next if not -f $_;
        push @files, $_;
        print "    $_\n";
    }
}

## parse libs to copy
my @libs;
{
    print "\n";
    foreach (@files) {
        my $ldd = qx{/usr/bin/ldd $_};
        chomp $ldd;
        print "$ldd\n\n" if defined $opts{verbose};

        my @files = split /\s+/, $ldd;
        push @libs, grep { -f $_ } @files;    ## check for existence
    }

    ## Unified them
    my %h = map { ( $_, 1 ) } @libs;
    @libs = sort keys %h;
    if ( defined $opts{verbose} ) {
        print "Libraries to copy:\n";
        print "    $_  => $opts{target}$_\n" foreach @libs;
    }
}

## Do the real work
print "\n";
{
    print "Copying files, please wait...\n";

    ## Add those files in the original list
    push @libs, @files;

    if ( not -d $opts{target} ) {
        print "Creating directory $opts{target}\n";
        system qq{ mkdir -p $opts{target} };
    }

    my $v = $opts{verbose} ? 'v' : '';
    foreach (@libs) {
        if (/^\//) {
            ## Absolute path
            s/^\///;
            system
                qq{ tar -C / -hpmcf - $_ | tar -C $opts{target} -pmx$v -f - };
        } else {
            ## Opposite path
            system
                qq{ tar      -hpmcf - $_ | tar -C $opts{target} -pmx$v -f - };
        }
    }
}



EOF

好了, 万事具备, 让我们开始制作吧!