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