打造自己的linux--认识启动过程

看一下linux具体的启动过程,下面是一个分析图:

Linux----精简版---运维师必备_第1张图片

1. 第一阶段:开机自检 ->MBR引导

2. 第二阶段:选择硬盘启动/boot/grub/目录,当MBR引导时会看到引导菜单即grub 菜单,grub选择我们要加载的操作系统,即找到该操作系统的内核(kernel),从而启动第一个进程init 进程,读取/etc/inittab 配置文件(需自己来进行编写),即init进程所要的表格,无论我们进入哪一个级别,都要执行/etc/rc.s/rc.sysinit 脚本的(这个是记录键盘输入设备输入数据、网络功能等,即进入的init 级别),若输入的是‘3’则执行/etc/rc.d/rc脚本,执行/etc/rc3.d/*.

系统开机的经过可

总的来说linux启动的流程如下分析

  1.  加载 BIOS 的硬件信息与进行自我测试,依据定取得第一个可开机的装置;

  2. 读取执行第一个开机装置内 MBR 的boot Loader (亦即是grub, spfdisk 等程序) ;

  3. 依据 boot loader 的定加载 Kernel  ,Kernel 会开始侦测硬件不加载驱程序;

  4. 在硬件驱成功后,Kernel 会主呼叨 init 程序,而 init 会取得 run-level 信息;

  5. init 执行/etc/rc.d/rc.sysinit 档案来准备软件执行的作业环境 (如网络、时区等) ;

  6. init 执行 run-level 的各个服务的启动(script 方) ;

  7. init 执行/etc/rc.d/rc.local 档案;

  8. init 执行终端机仿真程序 mingetty 来启动login 程序,最后就等待用户登入啦;

开始打造自己的linux

安装在硬盘上,在硬盘上应具备内核,应用,怎样把这些应用放在硬盘上呐?

找一个完好的宿主机,把宿主机上的内核和应用移植到硬盘上,然后把硬盘扣出来。

1.添加硬盘,在虚拟机添加一个20G左右新硬盘放在指定目录下。

2.查看我们添加的硬盘名称:fdisk -l  看到有/dev/sdb  这个就是我们插入新硬盘盘名。


现在开始创建并引导可以启动的新硬盘:

嗯,这个新加的硬盘做好后会挪到别的机器上做sda盘,启动盘,必须用自己的引导分区和根分区。必须建分区,

Fdisk  /dev/sdb   n   p(增加主分区)   1  +100MB  p (查看) n  p  2  +1000MB

N  P  3  +500M  分区就建好了,这是看一下sd3 id号为83 sd3 是副分区得改一下其id=82 ,  t  82    就可以了,w

执行一下:partprobe  /dev/sdb  格式化这3个分区mkfs -t  ext3  /dev/sdb1   mkfs -t  ext3  /dev/sdb2  mkfs -t  ext3  /dev/sdb3  

查看一下分区:fdisk -l   sdb1 作为另一台机器上的引导分区,sdb2 作为根分区。

建立光盘过载点: mkdir  /mnt/sysroot  mkdir /mnt/boot  

                Mount /dev/sdb1 /mnt/boot/       mount  /dev/sdb2  /mnt/sysroot/

一个硬盘首先要有它的mdir  ,怎莫来构建类?那个程序分为两段一段在grub内部,一段在磁盘上, 构建这些东西用这个指令:

grub-install   --root-directory=/mnt/(根分区挂载点/root/不用写自动识别)  /dev/sdb

查看一下grub目录挂载上没? ll /mnt/boot/  再查看一下grub目录的文件,缺少一个grub菜单文件,我们自己来建一个。先拷贝下宿主机的内核。

cp /boot/vmlinuz-2.6.18-164.el5 /mnt/boot/cp /boot/initrd-2.6.18-164.el5.img  /mnt/boot/

创建一个工作用的文件夹,先把initrd-2.6.18-164.el5.img 拷贝到该文件夹中,因为这是一个压缩的镜像文件,在该目录里好解压,好管理

[root@localhost boot]# mkdir /tmp/abc

[root@localhost boot]# mv initrd-2.6.18-164.el5.img  /tmp/abc  进入abc目录

[root@localhost abc]# zcat initrd-2.6.18-164.el5.img | cpio -idcpio -id 为防止出现乱码指令)

Zcat 是查看压缩包的文件  ll 就可以看到所有文件了。

在这有必须执行的init文件,我们可以查看一下,vim init (下面摘录几行)

3 mount -t proc /proc /proc  挂载驱动程序指令

7 mount -t sysfs /sys /sys  也是挂载虚拟文件系统

mknod /dev/tty c 5 0   mknod 创建各种节点

87 #resume LABEL=SWAP-sda3  交换分区因为sdb3分区没有格式化,先禁用,不改会报错

88 echo Creating root device.

89 mkrootdev -t ext3 -o defaults,ro sda2

再次查看该目录,删除initrd-2.6.18-164.el5.img

查看所有文件的目录: find .  

[root@localhost abc]# find . |cpio -o -H newc --quiet |gzip -9 >initrd.gz    (--quite 采取静:默模式  由于这个文件太大,压缩一下-9值最大压缩值>指向自己命名的压缩包名称 )

[root@localhost abc]# cp initrd.gz /mnt/boot/  把这个目录文件ccopy到根分区根目录下,该文件加载各种驱动。

编辑缺少的grub菜单。

Cd  /mnt/boot/grub/   vim grub.conf

读取目录 .!ls /mnt/boot/vmlinuz /mnt/boot/initrd.gz

 1 default=0

 2 timeout=5

 3 hiddenmenu

 4 title my linux

 5         root(hd0,0)

 6        initrd /initrd.gz

 7         kernel /vmlinuz-2.6.18-164.el5 ro root=/dev/sda2 quiet                                                                  

现在我们做到加载内核 ,接下来该做init进程目录了。

移植init 进程,

Which init    查看宿主机boot/ 目录下的所有目录  ll  / 命令

在新建硬盘/mnt/sysroot/ 这些目录都还没有,得建立。

[root@localhost sysroot]# mkdir dev etc home lib media misc mnt net opt proc root sbin selinux srv sys tftpboot tmp usr varbin

[root@localhost sysroot]# mkdir etc/rc.d

[root@localhost sysroot]# cp /sbin/init sbin/

查看目录所依赖的库。

[root@localhost sysroot]# ldd /sbin/init

linux-gate.so.1 =>  (0x0011e000)

libsepol.so.1 => /lib/libsepol.so.1 (0x00434000)

libselinux.so.1 => /lib/libselinux.so.1 (0x0041a000)

libc.so.6 => /lib/libc.so.6 (0x0026a000)

libdl.so.2 => /lib/libdl.so.2 (0x003db000)

/lib/ld-linux.so.2 (0x0024c000)

我们必须拷贝这些库文件到lib目录下,一般用脚本。

cp /lib/libsepol.so.1 lib/

[root@localhost sysroot]# cp /lib/libselinux.so.1  lib/

[root@localhost sysroot]# cp /lib/libselinux.so.1  lib/

cp: overwrite `lib/libselinux.so.1'? n

[root@localhost sysroot]# cp /lib/libc.so.6  lib/

[root@localhost sysroot]# cp /lib/libdl.so.2  lib/

[root@localhost sysroot]# cp /lib/ld-linux.so.2  lib/

需要一个inittable 表格放在etc目录下

先看一看原来了宿主机内的inittable 表格:

Vim /etc/inittable

18 id:5:initdefault:  默认的运行级别为5

21 si::sysinit:/etc/rc.d/rc.sysinit  无论进入哪一个级别我们都要执行这个命令, 我们只需拷贝这一句话到inittable 表格中就可以了。

只需在该文件夹里执行这个命令::21 w /mnt/sysroot/etc/inittable w是写入到...:

si::sysinit:/etc/rc.d/rc.sysinit    (si是指系统初始化标志,:: 空白表示在任何一种级别,sysinit 表示他的动作,/etc/rc.d/rc.sysinit  表示我要运行的脚本)

这是我们查看一下该硬盘的/etc.rc.d/rc.sysinit 文件是否存在?

[root@localhost rc.d]# ll

total 0

可见并不存在,先查看一下宿主机上的该目录内容:

[root@localhost rc.d]# file /etc/rc.d/rc.sysinit

/etc/rc.d/rc.sysinit: Bourne-Again shell script text executable  这是一个bash可执行的脚本。

现在我们自己做个比较简单的:内容如下:

#!/bin/bash

echo -e "\033[31m dabinLINUX \033[0m"

/bin/bash

这个脚本是可执行的,赋予它一个权限:

[root@localhost rc.d]# chmod a+x rc.sysinit

现在看一下我们走到哪里了?从那个启动示意图上可以看到:都做差不多了,那摩得有bash文件来启动脚本文件,所以把宿主机上的bash文件拷贝到该硬盘的/mnt/sysroot/bin 目录下,

[root@localhost rc.d]# which bash

/bin/bash

[root@localhost rc.d]# cp /bin/bash /mnt/sysroot/bin

这时候又该做一个连接库了,也就是cp 文件到 lib/目录下

[root@localhost sysroot]# cp /lib/libtermcap.so.2 lib/

[root@localhost sysroot]# cp /lib/libdl.so.2 lib/

cp: overwrite `lib/libdl.so.2'? y

[root@localhost sysroot]# cp /lib/libc.so.6 lib/

cp: overwrite `lib/libc.so.6'? y

[root@localhost sysroot]# cp /lib/ld-linux.so.2 lib/

cp: overwrite `lib/ld-linux.so.2'? Y

可见我们已经有些都拷贝过了,我们只需覆盖。

查看一下:

[root@localhost lib]# tree

.

|-- ld-linux.so.2

|-- libc.so.6

|-- libdl.so.2

|-- libselinux.so.1

|-- libsepol.so.1

`-- libtermcap.so.2

现在都基本上这个空壳linux做完了,现在可以试着执行以下看看。

在此多次输入sync命令,使我们在硬盘上做的各种动作,都完全写到此硬盘上。

[root@localhost ~]# sync

[root@localhost ~]# sync

1>先把宿主机停下来,打开新的机器,把原来的硬盘拆除,挂接一个新的硬盘,

2>打开该虚拟机就可以启动了。

Linux----精简版---运维师必备_第2张图片

这样就行了啦。

下面我们再来移ls init、等命令,可以这样搞。(其实就是一些链接库的cp拷贝到lib目录下)

Ls :命令:

[root@localhost sysroot]# which ls

alias ls='ls --color=tty'

/bin/ls

[root@localhost sysroot]# cp /bin/ls bin/

[root@localhost sysroot]# ldd /bin/ls

linux-gate.so.1 =>  (0x00122000)

librt.so.1 => /lib/librt.so.1 (0x009e6000)

libacl.so.1 => /lib/libacl.so.1 (0x00660000)

libselinux.so.1 => /lib/libselinux.so.1 (0x0083f000)

libc.so.6 => /lib/libc.so.6 (0x00123000)

libpthread.so.0 => /lib/libpthread.so.0 (0x0053a000)

/lib/ld-linux.so.2 (0x006a2000)

libattr.so.1 => /lib/libattr.so.1 (0x0093f000)

libdl.so.2 => /lib/libdl.so.2 (0x00b37000)

libsepol.so.1 => /lib/libsepol.so.1 (0x00337000)

[root@localhost sysroot]# sync

[root@localhost sysroot]# sync

这样在自己的linux系统下就可以使用ls命令了。

接下来是init命令的植入

先来了解一下init 的。

进入0级别,也就是关机级别:

[root@localhost ~]# cd  /etc/rc.d/rc0.d  进入这个目录。

这个目录下有许多文件进程,也就是只要我们进入0级别,都要把这么多进程杀掉,

也要启用一个进程?:lrwxrwxrwx 1 root root 17 Aug  7 05:05 S00killall -> ../init.d/killall

lrwxrwxrwx 1 root root 14 Aug  7 05:05 S01halt -> ../init.d/halt

[root@localhost rc0.d]# vim S01halt    进入这个文件看一下。

查看最后一行:222 exec $command $HALTARGS   用$执行 commandHALTARGS 都是一个变量。可以查看一下commond 在此文件里做什么用处。

220 [ "$INIT_HALT" != "HALT" ] && HALTARGS="$HALTARGS -p" 这一行设置了参数 -p

222行的声明是执行HALTARGS -p 的关机指令,

接下来查看宿主机的inittab文件。

[root@localhost etc]# vim /etc/inittab

Linux----精简版---运维师必备_第3张图片

末行模式执行:23 w>>/mnt/sysroot/etc/inittab  把23行的0级别内容移植到新硬盘的inittab目录下。

进入新硬盘/mnt/sysroot/etc/inittab 文件进行编译。

内容如下:(为了方便我自己取了个文件名字:rc.sysdown

si::sysinit:/etc/rc.d/rc.sysinit

l0:0:wait:/etc/rc.d/rc.sysdown

改写好这个文件后我们得创建rc.sysdown shell 脚本。

[root@localhost rc0.d]# cd  /mnt/sysroot/etc/rc.

[root@localhost rc.d]# vim rc.sysdown

[root@localhost rc.d]# chmod a+x rc.sysdown

上面的shell文件的执行文件还没有,我们把它copy/mnt/sysroot/sbin/目录下。

[root@localhost rc.d]# cp /sbin/halt /mnt/sysroot/sbin

这是就可以执行0级别关机了。

Linux----精简版---运维师必备_第4张图片

接下来设置主机名:

恩,这个开始时我们提过了,/etc/rc.s/rc.sysinit 脚本的(这个是记录键盘输入设备输入数据、网络功能等,即进入的init 级别)现在看一下这个文件宿主机怎么编译的哦

[root@localhost ~]# vim /etc/rc.d/rc.sysinit

在接下来查看/etc/sysconfig/network 文件

这时,我们分析完了,来在新硬盘里建立编写这个文件

[root@localhost ~]# vim /mnt/sysroot/etc/rc.d/rc.sysinit

Linux----精简版---运维师必备_第5张图片

[root@localhost ~]# mkdir /mnt/sysroot/etc/sysconfig

[root@localhost ~]# cd /mnt/sysroot/etc/sysconfig

[root@localhost sysconfig]# vim network

进入末行模式:

:r /etc/sysconfig/network  copy到该文件里。

这时想到我们这里得修改一下:

[root@localhost ~]# vim /mnt/sysroot/etc/rc.d/rc.sysinit

添加这两行。

这时还没有copy 宿主机下的/mnt/hostname指令

[root@localhost sysconfig]# cp /bin/hostname /mnt/sysroot/bin/

接下来该拷贝链接库文件:

[root@localhost bin]# ldd hostname

拷贝完链接库后

[root@localhost ~]# sync

[root@localhost ~]# sync

就可以执行hostname指令了。



可以说想要神马功能就可以构建这项功能。欢迎来访,有什么疑问我们共同探讨。