打造自己的linux--认识启动过程
看一下linux具体的启动过程,下面是一个分析图:
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 -id (cpio -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
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>打开该虚拟机就可以启动了。
这样就行了啦。
下面我们再来移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 用$执行 command、 HALTARGS 都是一个变量。可以查看一下commond 在此文件里做什么用处。
220 [ "$INIT_HALT" != "HALT" ] && HALTARGS="$HALTARGS -p" 这一行设置了参数 -p
则222行的声明是执行HALTARGS -p 的关机指令,
接下来查看宿主机的inittab文件。
[root@localhost etc]# vim /etc/inittab
末行模式执行: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级别关机了。
接下来设置主机名:
恩,这个开始时我们提过了,执/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
[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指令了。
可以说想要神马功能就可以构建这项功能。欢迎来访,有什么疑问我们共同探讨。