2012-09-10
在博文“Linux系统启动过程分析”中咱们了解了linux系统的启动流程,今天咱们就来手动一步一步从头来构建一个最小的linux系统,而后用模拟器将其加载起来。常见的模拟器有Qemu、Bochs、VMWare、VPC、Virtual Box和Xen等,以及特殊的模拟UML(User-Mode-Linux),这里咱们选择用VMWare。
咱们制做的Linux系统有shell功能,支持Web Server,telnet等服务,以及ifconfig,vi等常见工具。准备工做:
在http://www.kernel.org/ 下载内核源代码 linux-2.6.21.tar.bz2;
在http://www.busybox.org/ 下载busybox源码 busybox-1.14.4.tar.bz2。
在本地新建一个目录,例如/home/DIY,固然你能够随便选择,而后将下载的内核源码和busybox源码包拷贝到/home/DIY目录下;
A)、构造根文件系统
咱们都知道标准的发行版linux其目录结构通常是以下这个样子:
咱们制做的linux运行起来以后固然也应该有个相似的目录结构。这里咱们只选择一些必须的目录,由于咱们构建的是“最小”的Linux系统。
在/home/DIY目录下依次执行以下命令:
在rootfs/etc目录下分别创建以下各个文件group、inittab、profile、protocols、
rcS和services:
点击(此处)折叠或打开
###################### /etc/group ###################### from here
root:x:0:
ftp:x:800:
nogroup:x:65534:
######################/etc/inittab ###################### from here
::sysinit:/etc/rcS
tty1::askfirst:-/bin/sh --login
tty2::askfirst:-/bin/sh --login
tty3::askfirst:-/bin/sh --login
######################/etc/profile ###################### from here
#!/bin/sh
cat <<EOF
Welcome to DIY
EOF
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
######################/etc/protocols ###################### from here
# Internet (IP) protocols
#
ip 0 IP
icmp 1 ICMP
igmp 2 IGMP
ggp 3 GGP
ipencap 4 IP-ENCAP
st 5 ST
tcp 6 TCP
egp 8 EGP
igp 9 IGP
pup 12 PUP
udp 17 UDP
hmp 20 HMP
xns-idp 22 XNS-IDP
rdp 27 RDP
iso-tp4 29 ISO-TP4
xtp 36 XTP
ddp 37 DDP
idpr-cmtp 38 IDPR-CMTP
idrp 45 IDRP
rsvp 46 RSVP
gre 47 GRE
esp 50 IPSEC-ESP
ah 51 IPSEC-AH
skip 57 SKIP
rspf 73 RSPF CPHB
vmtp 81 VMTP
eigrp 88 EIGRP
ospf 89 OSPFIGP
ax.25 93 AX.25
ipip 94 IPIP
etherip 97 ETHERIP
encap 98 ENCAP
pim 103 PIM
ipcomp 108 IPCOMP
vrrp 112 VRRP
l2tp 115 L2TP
isis 124 ISIS
sctp 132 SCTP
fc 133 FC
######################/etc/rcS ###################### from here
#!/bin/sh
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
mount -t proc none /proc
mount -t sysfs none /sys
mount -t tmpfs tmpfs /dev -o size=512K,mode=0755
echo DIY > /proc/sys/kernel/hostname
mkdir -p /var/run /var/log /var/lock /var/state \
/var/tmp /var/mnt /dev/pts /dev/shm
mount devpts /dev/pts -t devpts
echo /bin/mdev > /proc/sys/kernel/hotplug
mdev -s
ifconfig lo 127.0.0.1 up
ifconfig eth0 192.168.1.1 netmask 255.255.255.0 up
telnetd -l /bin/sh
httpd -h /www
###################/etc/services ################# from here
ssh 22/tcp
ssh 22/udp
telnet 23/tcp
telnet 23/udp
http 80/tcp www www-http
http 80/udp www www-http
login 513/tcp
shell 514/tcp cmd
再在rootfs/www目录下创建一个index.html文件,内容以下:
点击(此处)折叠或打开
<h1>Success!</h1>
<p>Welcome to DIY linux!</p>
最后rootfs目录的组织结构以下:
其余的命令行工具由接下来的busybox生成。
B)、编译busybox
在Linux系统中经常使用的工具,如 bash、grep命令、sed 命令、telnetd等,这里为了方便省事,我就用busybox来代替了。如今的busybox拥有很是多的工具,真正成为一个“Busy”的box。后面的例子将尝试只使用 busybox来充当全部应用层所须要的工具集。包括Shell,网络配置,web服务器,telnet等。而busybox也由此获得一个称号“嵌入式世界的瑞士军刀”。
将修改后的“ busybox.config.txt ”复制到busybox-1.14.4目录下重命名为“.config”,注意文件名前面的点“.”绝对不能省略。
以后弹出以下界面:
在配置界面下,咱们依次选择:Busybox Settings => Build Options 而后选中(按空格键),这里咱们将编译生成静态库的busybox,以下图中所示选项:
配置busybox的安装目录,依次选择:Busybox Settings => Installation Options ,以下:
保存配置后执行编译命令make:
编译完成后执行make install:
这样咱们编译的busybox工具就安装到前面咱们建立的rootfs目录中了,此时rootfs目录下的组织结构就变成了以下这个样子:
无论是bin,sbin,usr/bin仍是usr/sbin目录下的命令都是到/bin/busybox应用程序的软链接。目前rootfs这个目录结构和咱们常见的linux发行版的目录结构仍是有些差别,因此咱们继续往rootfs中增长dev,proc,tmp,var,lib,root和sys目录:
这样子就更像一个“标准”linux发行版的样子了。接下来咱们来制做一个ramdisk的初始化文件,名为initrd。Linux内置支持以RAM磁盘的形式来启动。关于Linux系统的启动流程请参见博文“Linux系统启动过程分析”里的详细描述。
C)、制做initrd文件
D)、编译Linux内核源码
解压内核源码,而后将我修改后的内核配置文件“ linux.config.txt ”拷贝到linux-2.6.21目录下,重命名为“.config”,以下:
执行make menuconfig能够查看哪些配置项已经被选上:
执行make命令开始编译内核:
咱们提供的内核配置文件linux.conf将模块已经静态编译到内核中去了,这样就会形成内核比较大,若是是采用动态加载模块的话,须要将全部模块安装到前面制做的ramdisk里。编译好的内核镜像,通常位于:
<!--[if !supportLists]-->? <!--[endif]-->对于x86平台,压缩后的核心是 arch/x86/boot/bzImage;
<!--[if !supportLists]-->? <!--[endif]-->对于MIPS平台,压缩后的核心是 arch/powerpc/boot/zImage;
<!--[if !supportLists]-->? <!--[endif]-->对于arm平台,压缩后的核心是 arch/arm/boot/zImage
……
E)、用VMWare加载内核
将arch/x86/boot/bzImage和/home/DIY/initrd文件拷贝到linux系统的/boot目录下,而后修改/boot/grub/menu.lst,在其中添加以下一项:
点击(此处)折叠或打开
title DIY Your OS
root (hd0,0)
kernel /bzImage rw root=/dev/ram rootfs_size=8M
initrd /initrd
PS:由于咱们制做的initrd文件大小就是8M,因此rootfs_size=8M。
重启VMware,在启动界面咱们本身built的linux系统:
启动后效果以下:
咱们能够看到eth0接口已经up了,其IP地址默认为192.168.1.1,由于我虚拟机的IP地址池是192.168.6.*网段的,因此手动将eth0的接口IP设置为192.168.6.135:
而后经过web和telnet访问咱们本身作的系统,最终的访问结果以下:
小结:经过今天的学习相信你们对Linux系统的运行原理和启动流程的认识又上了一个新的台阶,更重要的是学会了如何手动构建一个“最小”的Linux“发行版”系统。那么,如今回过头来再看那些商业版的Linux系统,其实本质和咱们今天作工做的差很少,因此,若是有条件咱们也能够发行一个本身的系统了:)。