手动编译制作微小linux+nginx

为什么要自己编译linux呢?

    因为可以更高效的利用系统资源,把应用使用中没有必要加载的模块可以去掉,以使系统运行更加流畅。编译时可以根据硬件的芯片的不同做出一定的修改、匹配,使能更加稳定的运行。也就是为硬件定制了一套特有的操作系统。

下面的操作仅供参考,

机器型号:(虚拟机上编译)

processor    : 0    
vendor_id    : GenuineIntel      
cpu family    : 6      
model        : 37      
model name    : Intel(R) Core(TM) i3 CPU       M 380  @ 2.53GHz      
stepping    : 5      
microcode    : 0x2      
cpu MHz        : 2525.993      
cache size    : 3072 KB      
physical id    : 0

 

说明:(由于编译时截图太多没有在这里体现,图片在我的相册中有,大家可以参考)  
-----------------------------------------------------------------------------------------   

实例:手动编译内核,    
    1、下载安装包并解压    
        内核包linux-3.13.6.tar.xz    
        #tar xf linux-3.13.6.tar.xz -C /usr/src    
        # cd /usr/src    
        # ln -sv linux-3.13.6/ linux    
        # cd linux    
        # make allnoconfig    
        # make menuconfig(有截图) 
        # make -j 3    
        Kernel: arch/x86/boot/bzImage is ready  (#1)(编译完成后,指明的kernel的存放位置)    
        # cp  arch/x86/boot/bzImage /mnt/boot/(复制编译最后一样kernel到/mnt/boot/)    
        # sync    
    2、分区格式划磁盘(新添加磁盘)    
        # fdisk /dev/sdb (sdb1 50M;sdb2 512M)    
        # mke2fs -t ext4 /dev/sdb1    
        # mke2fs -t ext4 /dev/sdb2    
        # mkdir /mnt/{boot,sysroot}    
        # mount /dev/sdb1 /mnt/boot    
        # mount /dev/sdb2 /mnt/sysroot    
        # grub-install --root-directory=/mnt /dev/sdb    
        # vim /mnt/boot/grub/grub.conf

            timeout=5    
            default=0    
            title Customed Linux (3.13.8)    
                    root (hd0,0)    
                    kernel /bzImage ro root=/dev/sda2 init=/sbin/init    
        # cd /mnt/sysroot    
        # mkdir -pv proc sys dev tmp etc/init.d var usr mnt media home root boot sbin    
        # vim /mnt/sysroot/sbin/init

            #!/bin/bash    
            #    
            echo -e "Welcome to \033[34mCustomed\033[0m Linux"    
            mount -n -t proc proc /proc    
            mount -n -t sysfs sysfs /sys    
            mount -n -t devtmpfs none /dev    
            mount -n -o remount,rw /dev/sda2 /    
            /bin/bash    
        # chmod +x /mnt/sysroot/sbin/init    
        # bash -n /mnt/sysroot/sbin/init    
        # bash 1.sh    
            Plz enter a command: bash    
            Plz enter a command: mount    
            Plz enter a command: umount    
            Plz enter a command: ls    
            Plz enter a command: ps    
            Plz enter a command: kill    
            Plz enter a command: cat    
            Plz enter a command: quit    
        #sync    
        # chroot /mnt/sysroot(测试下)    
            bash-4.1# ls    
            bin  boot  dev    etc  home  lib64  lost+found  media  mnt  proc    root  sbin  sys  tmp  usr  var    
            bash-4.1# exit    
            exit

    把硬盘挂载新建虚拟机上启用,能正常启动!

    
    3、完善功能添加网络功能    
        # cd /usr/src/linux    
        # make menuconfig(有截图)    
        # make -j 3    
        Kernel: arch/x86/boot/bzImage is ready  (#2)    
        # cp arch/x86/boot/bzImage /mnt/boot/(编译完成后复制kernel覆盖原文件)    
        cp: overwrite `/mnt/boot/bzImage‘? y    
        # sync    
        # bash 1.sh (复制一些网络功能的命令)    
        Plz enter a command: ifconfig    
        Plz enter a command: route    
        Plz enter a command: netstat    
        Plz enter a command: ping    
        Plz enter a command: quit    
        # sync    
        挂起再次测试:    
        #export PATH=/bin:/sbin:/usr/bin:/usr/sbin    
        #ifconfig -a (有图)

   
    4、完善目标机器的命令功能装入busybox    
        软件包:busybox-1.22.1.tar.bz2(或者从网站下载www.busybox.net)    
            静态编译busybox    
            # tar xf busybox-1.22.1.tar.bz2    
            # cd busybox-1.22.1    
            # yum install glibc-static(编译需要这个包)    
            # make menuconfig(有图)    
            # make    
            # make install    
                # cd /mnt/sysroot(把这目录下的所有文件移走到,/tmp/sysroot下,也可以删除)    
                # mkdir /tmp/sysroot    
                # mv * /tmp/sysroot

            # ls /root/busybox-1.22.1/_install/    
                bin  linuxrc  sbin  usr    
            # cd /root/busybox-1.22.1/_install/    
            # cp -a * /mnt/sysroot/    
            # cd /mnt/sysroot/    
            # rm -rf linuxrc    
            # mkdir proc sys dev htom boot tmp var lib64 mnt meida root etc    
            # chroot /mnt/sysroot /bin/ash(本地测试启动下)    
                / #    
                / #    
                / # exit    
            # cd /mnt/sysroot/etc    
            # vim inittab(只提供物理控制台的inittab)    
                ::sysinit:/etc/rc.d/rc.sysinit    
                console::respawn:-/bin/sh    
                ::ctrlaltdel:/sbin/reboot    
                ::shutdown:/bin/umount -a -r    
            # vim fstab

                /dev/sda2       /       ext4    defaults        0 0    
                /dev/sda1       /boot   ext4    defaults        0 0    
                proc            /proc   proc    defaults        0 0    
                sysfs           /sys    sysfs   defaults        0 0    
            # mkdir /mnt/sysroot/etc/rc.d    
            # vim rc.d/rc.d/rc.sysinit

                #!/bin/sh    
                #    
                echo -e "Welcome to \033[34mCustomed\033[0m Linux"    
                echo "Remouting root filesystem"    
                mount -n -o remount,rw /dev/sda2 /    
            # chmod +x rc.d/rc.sysinit    
            挂载测试下busybox是否安装成功(有图有真相)

   
    5、完善系统用户登入功能    
        (1)提供虚拟控制台的inittab    
            # vim /mnt/sysroot/etc/inittab

                ::sysinit:/etc/rc.d/rc.sysinit    
                tty1::askfirst:/bin/sh(添加6个终端)    
                tty2::askfirst:/bin/sh    
                tty3::askfirst:/bin/sh    
                tty4::askfirst:/bin/sh    
                tty5::askfirst:/bin/sh    
                tty6::askfirst:/bin/sh    
                ::ctrlaltdel:/sbin/reboot    
                ::shutdown:/bin/umount -a -r    
            挂载测试下即可    
        (2)提供用户登录界面的inittab    
            # vim /mnt/sysroot/etc/inittab

            ::sysinit:/etc/rc.d/rc.sysinit    
            ::respawn:/sbin/getty 19200 tty1    
            ::respawn:/sbin/getty 19200 tty2    
            ::respawn:/sbin/getty 19200 tty3    
            ::respawn:/sbin/getty 19200 tty4    
            ::respawn:/sbin/getty 19200 tty5    
            ::respawn:/sbin/getty 19200 tty6    
            ::ctrlaltdel:/sbin/reboot    
            ::shutdown:/bin/umount -a -r    
            # vim /mnt/sysroot/etc/passwd(添加账户)

            root:x:0:0::/root:/bin/bash    
            ning:x:500:500::/home/ning:/bin/bash    
            # openssl passwd -1 -salt `openssl rand -hex 4`(生成MD5加密的密码)    
                Password:    
                $1$0eced7a5$4rE13xB7lWb4bgd.I1ijt.    
            # vim /mnt/sysroot/etc/shadow(添加帐号密码)

                root:$1$0eced7a5$4rE13xB7lWb4bgd.I1ijt:16259:0:99999:7:::    
                ning:$1$0eced7a5$4rE13xB7lWb4bgd.I1ijt:16259:0:99999:7:::    
            # vim /mnt/sysroot/etc/group(添加组)

                root:x:0:    
                ning:x:500:    
            # mkdir /mnt/sysroot/home/ning -pv(创建用户目录)    
                #cd    
                #bash 1.sh(移植下bash)    
                    Plz enter a command: bash    
                    Plz enter a command: quit    
            # vim /mnt/sysroot/etc/profile(添加bash显示头)

                export PS1=‘[\u@\h \W]\$‘    
            # vim rc.d/rc.d/rc.sysinit(修改启动脚本)

                #!/bin/sh    
                #    
                echo -e "Welcome to \033[34mCustomed\033[0m Linux"    
                echo "Remouting root filesystem"    
                mount -n -o remount,rw /dev/sda2 /    
                echo "mount all filesystem"(添加下面几行)    
                mount -a    
                echo "create device file"    
                mdev -s    
            #poweroff    
            测试用户登入密码结果(有图)

 


        (3)完善用户登入主机名    
            # mkdir /mnt/sysroot/etc/sysconfig    
            # vim /mnt/sysroot/etc/sysconfig/network

                HOSTNAME=ninghongliang    
            # vim /mnt/sysroot/etc/rc.d/rc.sysinit

                #!/bin/sh    
                #    
                echo -e "Welcome to \033[34mCustomed\033[0m Linux"    
                echo "Remouting root filesystem"    
                mount -n -o remount,rw /dev/sda2 /    
                echo "mount all filesystem"    
                mount -a    
                echo "create device file"    
                mdev -s    
                [ -r /etc/sysconfig/network ] && source /etc/sysconfig/network    
                [ -z "$HOSTNAME" -o "$HOSTNAME" == ‘(none)‘ ] &&  hostname localhost || hostname $HOSTNAME    
            # cp -a -d /lib64/libnss_files* /mnt/sysroot/lib64/(nsswitch名称解析框架,复制这些库)    
            # mkdir /mnt/sysroot/usr/lib64    
            #cp -a -d /usr/lib64/libnss_files.so /mnt/sysroot/usr/lib64/    
            #cp -a -d /usr/lib64/libnss3.so /mnt/sysroot/usr/lib64/    
            #cp -a -d /usr/lib64/libnsspem.som /mnt/sysroot/usr/lib64/    
            #cp -a -d /usr/lib64/libnsssysinit.so /mnt/sysroot/usr/lib64/    
            #cp -a -d /usr/lib64/libnssutil3.so /mnt/sysroot/usr/lib64/    
            # cp /etc/nsswitch.conf /mnt/sysroot/etc/    
            # vim /mnt/sysroot/etc/nsswitch.conf(无需太大改动,,删除hosts后面的内容就可以)

            测试主机名是否完整(有图有真相)

   
        6、远程登录dropbear的编译(通过宿主机编程完成之后,复制到目标磁盘即可)    
             dropbear-2013.58.tar.bz2    
             # tar xf dropbear-2013.58.tar.bz2    
             # cd dropbear-2.13.58    
             # ./configure    
             # make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp"    
             # make PROGRAMS="dropbear dbclient dropbearkey dropbearconvert scp" install    
                    # ls /usr/local/bin(默认编辑不指定目录,默认安装的位置)    
                    dbclient  dropbearconvert  dropbearkey  scp(生成了这四个程序)    
             #mkdir /etc/dropbear(创建存放密钥的文件)    
             # dropbearkey -t dss -f /etc/dropbear/dropbear_dss_host_key    
             # dropbearkey -t rsa -s 2048 -f /etc/dropbear/dropbear_rsa_host_key    
             # ls /etc/dropbear(查看下生成的结果一般这两个文件的权限是不允许别人查看的)    
                dropbear_dss_host_key  dropbear_rsa_host_key    
             # /usr/local/sbin/dropbear -p 22022(编译完成后我们启动下,,因为主机上22号端口被sshd占用了,,所以我们指定个端口启用)    
                这里我们需要在宿主机上测试下是否能正常使用,    
                ssh [email protected] 22022(查看下树pstree)    
            移植dropbear    
            # cd /root    
            # bash 1.sh    
                Plz enter a command: dropbear    
                Plz enter a command: dropberkey    
                Plz enter a command: dbclient    
                Plz enter a command: quit 
            # ldd /usr/local/bin/scp (这里说明下,由于是编译安装,宿主机上有两个的scp,我们需要移植的是编程生成的。)    
                linux-vdso.so.1 =>  (0x00007fff2aedf000)    
                libc.so.6 => /lib64/libc.so.6 (0x00000039dc000000)    
                /lib64/ld-linux-x86-64.so.2 (0x00000039db800000)    
            # cp -a -d /usr/local/bin/scp /mnt/sysroot/usr/local/bin/ (这里只需要移植命令即可,库文件box里面有)    
            这里我们要给目标主机创建密钥文件(我们这里是在宿主机上执行,也可以把磁盘挂在目标主机下,执行也可以。)    
            # mkdir /mnt/sysroot/etc/dropbear    
            # dropbearkey -t dss -f /mnt/sysroot/etc/dropbear/dropbear_dss_host_key    
            # dropbearkey -t rsa -s 2048 -f /mnt/sysroot/etc/dropbear/dropbear_rsa_host_key    
            # mkdir /mnt/sysroot/var/run(提供pid文件存放目录)    
            # vim /mnt/sysroot/etc/shells(因为dropbear启动时会检查安全shell,我们这里提供下)

                /bin/sh    
                /bin/bash    
                /bin/ash    
                /bin/hush    
                /sbin/nologin    
                我们还需要提供个tty虚拟中断系统    
                    # cat /etc/fstab(我们可以查看下宿主机上的,,文件挂载系统中有下面一项,)    
                        devpts                  /dev/pts                devpts  gid=5,mode=620  0 0    
                虚拟也需要添加目录    
            # vim /mnt/sysroot/etc/fstab

                /dev/sda2       /       ext4    defaults        0 0    
                /dev/sda1       /boot   ext4    defaults        0 0    
                proc            /proc   proc    defaults        0 0    
                sysfs           /sys    sysfs   defaults        0 0    
                devpts          /dev/pts        devpts  defaults        0 0    
            # vim etc/rc.d/rc.sysinit

                #!/bin/sh    
                #    
                echo -e "Welcome to \033[34mCustomed\033[0m Linux"    
                echo "Remouting root filesystem"    
                mount -n -o remount,rw /dev/sda2 /    
                echo "create device file"    
                mdev -s

                echo "mount all filesystem"    
                mkdir /dev/pts(由于devpts是挂载在内核的,所以每次开机都需要创建,这一条需要添加在挂载系统之前)    
                mount -a

                [ -r /etc/sysconfig/network ] && source /etc/sysconfig/network    
                [ -z "$HOSTNAME" -o "$HOSTNAME" == ‘(none)‘ ] &&  hostname localhost || hostname $HOSTNAME

                ifconfig lo 127.0.0.1 netmask 255.0.0.0(网络IP地址可以在/etc/创建个脚本专门来配置IP,source那个脚本在这里就可以了。)    
                ifconfig eth0 192.168.1.88 netmask 255.255.255.0    
            测试下远程虚拟用户的登录(有图有真相)    
                #/usr/local/sbin/dropbear (由于没有在frofile中添加,,路径)    

        7、    提供dropbear服务启动脚本

            # vim /etc/init.d/dropbear(我们这里是在宿主机上做的,需要再复制到目标主机)    
            #!/bin/bash    
            #    
            dbprog=‘/usr/local/sbin/dropbear‘    
            dbkeygen=‘/usr/local/bin/dropbearkey‘    
            dsskey=‘/etc/dropbear/dropbear_dss_host_key‘    
            rsakey=‘/etc/dropbear/dropbear_rsa_host_key‘    
            rsakeysize=2048    
            dbport=22

            gendsskey() {    
                if [ ! -f $dsskey ]; then    
                    echo "Generating dss key file."    
                    [ -d /etc/dropbear ] || mkdir /etc/dropbear 
                    $dbkeygen -t dss -f $dsskey    
                fi   
            }    
            genrsakey() {    
                if [ ! -f $rsakey ]; then    
                    echo "Generating rsa key file."    
                    [ -d /etc/dropbear ] || mkdir /etc/dropbear 
                    $dbkeygen -t rsa -s $rsakeysize -f $rsakey    
                fi   
            }

            start () {    
                gendsskey    
                genrsakey    
                if ! pidof dropbear &> /dev/null; then    
                echo "Starting dropbear"    
                    $dbprog -p $dbport    
                    retval=$?    
                else    
                    echo "$dbprog is already runing..."    
                        return 1    
                fi

                if [ $retval -eq 0 ]; then    
                    echo "start....OK"    
                    return 0    
                else    
                    echo "Failure"    
                    return 1    
                fi     
            }

            stop () {    
                echo "Stop dropbear"    
                if pidof dropbear &> /dev/null ; then    
                    echo "stopping dropbear"    
                    killall dropbear    
                    retval=$?    
                else    
                    echo "dropbear is not running..."    
                    return 1    
                fi    
            }

            restart () {

                    stop    
                    sleep 1    
                    start    
            }    
            usage() {    
                echo "Usage: `basename $0` {start|stop|restart}"    
            }    
            case $1 in

            start)    
                start    
                ;;    
            stop)    
                stop    
                ;;    
            restart)    
                restart    
                ;;    
            *)    
                usage    
                ;;    
            esac   
            # chmod +x     /etc/init.d/dropbear    
            # mkdir /mnt/sysroot/etc/init.d(给目标主机创建目录)    
            # cp /etc/init.d/dropbear /mnt/sysroot/etc/init.d(复制到目标主机上)

            下面设置脚本开机启动    
            # mkdir /mnt/sysroot/etc/rc.start    
            # mkdir /mnt/sysroot/etc/rc.stop    
            # cd /mnt/sysroot/etc/rc.start    
            # ln -sv ../init.d/dropbear 01dropbear    
            # cd /mnt/sysroot/etc/rc.stop    
            # ln -sv ../init.d/dropbear 02dropbear    
            # vim /mnt/sysroot/etc/rc.d/rc.sysinit (最后添加以下内容)    
                for i in /etc/rc.start/*; do    
                $i start    
                done    
            下面设置脚本关机关闭脚本    
            # vim /mnt/sysroot/etc/rc.d/rc.sysdown(关闭的时候是先关闭服务,再关闭启动其他挂载)

                #!/bin/bash    
                #    
                for i in /etc/rc.stop/*; do    
                        $i stop    
                done    
                umount -a -r    
                sleep1    
                poweroff    
            # chmod +x /mnt/sysroot/etc/rc.d/rc.sysdown    
            # vim inittab    
                ::sysinit:/etc/rc.d/rc.sysinit    
                ::respawn:/sbin/getty 19200 tty1    
                ::respawn:/sbin/getty 19200 tty2    
                ::respawn:/sbin/getty 19200 tty3    
                ::respawn:/sbin/getty 19200 tty4    
                ::respawn:/sbin/getty 19200 tty5    
                ::respawn:/sbin/getty 19200 tty6    
                ::ctrlaltdel:/sbin/reboot    
                ::shutdown:/etc/rc.d/rc.sysdown(把这个地方得目录换成现在这个样子)关机加载那个脚本    
            测试开关机自启动(有图有真相)

   
        8、安装nginx提供web服务(我们这里在宿主机上编译安装,并移植到目标主机)    
             # tar xf nginx-1.4.7.tar.gz    
             # cd nginx-1.4.7    
             # useradd nginx    
             #./configure --user=nginx --group=nginx --conf-path=/etc/nginx/nginx.conf --without-pcre --without-http_rewrite_module    
             # make && make install    
             测试下能不能正常启动    
                 #/usr/local/nginx/sbin/nginx    
http://192.168.1.109/    
             移植nginx    
            # cd /root/    
            # bash 1.sh(移植)    
                Plz enter a command: /usr/local/nginx/sbin/nginx    
                Plz enter a command: quit    
            # vim /mnt/sysroot/etc/passwd(如果在宿主机上,,添加了还是不能识别,就去目标机上添加即可)    
                nginx:x501:501:::/home/nginx:/bin/ba    
            # vim /mnt/sysroot/etc/group    
                nginx:x:501:    
            # vim /mnt/sysroot/etc/shadow    
                nginx:$1$2aff1663$JQgmh9Uxuy3SaaL8CBpbA.:16259:0:99999:7:::    
            # vim /mnt/sysroot/etc/profile

            export PS1=‘[\u@\h \W]\$‘    
            export PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:/usr/local/nginx/bin:/usr/local/nginx/sbin    
                把磁盘挂载到目标机启动#nginx    
            测试:(测试的时候我们这里就和宿主机分离了。。开始单独运行)    
                首先:测试下用户是否存在#id nginx    
                出现了下面错误不能正常启动(因为我们内核没有编译支持套接字模块Unix domain sockets)(所以我们得重新编译下内核,复制过来即可)    
                #tail /usr/local/nginx/logs/error.log    
                2014/08/24 03:05:49 [alert] 255#0: socketpair() failed while spawning "worker process" (97: Address family not supported by protocol)    
                下面是在我们宿主机上重新编译下复制过来:    
                    # cd /usr/src/linux    
                    # make menuconfig(有截图)    
                    # make -j 4 bzImage    
                下面是我们从客户机器上操作    
                    #ln -sv /usr/local/bin/dbclient /usr/bin(由于我们编译安装的dropbear,程序的默认路径为/usr/local/bin/dbclient,busybox的命令默认路径在/usr/bin下去找)    
                    # scp [email protected]:/tmp/bzImage /root/(这里我们先放到家目录下)    
                    测试    
http://192.168.1.88(有图有真相)

   
                做下压力测试;目标主机:#watch -n10 ‘free -m‘    
                              宿主机:#ab -c 1000 -n 100000 http://192.168.1.88/index.html


            至此我们这个编译告一段落!!还缺少个nginx的服务启动脚本。后续跟上


常识:如果在虚拟机做的是有出现了同步数据出现了问题,或者有信息丢失的情况,可以用以下命令操作格式化目标主机磁盘。(最好不要操作的太快,就不会出现这样的问题)       
        #find . | cpio -o -H newc --quiet | gzip -9 -n > /root/sysroot.2.gz    
        #umount /mnt/sysroot    
        #mke2fs -t ext4 /dev/sdb2    
        #mount /dev/sdb2 /mnt/sysroot    
        #gzip -d sysroot.2.gz    
        #cd /mnt/sysroot    
        #cpio -i < /root/sysroot.2    
我们这里提供一个上面用到的移植脚本    
复制命令脚本1.sh脚本    
#!/bin/bash    
#    
target=/mnt/sysroot/

[ -d $target ] || mkdir $target

preCommand() {    
    if which $1 &> /dev/null; then    
    commandPath=`which --skip-alias $1`    
    return 0    
    else    
    echo "No such command."    
    return 1    
    fi    
}

commandCopy() {    
    commandDir=`dirname $1`    
    [ -d ${target}${commandDir} ] || mkdir -p ${target}${commandDir}    
    [ -f ${target}${commandPath} ] || cp $1 ${target}${commandDir}    
}

libCopy() {    
    for lib in `ldd $1 | egrep -o "/[^[:space:]]+"`; do    
    libDir=`dirname $lib`    
    [ -d ${target}${libDir} ] || mkdir -p ${target}${libDir}    
    [ -f ${target}${lib} ] || cp $lib ${target}${libDir}    
    done    
}

read -p "Plz enter a command: " command

until [ "$command" == ‘quit‘ ]; do

  if preCommand $command &> /dev/null; then    
    commandCopy $commandPath    
    libCopy $commandPath    
  fi

  read -p "Plz enter a command: " command    
done

本文出自 “奋斗的人” 博客,请务必保留此出处http://wodemeng.blog.51cto.com/1384120/1543955

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。