这次建小Linux的方法有少许不同,添加了一个复制命令的脚本,如此,往目标主机上移植命令就变的很简单,并且还增添的一些功能,一个小的Linux操作系统逐步完善起来。

 

在宿主机上添加一块磁盘,不用太大,在这里我们添加一块20G的磁盘。

 

1、分区格式化磁盘/dev/sdb 

3个分区:boot所在的分区(主分区)/dev/sdb1:为100M

          交换分区/dev/sdb2为:256M    系统ID改为82 

          根分区/dev/sdb3为:1G

创建分区都已熟悉,步骤也不难,在此省略不写。

对于一个新磁盘分区,不用partprobe /dev/sdb重新写入磁盘系统也可以识别。所以,直接查看就行了:

    # cat /proc./partitions

格式化分区:

    # mke2fs -j /dev/sdb1

    # mke2fs -j /dev/sdb3

    # mkswap /dev/sdb2

 

2、安装grub

 

安装grub之前需要先挂载:

    # mkdir /mnt/{boot,sysroot}

    # mount /dev/sdb1 /mnt/boot/

# mount /dev/sdb3 /mnt/sysroot/

安装grub

    # grub-install --root-directory=/mnt /dev/sdb

    # ls /mnt/boot/grub/

device.map     ffs_stage1_5      minix_stage1_5     stage2           xfs_stage1_5

e2fs_stage1_5  iso9660_stage1_5  reiserfs_stage1_5  ufs2_stage1_5

fat_stage1_5   jfs_stage1_5      stage1             vstafs_stage1_5

 

3、准备内核和initrd

 

    # cd /mnt/boot/

    # cp /boot/vmlinuz-2.6.18-164.el5 ./vmlinuz

    # ls

    # cd /tmp

    # mkdir linux

    # cd linux

    # zcat /boot/initrd-2.6.18-164.el5.img | cpio -id

    # ls

    # vim init

    将:mkrootdev -t ext3 -o defaults,ro /dev/vol0/root

    改为:mkrootdev -t ext3 -o defaults,ro /dev/sda3

    # find . | cpio -o -H newc --quiet | gzip -9 > /mnt/boot/initrd.gz

压缩完成,linux文件便可以删除了

    # rm -rf /tmp/linux

编辑grub配置文件:

    # cd /mnt/boot/

# vim grub/grub.conf

添加:

    default=0

    timeout=3

    title Linux

            root (hd0,0)

            kernel /vmlinuz ro root=/dev/sda3 quiet

            initrd /initrd.gz

创建一些Linux系统所需的目录:

# cd /mn t/sysroot

# mkdir -pv ./{etc/rc.d,bin,sbin,dev,usr,home,root,lib,proc,sys,mnt,media,var,tmp,opt}

 

4、准备/etc/inittab, /etc/rc.d/rc.sysinit

 

    # cd etc/

    # vim inittab

    添加如下行:

    id:3:initdefault:

si::sysinit:/etc/rc.d/rc.sysinit

 

# vim rc.d/rc.sysinit

#!/bin/bash

#

echo -e "\tWelcome to Linux"        

 

echo "insert pcnet32 module..."

insmod /lib/modules/mii.ko           此模块是pcnet.ko所依赖的模块    

insmod /lib/modules/pcnet32.ko       模块初始化(实现加载模块)

 

ifconfig lo 127.0.0.1/8               配置IP地址

 

/bin/bash

 

    赋予执行权限:

# chmod +x rc.d/rc.sysinit        

复制模块:

# cd /mnt/sysroot

# modinfo pcnet32       查看模块pcnet32的信息,依赖于mii模块

# modinfo mii           查看模块路径信息,以便复制

# mkdir lib/modules      

# cp /lib/modules/2.6.18-164.el5/kernel/drivers/net/mii.ko  lib/modules/

# cp /lib/modules/2.6.18-164.el5/kernel/drivers/net/pcnet32.ko  lib/modules/

 

5、复制各二进制文件及库文件

 

复制文件脚本:

# cd

# vim bcp.sh

#!/bin/bash

#

