剖析Linux之制作一个小LINUX

简介:
经过半下午的不懈努力,终于完成了马哥布置的作业——制作一个小LINUX,或许有很多学哥学姐已经写过自己的制作过程,这里我了分享一下,写下自己的制作过程及中间遇到的困难。本人文笔不是很好,就不多说了,直接开工。

要制作一个小的Linux,我们就要了解Linux系统开机的整个过程,其实很简单,跟WIN差不多。
POST(BIOS加电自检)-->根据BIOS的设定启动相应的设备-->Boot loader -->解压内核到内存 -->运行init进程

整个过程大概如上所述。
其中,内核在加载的过程中所完成的工作包括以下:
硬件探测
完成设备驱动程序初始化(initrd获取驱动程序,以模块的形式存在)
挂载根文件系统(以只读方式挂载)
装载/sbin/init,启动系统的PID为1的进程

系统的主进程init主要是根据/etc/inittab文件中的定义,来进行工作的。下面再看一下inittab文件是怎么写的,我们可以man inittab看一下,该文件的组成部分以及各组成部分的详细信息。
NAME
inittab - format of the inittab file used by the sysv-compatible
init process

id:runlevels:action:process

各字段的解释
ID:就是一ID号,说白了就是一名字,代号,可以随便取。
RUNLEVELS:运行级别
ACTION:在什么情况下
PROCESS:运行什么命令

以下是action常用的选项
action:
respawn 重新启动,当进程结束后,将会马上被重启
wait只有进入某个特定级别以后process才会启动一次,并且直到其结束为止,不再有其它动作
initdefault 设定默认运行级别
sysinit 系统初始化,这个进程将在系统启动过程中会被执行一次
ctrlaltdel: 用户同时按下ctrl+alt+del执行进程

看一下inittab文件的内容
id:3:initdefault:
#名字叫id,运行级别为3,initdefault的意思上面已经有解释了。设定默认运行级别的

si::sysinit:/etc/rc.d/rc.sysinit
#名字叫si,运行级别没写,表示所有的运行级别,动作叫sysinit,表示系统的初始化,然后初始化要运行的脚本为/etc/rc.d/rc.sysinit

l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
#名字叫 l1---l6,运行级别为0-6,分别对应系统的6个运行级别,每个级别分别运行所对应的/etc/rc.d/rc 0 在/etc/rc.d里有个脚本叫rc,这个脚本主要是调用/etc/rc.d/rc.[0-6]/目录里的文件,该目录里的文件都是以K加数字加服务名或者S加数字加服务名组成,其中K表示KILL,要杀掉的服务,也即是系统开机后,不运行的服务,S表示start,运行对应级别后,所要运行的服务,其后面所对应的数字是服务的优先级。
ca::ctrlaltdel:/sbin/shutdown -t3 -r now
#名字叫ca,所有运行级别,当按下Ctrl+Alt+Del的时候,运行/sbin/shutdown命令,也就是说:当用户按下CTRL+ALT+DEL组合键后,系统会在3分钟内重启。这样很危险,建议改成其它的。
pf::powerfail:/sbin/shutdown -f -h +2 "Power Failure; System Shutting Down"
#名字叫pf,所有的运行级别,powerfail表示停电之后(对UPS有效),执行后面的shutdown
pr:12345:powerokwait:/sbin/shutdown -c "Power Restored; Shutdown Cancelled"
#名字叫pr,在12345的运行级别,powerokwait 表示停电不久,在指定关机的时间内,又来电了,就执行后面的shutdown内容


1:2345:respawn:/sbin/mingetty tty1
2:2345:respawn:/sbin/mingetty tty2
3:2345:respawn:/sbin/mingetty tty3
4:2345:respawn:/sbin/mingetty tty4
5:2345:respawn:/sbin/mingetty tty5
6:2345:respawn:/sbin/mingetty tty6
#名字分别叫123456,都是在2345级别,rewpawn表示后面执行的进程只要一结束,就立即重启它们
x:5:respawn:/etc/X11/prefdm -nodaemon
#名字叫x,在5级别下,只要后面的进程一结束,就立即重新运行它们。

INIT调用了/etc/inittab文件后,系统就开始启动了,其实inittab文件就是判断系统是运行在哪个级别以及设置默认的级别,判断完默认级别后,开启指定级别目录内的服务(/etc/rc.d/rc.N目录内的所有脚本).然后调用了一个rc.sysinit脚本。

LINUX开机其实大概就做这么多事情。

我们要做一个LINUX,首先POST就可以略过考虑了,还有BIOS里设置设备启动次序的。那再往后,我们要做的就是要有一个bootloader了,这个可以通过安装grub来实现 ,至于怎么安装grub,我已经有一篇博客说过了,这里就不再说了。再往后,就是要有一个内核了,内核引导完成后,有一个init进程,这个进程其实就是/sbin/init这个命令来调用的。那我们把这个拷过来,就行了。init又是根据/etc/inittab文件来工作的,那我们就再创建一个inittab的文件,inittab文件又要调用 /etc/rc.d/rc.sysinit这个文件,我们再写一个这样的文件,任务就完成了。就这么多东西,呵呵,有点儿乱,整理一下下

构建一个小LINUX需要的东西有:bootloader(grub),kernel,init,inittab,rc.sysinit.
好了,思路搞清楚了,下面开工吧。

