写在前面:如果此文有幸被某位朋友看见并发现有错的地方,希望批评指正。如有不明白的地方,愿可一起探讨。
本文主要目的
本文并不是要真正的去构建一个自己的Linux的系统,而是通过制作Linux系统的过程中,更加清晰的理解Linux系统的启动流程,实践检验真理嘛。
Linux系统启动的简要流程
为了明白制作Linux系统的简单步骤,下面给出Linux系统启动的简要流程图:
本文主要进行的步骤:
1.制作grub,编辑grub.conf配置文件;
2.编译内核并将其复制到相应目录;
3.编辑/sbin/init并配置其执行环境;
准备工作
在虚拟宿主机上添加一块大小为10G的SCSI磁盘(Cl7)并将其分区格式化(具体如何添加,这里就不进行说明了,望理解):
# fdisk /dev/sdb n p 1 +50M n p 2 +512M n p 3 +512M t 3 82 w # kpartx -af /dev/sdb # partx -a /dev/sdb # mke2fs -t ext4 /dev/sdb1 # mke2fs -t ext4 /dev/sdb2 # mkswap /dev/sdb3 # mkdir /mnt/boot # mkdir /mnt/sysroot # mount /dev/sdb1 /mnt/boot # mount /dev/sdb2 /mnt/sysroot
再添一台虚拟主机(Cl7),并将虚拟宿主机中所添加的磁盘作为其启动盘
提示:在新建虚拟主机(Cl7)过程中,当到达"Select a Disk"对话框这一步时,选择"Use an existing virtual disk"选项;点击Next后点击Browse...按钮找到虚拟宿主机所添加的那块磁盘即可。
安装GRUB并编辑grub.conf配置文件
安装GRUB
[root@localhost ~]# grub-install --root-directory=/mnt/ /dev/sdb
Probing devices to guess BIOS drives. This may take a long time. Installation finished. No error reported. This is the contents of the device map /mnt/boot/grub/device.map. Check if this is correct or not. If any of the lines is incorrect, fix it and re-run the script `grub-install'. (fd0) /dev/fd0 (hd0) /dev/sda (hd1) /dev/sdb
编辑grub.conf配置文件
[root@localhost ~]# vim /mnt/boot/grub/grub.conf
default=0 timeout=5 title Mini-Linux (3.13.6-cl7) root (hd0,0) kernel /bzImage ro root=/dev/sda2 init=/sbin/init
将数据同步到磁盘
# sync # sync # sync
挂起虚拟宿主机,启动Cl7这台虚拟主机看看效果
看到了吗?这红色框里就是我们在grub.conf里所编辑的title那行!
呀,怎么文件没有找到?找到了才不正常呢!因为我们根本就没有提供这个文件哦。接下来,我们就来定制、编译内核并将其添加进来。
定制并编译内核
# 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
接下来就是选择所需要的内核模块,*表示将其编译进内核,除了默认选项外,本文需要添加内容
[*] 64-bit kernel General setup ---> ()Local version - append to kernel release -cl7 [*] System V IPC [*] Enable loadable module support ---> [*] Module unloading -*- Enable the block layer ---> [*] Block layer SG support v4 Processor type and features ---> [*] Symmetric multi-processing support Processor family (Generic-x86-64) ---> (X) Core 2/newer Xeon Bus options (PCI etc.) ---> [*] PCI support Executable file formats / Emulations ---> [*] Kernel support for ELF banaries [*] Kernel support for scripts starting with #! [*] Networking support ---> [ ] Wireless ---- Networking options ---> <*> Unix domain sockets [*] TCP/IP networking [*] IP: multicasting [*] IP: advanced router [*] TCP: advanced congestion control ---> < > The IPv6 protocol ---- Device Drivers ---> Generic Driver Options ---> [*] Maintain a devtmpfs filesystem to mount at /dev [*] Automount devtmpts at /dev, after the kernel mounted the rootfs SCSI device support ---> <*> SCSI device support <*> SCSI disk support [*] Fusion MPT device support ---> <*> Fusion MPT ScsiHost drivers for SPI [*] Fusion MPT logging facility [*] Network device support ---> [*] Ethernet driver support ---> [*] Intel devices <*> Intel (R) PRO/1000 Gigabit Ethernet support <*> Intel (R) PRO/1000 PCI-Express Gigabit Ethernet support 其他选项全部去掉 [ ] Wireless LAN ---- Input device support ---> <*> Mouse interface [*] Keyboards ---> [*] Mice ---> [*] USB support ---> <*> Support for Host-side USB <*> xHCI HCD (USB 3.0) support <*> EHCI HCD (USB 2.0) support <*> OHCI HCD (USB 1.1) support <*> UHCI HCD (most Intel and VIA) support File systems ---> <*> The Extended 4 (ext4) filesystem
保存退出,编译内核
# make -j 4 # cp arch/x86_64/boot/bzImage /mnt/boot/
将数据同步到磁盘
# sync # sync # sync
挂起虚拟宿主机,启动Cl7这台虚拟主机看看效果
红框里的意思为:执行/sbin/init失败,究其原因在于没有找到init。这就对了,因为我们根本就没有提供这个文件,因此,接下来,我们就来提供此文件。
编辑/sbin/init并配置其执行环境
建立根文件系统文件
# cd /mnt/sysroot/ # mkdir -pv proc sys dev etc/init.d usr sbin bin root home var mnt media tmp
编辑init文件
[root@localhost ~]# vim /mnt/sysroot/sbin/init
#!/bin/bash echo -e "Welcome to \033[35mMini-Linux\033[0m" 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
设置init为可执行并检查其是否有语法错误
# chmod +x /mnt/sysroot/sbin/init # bash -n /mnt/sysroot/sbin/init
在init文件中要使用需要bash来执行程序,因此我们得为其提供执行环境。本文使用bincp.sh脚本将命令及其所以来的库复制到相应的目录中,bincp.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 ; then commandCopy $commandPath libCopy $commandPath fi read -p "Plz enter a command: " command done
执行bincp.sh脚本,复制几个命令
[root@localhost ~]# bash bincp.sh
Plz enter a command: bash Plz enter a command: ls Plz enter a command: mount Plz enter a command: umount Plz enter a command: quit
将数据同步到磁盘
# sync # sync # sync
挂起虚拟宿主机,启动Cl7这台虚拟主机看看效果
在上图中,将鼠标点击进去并敲Enter键得到bash提示符
仔细查看上图,其实bash提示符在敲Enter键之前已经出现了,只是被后来的信息淹没在浩瀚的海洋中,不容易被察觉而已!!!
以上内容仅仅是提供了一个bash程序以及系init脚本,对于系统服务以及获得bash提示符之前的很多内容并没有添加进来。接下来的工作就是为这个Mini-Linux系统提供系统服务和bash执行环境等内容。
转载于:https://blog.51cto.com/muluhe/1545584