标签:自制linux小系统
章节导航:
前言
Linux系统启动流程
实验前的准备
实验过程
拷贝命令脚本
一、前言
我们生活中离不开电脑,时时刻刻在跟操作系统打交道,有时候会被系统中出现的错误搞得头昏脑胀,使用操作系统,不如亲自动手组建一个自己的简单的系统,体验一下制作操作系统的乐趣。在系统的学习了Linux操作系统之后,就有了理论基础,所以,迫不及待的想做一个自己的简单的Linux小系统,有兴趣的同学也可以来动手做一做。
在接下来的文章中,小编会先从Linux系统的启动流程入手,将启动过程一一展示出来,再进行实验指导。
二、Linux系统启动流程
这些自检的功能是有一个软件程序来实现的,这个软件程序叫做:BIOS。BIOS是基本输入输出系统,他是装在一个硬件芯片CMOS之上,加电过程给CMOS通电,BIOS会根据CMOS上的一些配置信息去读取硬件的状态,之后进行硬件设备的初始化。
加电自检主要是检测一下硬件设备是够存在并能够正常运行,如:CPU、内存、硬盘是否存在并能正常运行,CPU风扇是否能够运转散热,以及一些外围的输入输出设备是否存在,但是有些设备存在与否不影响系统的正常启动,如键盘、鼠标。
在硬件初始化之后,BIOS会列出一些可以启动的装置顺序,接下来就开始读取第一个可以启动的设备中操作系统的核心文件。我们必须以一个启动管理程序来处理这些核心文件的加载问题,这个启动管理程序为:Bootloader,Boot loader是一个程序,他肯定依赖于一个硬件之上,这个硬件就是硬盘,准确的说是第一个可以启动的硬盘的第一个扇区内,就是我们之前读到的MBR(主引导记录)当中。所以,在加电自检之后BIOS会将系统引导到MBR中,找到Boot loader。
Boot Loader就是在操作系统内核运行之前运行的一段小程序。通过这段小程序,可以初始化硬件设备,建立内存空间的映射图,从而将系统的软硬件环境为最终调用操作系统内核做好准备。Boot Loader使用最广的就是Grub了,系统将Linux下/boot/grub/grub.conf的配置文件读取到内存中,根据配置文件中的信息找到内核文件和伪根文件,并将伪根文件加载到内存中,模拟出一个根文件系统,再进行加载内核文件。
Bootloader可以加载kernel和initrd,然后在内存中让initrd解压缩成根目录,然后内核可以在这个虚拟的根文件系统之上加载合适的驱动程序,来加载硬盘等设备,之后释放虚拟的根文件系统,并以只读的方式挂载磁盘上真实的根文件系统,之后就开始正常的启动过程。此时内核程序已经完全接管了BIOS工作,之后的操作都是有内核来完成的。
在内核、硬件及驱动信息加载完毕后,内核会呼叫用户空间的第一个执行程序/sbin/init,inti进程主要功能是准备软件运行环境,包括系统的主机名称、网络配置、文件系统格式、服务运行级别等其他服务的启动管理。这些所有的操作都是通过init的配置文件来定义的。
Init的配置文件:
Centos5:由于centos5采用的是Sys init方式,其特点是启动用户空间的服务程序,通常通过脚本运行,有依赖关系的服务将被串行启动,这也就导致了centos5的系统启动过程非常的缓慢,配置文件为:/etc/initab
Centos6:采用Upstart的方式,其特点是守护进程间的通信依赖于D-Bus进行,因此,可基本实现类似并行启动:配置文件:/etc/inittab,/etc/init/*.conf
Centos7:采用Systemd方式,其特点是服务只有在第一次被访问到时才会真正启动起来,因此Centos7系统的启动过程非常之快,配置文件是:/usr/lin/system/*。
在定义完运行级别后,Linux系统执行的第一个用户层文件就是rc.sysinit脚本程序,这个脚本为初始化用户空间环境,会执行许多系统初始化任务;在完成系统初始化脚本后,系统还会启动对应级别下设定为要启动的服务,关闭那些设定为要关闭的服务。该步骤是根据inittab配置文件中定义的运行级别,来运行对应运行目录中的服务设定脚本。
在服务启动的最后,会执行最后一个脚本:/etc/rc.d/rc.local,这个脚本是留个用户的,可以将用户想要启动的东西放到这里。
此时就进入了输入username和password的时刻了,漫漫开机之路就算到此结束了。
附上启动流程图:
三、实验前的准备
我们要制作的是U盘Linux系统,所以要准备一个U盘,不需要太大够用就行。
需要准备的工具:U盘、虚拟机或Centos的主机一台、Centos6系统。
U盘的要求:一般Linux系统不识别NTFS的文件系统,所以要是U盘是NTFS的系统,我们需要将其格式化为FAT32文件系统的格式,这样系统才能识别。
四、实验过程
1、启动虚拟机的VMware USB Arbitration Service服务
我们需要虚拟机能够识别USB接口上的U盘,所以要开启这个服务,如果一斤开启了,可以直接跳过步骤,小编将为大家演示如何开启该服务。
如图所示:
右击我的电脑,打开管理,进入:
在服务中找到VMware USB Arbitration Service项,将服务启动起来,这个时候重新打开虚拟机。
2、将U盘挂载到虚拟机中的系统上
打开虚拟机后,将右下方显示的磁盘标志,找到自己的U盘,选择连接:
3、 对U盘进行分区
我们需要将U盘分为两个分区,一个用来当做boot分区,一个用来当做根分区。使用:fdisk 命令。
在小编的电脑上识别到的U盘为/dev/sdc盘号,所以执行:fdisk/dev/sdc,将/dev/sdc1作为boot分区,分出大小1G;将/dev/sdc2作为根分区,将剩余空间全部分给根分区。
4、 将分区格式化为ext4文件系统
分好区后并不能直接使用,我们需要将分区格式化后才可以正常使用,使用命令:mkfs.ext4 /dev/sdc1需要将/dev/sdc1和/dev/sdc2两个分区进行格式化。
5、 创建挂载将要设置为boot分区的目录
该目录必须为boot,这样在生成一些数据的时候才不会乱,因为我们要将分区/dev/sdc1挂载到命名为/boot的目录下,我们需新建目录,为了不和本地系统上的boot目录混淆,小编创建新的目录:mkdir –p /linshi/boot
6、 将/dev/sdc1挂载到/linshi/boot目录上
执行命令:mount /dev/sdc1 /linshi/boot
7、 对boot分区/dev/sdc1安装grub
执行命令:grub-install --root-directory=/linshi /dev/sdc
该命令是用来安装修复grub引导文件的,如果grub目录中的文件损坏了,可以通过该命令进行恢复。因为我们要在U盘的boot目录上安装grub,所以需要指定一个位置,那就是—root-directory=/linshi,对象为/dev/sdc
查看/linshi/boot下的目录树结构:
查看U盘的MBR表:
8、 将本地的boot下的内核文件和伪根文件拷贝到U盘中的boot下,命令如下:
cp /boot/vmlinuz-2.6.32-696.e16.x86_64 /linshi/boot/
cp /boot/initramfs-2.6.32-696.e16.x86-64.img /linshi/boot/
执行过程如图所示:
9、 手动编写grub.conf配置文件
Vim /mnt/boot/grub/grub.conf
内容如下:
default=0
timeout=5
hiddenmenu
title Centos-jiake
root(hd0,0)
kernel/vmlinuz-2.6.32-696.e16.x86_64 root=UUID=(U盘的根分区的UUID) selinux=0 init=/bin/bash
initrd/ initramfs-2.6.32-696.e16.x86-64.img
如图所示:
10、 创建挂载根分区的目录,并挂载U盘的根分区
mkdir /linshi/sysroot
mount /dev/sdc2 /linshi/sysroot
如图:
11、 在U盘的根分区下创建与本地根下相同的目录
一个一个创建太慢,我们使用一个快捷的方式,先将本地根下的目录名全部存放起来,做成一个列表,然后一次性创建。
先ls / > /mulu.txt
mkdir –p `cat mulu.txt`
如图:
12、 拷贝网卡驱动
有时候我们需要用用网卡,所以我们将网卡驱动一块拷贝过去,如果不想使用网卡功能,可以不用拷贝这个文件驱动。
使用locate e1000找到网卡驱动的位置,e1000是网卡的驱动程序文件。
如图所示:
13、 通过命令拷贝脚本,将需要使用的命令拷贝到U盘的根分区上
这个脚本是小编自己编写的,如果你不会,不用着急,小编会在后面附上源代码。如果你要使用脚本,记得给脚本加上执行的权限。具提的操作可以看小编的截图:
14、 查看我们U盘根分区下的树状结构图
我们拷贝完命令,一定要验证命令是否拷贝成功,并且路径一定要正确。命令原来在什么地方,拷贝过来还要放到对应的目录下。否则会导致命令不可用。
15、 完成命令移植的功能后,将U盘放到独立的机器上启动
要关机将U盘拔下来,这里小编使用电脑作为整机,从U盘启动,所以就不能呈上优质的截图了。一下图片使用手机拍摄。
对于不同的机型,进入本地BIOS的按键也不同,请各位同学自行寻找进入BIOS的按键,进入BIOS需要将U盘设为第一启动项,(为了在BIOS的boot启动项显示出U盘,需要先将U盘插入电脑)
找到自己的U盘,使用shift +将U盘移动到第一位:
完成后按下F10保存退出启动:
16、 启动成功!
稍等片刻,我们就能看到成功进入bash的界面了,由于我们自制了一个简单的Linux系统,所以目前只是使用bash进入了一个简单的bash环境,可以执行一些简单的命令,如果想使用init启动进程,需要配置更多的文件,如果有兴趣的同学可以据需深入研究。
五、拷贝命令脚本
#!/bin/bash
#将用户指定的命令拷贝到对应的根目录下
copy_comd() {
com_path=`which $1`
com_dest=`dirname $com_path`
[ ! -d $dir$com_dest ] && mkdir -p $dir$com_dest
ls $dir$com_path &> /dev/null && { echo "该命令已存在!" ;return 99; }
cp $com_path $dir"$com_path"
echo -e "$com_path \e[33;5m ====>\e[0m $dir"$com_path""
}
#将命令所依赖的库文件拷贝到对应的目录中
copy_comfile(){
ldd $(which $1) |grep -oE "/.* " | while read libfile
do
local lib_destdir=$dir$(dirname $libfile)
local lib_destfile=$dir$libfile
if [ -e $lib_destfile ];then
continue
elif [ -d $lib_destdir ];then
cp $libfile $lib_destdir
echo -e "$libfile \e[33;5m ===> \e[0m $lib_destfile"
else
mkdir -p $lib_destdir &> /dev/null
cp $libfile $lib_destdir
echo -e "$libfile \e[33;5m ===> \e[0m $lib_destfile"
fi
done
}
#主程序(需要先指定根目录,每个执行步骤都可以quit退出。)
while true;do
read -p "Please input the dir("quit" to exit!): " dir
if [ "$dir" == quit ] ;then
exit
fi
[ -z $dir ] && { echo -e "\e[31m Please input the dir!\e[0m";continue;}|| break
done
ls -d $dir &> /dev/null || mkdir -p $dir
while true; do
read -p "Please input the command that you want to copy("quit" to exit! ): " com
if [ "$com" == quit ]; then
exit
fi
which "$com" &> /dev/null || { echo "This command is no exited!" ;continue; }
copy_comd $com
ret=$?
[ $ret -eq 99 ] && continue
copy_comfile $com
done
#(记得给脚本加执行权限哦!)
本文出自 “Linux运维” 博客,请务必保留此出处http://jk6627.blog.51cto.com/12002684/1967667
标签:自制linux小系统
原文地址:http://jk6627.blog.51cto.com/12002684/1967667