function BCP {

  TARGET=/mnt/sysroot  

 

  COMMAND=`which $1 | grep -o "/.*"`

  CMDPATH=${COMMAND%/*}

 

  [ -d $TARGET$CMDPATH ] || mkdir -p $TARGET$CMDPATH

  [ -e $TARGET$COMMAND ] || cp $COMMAND $TARGET$CMDPATH

 

  for LIBFILE in `ldd $COMMAND | grep -o "/.*lib[^[:space:]]*"`; do

    LIBPATH=${LIBFILE%/*}

    [ -d $TARGET$LIBPATH ] || mkdir -p $TARGET$LIBPATH

    [ -e $TARGET$LIBFILE ] || cp $LIBFILE $TARGET$LIBPATH

  done

}

 

while true; do

  read -p "A Command: " MYCMD

  case $MYCMD in

  q|Q) 

     echo "Quit..."

     exit 0

     ;;

  *)

    ! which $MYCMD &> /dev/null && echo "Wrong command..." && continue

    BCP $MYCMD

    ;;

  esac

done

 

 

# bash -n bcp.sh           检查脚本语法是否有错误 

# bash bcp.sh             开始执行脚本,复制命令

A Command: init

A Command: bash

A Command: insmod

A Command: ifconfig

A Command: mount

A Command: umount

A Command: ping

A Command: ls

A Command: vim

A Command: hostname

A Command: halt

A Command: reboot

A Command: sync

A Command: mingetty

A Command: passwd

A Command: sleep

A Command: swapon

A Command: swapoff

A Command: grep

A Command: ftp

A Command: netstat

A Command: ps

A Command: free

A Command: sysctl

A Command: mkdir

A Command: rm

A Command: cat

A Command: ld

A Command: mv

A Command: touch

A Command: rm

A Command: cp

A Command: q

Quit...         尽量多复制几个以后能用得着的命令,省得来回切换。

 

写一个关机脚本,写之前查看syncsleep的路径:

# which sync

/bin/sync

# which sleep

/bin/sleep

编辑:

# cd /mnt/sysroot

# vim etc/rc.d/rc.sysdone

#!/bin/bash

#

sync      最好写绝对路径,这样写也可以:   /binsync

sleep 3       两者都可以                    /bin/sleep 3

sync                                       /bin/sync

 

exec /sbin/halt -p

 

赋予执行权限:

# chmod +x /mnt/sysroot/etc/rc.d/rc.sysdone

 

让关机脚本执行,编辑文件:   

# vim /mnt/sysroot/etc/inittab 

添加一行:l0:0:wait:/etc/rc.d/rc.sysdone           

 

多同步几次:

# sync

# sync

 

6、开启目标主机

    先把此虚拟机挂起,再新建虚拟机(往后称为目标主机),磁盘使用已经存在的,把这块磁盘添加上去,内存不需要太大,64M即可。系统要选Linux,桥接,其他默认即可:

制作一个小Linux_第1张图片

目标主机启动成功,也就是说,一个缩小的Linux系统制作完成,但功能并不完善,许多功能还需添加。并且复制过去的命令都可以执行。配置一个IP地址后,还可以ping通。切换回宿主机,可以继续添小Linux的功能。

7、实现虚拟终端

    挂起或关闭小Linux系统,宿主机启动起来。让小Linux系统可以启动6个虚拟终端:

编辑inittab脚本:

# vim /mnt/sysroot/etc/inittab 

添加如下行:

# Run gettys in standard runlevels

1:2345:respawn:/sbin/mingetty tty1

2:2345:respawn:/sbin/mingetty tty2

3:2345:respawn:/sbin/mingetty tty3

4:2345:respawn:/sbin/mingetty tty4

5:2345:respawn:/sbin/mingetty tty5

6:2345:respawn:/sbin/mingetty tty6

 

8、实现用户登录

    login程序依赖于PAM,而对于现在的我们来说,移植PAM相又很困难,因此,在这我们使用一种简单的方法移植login,老师为我们准备了一个不需要PAM的被简化过的login程序,将它移植到小Linux上,以实现用户登录的功能。

 

下载下来,并赋予执行权限:

# chmod +x login

 

查看login所依赖的库文件:

# ldd login 

linux-gate.so.1 =>  (0x005a4000)

libcrypt.so.1 => /lib/libcrypt.so.1 (0x03357000)

libm.so.6 => /lib/libm.so.6 (0x00786000)

libc.so.6 => /lib/libc.so.6 (0x00638000)

/lib/ld-linux.so.2 (0x00615000)

查看小Linux中的库文件,看是否包含了全部依赖库文件,若没有,复制:

# tree /mnt/sysroot/lib/

 

查看login所在路径:

# which login

/bin/login

login复制到小Linuxbin目录下:

# cp login /mnt/sysroot/bin/ 

 

    mingetty会调用login,提醒用户登录。

在宿主机的/etc/rc.d/rc.sysinit文件中,不会看到执行/bin/bash的命令,用户的shell/etc/passwd中定义,那么之前我们把/bin/bash写在小Linux中的/etc/rc.d/rc.sysinit文件中,是因为此前系统从没有用户登录过,所以此前从没有给用户定义默认shell,因此我们都是进入系统就直接执行shell,所以可以定义在/etc/rc.d/rc.sysinit文件中。

因此,用户可以登录后,就不能再在/etc/rc.d/rc.sysinit中直接运行shell

 

# vim /mnt/sysroot/etc/rc.d/rc.sysinit

将下面的/bin/bash这一行去掉

 

用户名称和密码

    对于小Linux来说,一个root用户就足够用了,因此,我们复制用户、密码和组的信息时,仅复制root用户的就可以了:

# cd /mnt/sysroot/

# head -1 /etc/passwd > /mnt/sysroot/etc/passwd

# head -1 /etc/group > /mnt/sysroot/etc/group

# head -1 /etc/shadow > /mnt/sysroot/etc/shadow

# chmod 400 etc/shadow 

 

用户登录时要依赖一些库文件:

# cd /usr/lib

# ls | grep libnss     下面的库文件并非每个都依赖,但有时候简化过程,可以都

libnss3.so           复制过去,而这些文件又都是连接文件,该如何做呢

libnssckbi.so

libnss_compat.so

libnss_db.so

libnss_dns.so

libnss_files.so

libnss_hesiod.so

libnss_ldap.so

libnss_nisplus.so

libnss_nis.so

libnssutil3.so

libnss_winbind.so

libnss_wins.so

     我们就复制几个库文件就好了,复制libnss3.solibnssckbi.solibnss_compat.solibnss_db.solibnss_dns.solibnss_files.so这几个文件,也要把这几个文件所有连接文件文件也复制过去,用cp -a ,把连接的属性也复制过去,这样就不用再手动创建连接了。

# cd /mnt/sysroot

# cp -a /usr/lib/libnss* ./usr/lib/

# cp -a /lib/libnss* ./lib/

 

编辑配置文件

# vim /mnt/sysroot/etc/nsswitch.conf 

添加如下行:

passwd:     files

shadow:     files

group:      files

hosts:      files dns

 

挂起宿主机,启动目标主机:

制作一个小Linux_第2张图片

更多功能,下篇继续完善