首先要有一个内核,内核我们可以通过拷贝系统自身的内核来实现。
记得一定要放对目录,不要乱放,放到grub的同级目录。vmlinuz是系统的内核文件,initrd.img是内核所需要加载的一些驱动,但是initrd.img文件不能直接使用,我们要改一下里面的一个参数。
文件类型是gzip的,但是不能直接解压,不然会报:无法识别的后缀名。要先改成.gz的,然后再解压,解压完成后,再看一下是cpio的,然后再用cpio把文件取出来,就看到了一个微型的linux,这个微型的linux里面,只有驱动,没有其它东西,文件基本上都在lib下。
然后我们要改一下init文件,里面有一项叫mkrootdev,这里是要指定的根设备。就是系统的根。如果没错,就不用改,如果有错,要改一下的。改成我们的小linux所在的磁盘设备名,grub已经战用了一个/dev/sda1,那这里我们就要改成/dev/sda2,做为小LINUX的根。

改完之后,内核这一步我们就做完了。下面就是做init了
init在/sbin下,所以,我们要在我们的根文件系统上,创建出/sbin目录,然后把init放进去。inittab文件在/etc/inittab里面,也同样的放进去。然后在inittab文件里面,简单的写两项就行了,如下
InBlock.gif[root@Honway sysroot]# cat etc/inittab    
InBlock.gifid:3:initdefault: 
InBlock.gifsi::sysinit:/etc/rc.d/rc.sysinit 
第一行是设置系统的默认运行级别的,第二行是调用rc.sysinit文件的。这个文件不存在,我们也要创建出来,包括其父目录。
然后在里面随便写点东西就可以了。
InBlock.gif[root@Honway sysroot]# cat etc/rc.d/rc.sysinit    
InBlock.gif#!/bin/bash 
InBlock.gifecho -e  "\033[34m \033[05mHello,Welcome to my host.\033[0m" 
InBlock.gifbash 
比如我们就写上面一句话,然后打开bash,因为bash也没有,所以,我们还要拷贝/bin/bash文件放到对应的目录
以上的做完之后,还有拷贝一些库文件放到对应的目录,因为命令的运行,是要调用库文件的,用ldd命令查看一下init和bash两个命令要调用哪些库文件,然后拷贝到相对应的目录即可。
InBlock.gif[root@Honway sysroot]# ldd /bin/bash 
InBlock.gif                linux-gate.so.1 =>    (0x00e68000) 
InBlock.gif                libtermcap.so.2 => /lib/libtermcap.so.2 (0x00d65000) 
InBlock.gif                libdl.so.2 => /lib/libdl.so.2 (0x00d5f000) 
InBlock.gif                libc.so.6 => /lib/libc.so.6 (0x00bee000) 
InBlock.gif                /lib/ld-linux.so.2 (0x00bd0000) 
这里我们只拷贝/开头的库文件,其它不用管。到这里,系统就算是制作完成了。是不是很EASY。呵呵。如果想使用一些其它的命令,比如/bin/ls,也只需要把命令拷过去,然后对应的库弄过去,就OK了。看一下我们制作出来的小系统吧

搞定了,是不是很有成就感啊。呵呵,上面有个小错,可能是我initrd.img文件里面的init文件没有改好,再改下就行了。
你还等什么,赶快也试试吧……


本文转自 gm100861 51CTO博客,原文链接:http://blog.51cto.com/gm100861/784870

相关文章
|
Linux
Linux制作deb格式安装包教程
Linux制作deb格式安装包教程
544 0
|
Ubuntu Java Linux
alpine Linux与基于alpine制作JDK8镜像
Docker commit 命令 1.下载基础镜像 2.使用此基础镜像创建/启动/进入容器 3.在容器安装自己需要的软件 4.将保存配置完成的容器提交成镜像 语法如下 docker commit [OPTIONS] CONTAINER [REPOSITORY[:TAG]] OPTIONS说明: -a :提交的镜像作者; -c :使用Dockerfile指令来创建镜像; -m :提交时的说明文字; -p :在commit时,将容器暂停。 实例:将容器a404c6c174a2 保存为新的镜像,并添加提交人信息和说明
|
安全 Linux Windows
Linux科普扫盲系列(Linux启动安装U盘的制作)
Linux科普扫盲系列(Linux启动安装U盘的制作)
613 0
Linux科普扫盲系列(Linux启动安装U盘的制作)
|
缓存 Unix Linux
linux系统编程(三)gcc常用技巧与静态库与动态库制作
linux系统编程(三)gcc常用技巧与静态库与动态库制作
231 0
linux系统编程(三)gcc常用技巧与静态库与动态库制作
|
存储 Linux iOS开发
制作 Kali 可启动 USB 驱动器 (Linux)
制作 Kali 可启动 USB 驱动器 (Linux)
288 0
制作 Kali 可启动 USB 驱动器 (Linux)
|
存储 Java Linux
【系统】[Linux]CentOS 7之下载、制作U盘系统盘篇
【系统】[Linux]CentOS 7之下载、制作U盘系统盘篇
192 0
【系统】[Linux]CentOS 7之下载、制作U盘系统盘篇
|
Java Linux Windows
制作Linux启动jar文件脚本
在windows上的命令行可以使用java -jar的方式来启动jar程序,在Linux上该如何方便启动呢?
385 0
制作Linux启动jar文件脚本
|
Linux
全网首发:制作LINUX安装软件包,要处理哪些系统目录和文件(3)
全网首发:制作LINUX安装软件包,要处理哪些系统目录和文件(3)
72 0
全网首发:制作LINUX安装软件包,要处理哪些系统目录和文件(2)
全网首发:制作LINUX安装软件包,要处理哪些系统目录和文件(2)
90 0
|
Linux
全网首发:制作LINUX安装软件包,要处理哪些系统目录和文件(1)
全网首发:制作LINUX安装软件包,要处理哪些系统目录和文件(1)
241 0