前提:
1、一个作为宿主机的Linux;这里使用的是Redhat Enterprise Linux 5.8;
2、在宿主机上提供一块额外的硬盘作为新系统的存储盘,为了降低复杂度,这里添加使用一块IDE接口的新硬盘;要记住其存储的位子
3、本文使用的是vmlinux-2.6.18-308.el5。
一、为系统上的新硬盘建立分区,这里根据需要先建立一个大小为100M的主分区作为新建系统的boot分区和一个512M的分区作为目标系统(即正在构建的新系统,后面将沿用此名称)的根分区;100M的分区格式化后将其挂载至/mnt/boot目录下;512M的分区格式化后将挂载至/mnt/sysroot目录;
- #mkdir /mnt/{boot,sysroot} //创建文件目录
- #mount /dev/hda1 /mnt/boot
- #mount /dev/hda2 /mnt/sysroot //挂载
- #mount -a //重读系统挂载
- #mount //查看下是否挂载上如图1
- #tree /mnt //图2
二、编译内核源代码,为新系统提供一个所需的内核
- #cp /boot/vmlinux-2.6.18-308.el5 /mnt/boot/vmlinuz
- #mkdir text
- #cd text
- #zcat /boot/initrd-2.6.18-308.el5.img | cpio -id
然后编辑下init程序,找到mkrootdev将其改成/dev/hda2
注:在这里需要说明,这里的init中定义装载了很多模块并且是累赘的不必要的,所以可以将其用#引用,只需要留下jbd.ko 与ext3.ko这两个模块,如图3因为这2个模块是为了内核可以加载根ext3文件系统而存在的。
而后 cd到lib/目录下,将dm模块都删掉
- #rm -f dm-*
- #cd ..
然后开始制作init
- #find . | cpio -H newc --quiet -o | gzip -g >/mnt/boot/initrd.gz
这个时候可以ls -lh查看下boot目录中是否存在这个文件。如图4
可以看出来内核,init都已经有了,那么就可以安装grub了
- #grub-install --root-directory=/mnt /dev/hda
- #ls //查看下grub文件是否存在
- #vim /mnt/boot/grub/grub.conf //编辑grub的配置文件
- default=0
- timeout=3
- title MageEdu chenyanzong's Linux
- root(hd0,0) ro root=/dev/hda2 quiet
- kernel /vlinuz
- initrd /
安装完grub然后到sysroot下创建根文件系统的所需要的目录
- #mkdir etc/{rc.d/init.d} bin sbin proc sys dev lib root mnt medir var/{log,run,lock/subsys,tmp} usr/{bin,sbin,local} tmp home opt boot -pv //其中init.d是链接指向rc.d/init.d
于是,去etc下为其创建inittab
- #vim etc/inittab
- id:3:initdefault:
- si::sysinit:/etc/rc.d
- l0:0:wait:/etc/rc.d/rc 0
- l1:1:wait:/etc/rc.d/rc 1
- l3:3:wait:/etc/rc.d/rc 3
- l6:6:wait:/etc/rc.d/rc 6
- 1:2345:respawn:/sbin/mingetty tty1
- 2:2345:respawn:/sbin/mingetty tty2
然后去创建sysinit文件
- #!/bin/bash
- #
- . /etc/rc.d/init.d/fuctions
- echo -e "\tWelcome to \033[34mMageEdu\033[0m Linux"
- echo "Remount rootfs..."
- mount -n -o remount,rw /
- [ $? -eq 0 ] && success "remount rootfs " || failure "Remount rootfs"
- mount -a
- [ $? -eq 0 ] && success "Mount others filesystem " || failure "Mount others filesystem"
- echo "Set the hostname..."
- [ -f /etc/sysconfig/network ] && . /etc/sysconfig/network
- [ -z $HOSTNAME -o "$HOSTNAME" == '(none)' ] && HOSTNAME=localhost
- /bin/hostname $HOSTNAME
- [ $? -eq 0 ] && success " Set the hostname" || failure "Set the hostname"
- echo "Initializing network device..."
- /sbin/insmod /lib/modules/mii.ko
- /sbin/insmod /lib/modules/pcnet32.ko
- [ $? -eq 0 ] && success " Initializing network device" || failure "Initializing network device"
- ifconfig lo 127.0.0.1/8
- [ $? -eq 0 ] && success " Activating loopback network device" || failure "Activating loopback network device" sysctl -p &>/dev/null
[ $? -eq 0 ] && success " Setting kernel parameter" || failure "Setting kernel parameter"
/etc/rc.d/rc脚本示例:
- #!/bin/bash
- #
- RUNLEVEL=$1
- for I in /etc/rc.d/rc$RUNLEVEL.d/K*; do
- $I stop
- done
- for I in /etc/rc.d/rc$RUNLEVEL.d/S*; do
- $I start
- done
这个时候,可以返回原目录,为这个小系统添加命令,关于这个命令的脚本本人已经编辑好了,直接贴图
- #!/bin/bash
- #
- DEST=/mnt/sysroot
- libcp() {
- LIBPATH=${1%/*}
- [ ! -d $DEST$LIBPATH ] && mkdir -p $DEST$LIBPATH
- [ ! -e $DEST${1} ] && cp $1 $DEST$LIBPATH && echo "copy lib $1 finished."
- }
- bincp() {
- CMDPATH=${1%/*}
- [ ! -d $DEST$CMDPATH ] && mkdir -p $DEST$CMDPATH
- [ ! -e $DEST${1} ] && cp $1 $DEST$CMDPATH
- for LIB in `ldd $1 | grep -o "/.*lib\(64\)\{0,1\}/[^[:space:]]\{1,\}"`; do
- libcp $LIB
- done
- }
- read -p "Your command: " CMD
- until [ $CMD == 'q' ]; do
- ! which $CMD && echo "Wrong command" && read -p "Input again:" CMD && continue
- COMMAND=` which $CMD | grep -v "^alias" | grep -o "[^[:space:]]\{1,\}"`
- bincp $COMMAND
- echo "copy $COMMAND finished."
- read -p "Continue: " CMD
- done
然后执行./bincp.sh命令进行命令的复制,命令大致如下:
init,bash,ls,touch,mkdir,rm,mv,cp,cat,mount,umount,vi,vim,chmod,ping,insmod,modprobe,sysctl,rmmod,ifconfig,route,halt,reboot,shutdown,hostname,basename,seq,stty,
然后cd到/mnt/sysroot/etc/rc.d/init.d下创建关机重启脚本halt 服务测试脚本tserver
- #vim halt
- #!/bin/bash
- #
- case $0 in
- *reboot)
- COMMAND='/sbin/reboot';;
- *halt)
- COMMAND='/sbin/halt -p ;;
- *)
- echo "Only call this csrip by *reboot OR *halt;"
- ;;
- esac
- case $1 in
- start)
- ;;
- stop)
- ;;
- *)
- echo "Usage:`basename $0` {start|stop}"
- ;;
- esac
- exec $COMMAND
- #vim tserver
- #!/bin/bash
- #
- # chkconfig: 35 66 33
- # description: test service script
- #
- . /etc/rc.d/init.d/functions
- prog=tserver
- lockfile=/var/lock/subsys/$prog
- start() {
- touch $lockfile
- [ $? -eq 0 ] && success "Starting $prog" || failure "Staring $prog"
- }
- stop() {
- rm -f $lockfile
- [ $? -eq 0 ] && success "Stopping $prog" || failure "Stopping $prog"
- }
- status() {
- if [ -f $lockfile ]; then
- echo "Running..."
- else
- echo "Stopped..."
- fi
- }
- usage() {
- echo "Usage: $prog {start|stop|status|restart}"
- }
- case $1 in
- start)
- start ;;
- stop)
- stop ;;
- restart)
- stop
- start
- ;;
- status)
- status
- ;;
- *)
- usage
- exit 1
- ;;
- esac
#chmod +x init.d/tserver
然后测试下这个脚本,
然后cd到/mnt/sysroot/etc/rc.d下创建rc0.d rc1.d rc6.d rc3.d
然后依次cd到各个目录下为其创建连接文件
- #cd ../rc0.d/
- #ln -sv ../init.d/halt S99halt
- #cd ../rc6.d/
- #ln -sv ../init.d/halt S99reboot
- #cd rc3.d/
- #ln -sv ../init.d/tserver S66tserver
- #cd ../rc0.d/
- #ln -sv ../init.d/tserver K33tserver
- #cd ../rc6.d/
- #ln -sv ../init.d/tserver K33tserver
设定开机挂载项
- /dev/hda2 / ext3 defaults 0 0
- /dev/hda1 /boot ext3 defaults 0 0
- proc /proc proc defaults 0 0
- sysfs /sys sysfs defaults 0 0
注:此处完成后需要到sysinit中添加开机读写挂载根文件系统
设定主机名:
- #mkdir etc/sysconfig/network
- HOSTNAME=minilinux.magedu.com
注:此处完成后需要到sysinit中添加设置主机名
开机启动服务时,显示绿色ok或者红色fauled时的操作.可用于控制服务脚本的信息显示
#cd /mnt/sysroot/
#vim etc/rc.d/init.d/functions
- #!/bin/bash
- SCREEN=`stty -F /dev/console size 2>/dev/null`
- COLUMNS=${SCREEN#* }
- [ -z $COLUMNS ] && COLUMNS=80
- SPA_COL=$[$COLUMNS-14]
- RED='\033[31m'
- GREEN='\033[32m'
- YELLOW='\033[33m'
- BLUE='\033\34m'
- NORMAL='\033[0m'
- success() {
- string=$1
- RT_SPA=$[$SPA_COL-${#string}]
- echo -n "$string"
- for I in `seq 1 $RT_SPA`;do
- echo -n " "
- done
- echo -e "[ ${GREEN}OK${NORMAL} ]"
- }
- failure() {
- string=$1
- RT_SPA=$[$SPA_COL-${#string}]
- echo -n "$string"
- for I in `seq 1 $RT_SPA`;do
- echo -n " "
- done
- echo -e "[ ${RED}FAILED${NORMAL} ]"
- }
注:创建完成后需要在etc/rc.d/init.d/tservrt中用 . /etc/rc.d/init.d/functions 调用此脚本
装载网卡驱动,设置IP地址:
- #mkdir lib/modules
- #modinfo pcnet32 查看其目录与其依赖模块(可发现mii与其依赖)如图yilai
- ...省略
- #cp /lib/modules/2.6.18-308.el5/kernel/drivers/net/pcnet32.ko /mnt/sysroot/lib/modules/
- #modinfo mii
- ...省略
- #cp /lib/modules/2.6.18-308.el5/kernel/drivers/net/pcnet32.ko /mnt/sysroot/lib/modules/
注:完成后在sysinit中装载此模块
然后配置文件network
#chmod +x etc/rc.d/init.d/network
- #mkdir -pv etc/sysconfig/network-scripts
- #vim etc/sysconfig/network-scripts/ifcfg-th0
- DEVICE=eth0
- BOOTPROTO=static
- PDADDR=172.16.100.5
- NETMASK=255.255.0.0
- GATEWAY=172.16.0.1
- ONBOOT=yes
- #vim etc/rc.d/init.d/network
- #!/bin/bash
- #
- # chkconfig: 35 09 90
- # description: network service
- $prog=network
- . /etc/rc.d/init.d/functions
- CONF=/etc/sysconfig/network-scripts/ifcfg-th0
- .$CONF
- NETMASK=16
- start(){
- ifconfig eht0 $IPAPPR/$NETMASK up
- [-z #GATEWAY ] && route add default gw $GATEWAY
- }
- stop(){
- ifconfig eth0down
- }
- status(){
- ifconfig eth0
- }
- usage(){
- echo "$prog :{start|stop|status}"
- }
- case $1 in
- start
- success "Config network eth0"
- ;;
- stop)
- stop
- success "Stop network eth0"
- ;;
- restart)
- stop
- start
- success "Restart network eth0"
- ;;
- *)
- usage
- exit 1
- ;;
然后依次cd到各个目录下为其创建连接文件
- #cd rc3.d/
- #ln -sv ../init.d/network S09network
- #cd ../rc0.d/
- #ln -sv ../init.d/network K90network
- #cd ../rc6.d/
- #ln -sv ../init.d/network K90network
用户
由于用户依赖于PAM,但是PAM太过麻烦,此处略过PAM
事先准备了1个login文件,只通过复制简单的文件来实行用户登录
- /etc/passwd,/etc/shadow,/etc/group
- #cp -d /usr/lib/libnss_files.so /mnt/sysroot/usr/lib
- #cp -d /usr/lib/libnss3.so /mnt/sysroot/usr/lib
- #cp -d /usr/lib/libnssckbi.so /mnt/sysroot/usr/lib
- #cp -d /usr/lib/libnssutil3.so /mnt/sysroot/usr/lib
vim /mnt/sysroot/etc/nsswitch.conf (此文件为login与用户资料存放文件的中间层,起桥接作用,本文件可适应多种存储文件,此处用于files文件)
可将其里面的内容只保留四行
- passwd: files
- shadouw: files
- group: files
- hosts: files dns
然后复制用户过去
- grep -E "^(root|hadoop)\>" /etc/passwd >/mnt/sysroot/etc/passwd
- grep -E "^(root|hadoop)\>" /etc/shadow>/mnt/sysroot/etc/shadow
- grep -E "^(root|hadoop)\>" /etc/group>/mnt/sysroot/etc/group
然后lftp 172.16.0.1
cd pub/
get login
...
bye
chmod +x login
然后cd /root
- #vim .bash_profile
- PA1=`[\u@\h \W]\$`
- export PS1
然后设置到此,登录时便会提示这样
单用户模式(因为其为1级别启动)
首先,cd /mnt/sysroot中去。
vim etc/inittab中去定义1级别
加入l1:1:wait:/etc/rc.d/rc
然后 cd到rc.d/
- #mkdir rc1.d
- #cd rc1.d/
- #ln -sv ../init.d/network K90network
- #ln -sv ../init.d/tserver K33network
然后设定单用户模式
- #vim rc.d/init.d/single
- #!/bin/bash
- #
- # chkconfig:
- # description:
- #
- case $1 in
- start)
- ;;
- *)
- echo "usage :single start"
- ;;
- esac
- exec /sbin/init S
- #chmod +x rc.d/init.d/single
- #cd rc.d/rc1.d/
- #ln -sv ../init.d/single S99single
用户列表按e e 然后添加 S 然后 b引导
由于操作IDE磁盘是在别的宿主机上完成,所以可能导致在新建虚拟机装载系统时出现磁盘未写好的情况导致系统崩溃,具体解决可参考下面步骤。
- #cd /mnt/sysroot
- #find . | cpio -H newc --quiet -o | gzip > /root/sysroot.gz
- #fuser -km /dev/hda2
- #umount /dev/hda2
- #mke2fs -j /dev/hda2
- #mount /dev/hda2 /mnt/sysroot
- #cd /mnt/sysroot/
- #zcat /root/sysroot.gz | cpio
- #ls