爲什麼要自己編譯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