您的位置:首页 > 运维架构 > Linux

运用内核创建一个小的linux【壹】--分析linux启动流程

2013-08-07 20:29 721 查看
当我们打开linux系统,在等待他启动的过程中,我们是否想过,他是怎么来启动系统的,它的启动流程又是什么??这次就是用一个小小的精简版的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;
7. init 执行 /etc/rc.d/rc.local 档案;
8. init 执行终端机仿真程序 mingetty 来启动 login 程序,最后就等待用户登入啦;

规划:
1.简化的系统必备的东西:内核,驱动,init进程,inittabble,库文件,应用【这里应用指的是一些命令,比如ls cat之类的】
2.虚拟机
3.一个完整的linux5.4操作系统
4.一个没有硬盘的,空壳linux5.4系统
做得并不复杂,只是通过它来关注一下系统的启动流程

第一阶段

1.首先在一个功能齐全的linux虚拟机上面,创建一个新的硬盘。




2.dev目录下已经挂载上新的磁盘
[root@localhost~]# ls /dev/sd*
/dev/sda /dev/sda1 /dev/sda2 /dev/sda3 /dev/sdb
3.然后创建分区,创建三个主分区
[root@localhost ~]# fdisk /dev/sdb
Command (m for help): n
Command action
e extended
p primary partition (1-4)
p
Partition number(1-4): 1
First cylinder(1-2610, default 1):
Using defaultvalue 1
Last cylinder or+size or +sizeM or +sizeK (1-2610, default 2610): +100M
创建一个boot分区,只需要100M
Command (m forhelp): n
Command action
e extended
p primary partition (1-4)
p
Partition number(1-4): 2
First cylinder(14-2610, default 14):
Using defaultvalue 14
Last cylinder or+size or +sizeM or +sizeK (14-2610, default 2610): +1024M
第二个根分区1G【在这里如果设置的少的话,在精简的linux启动的时候是启动不起来了】
Command (m forhelp): n
Command action
e extended
p primary partition (1-4)
p

Partition number(1-4): 3
First cylinder(139-2610, default 139):
Using defaultvalue 139
Last cylinder or+size or +sizeM or +sizeK (139-2610, default 2610): +500M
第三个分区,交换分区 swap
4. 更改他们的id号~ 并设置sdb1为引导分区
Device Boot Start End Blocks Id System
/dev/sdb1 * 1 13 104391 83 Linux
/dev/sdb2 14 138 1004062+ 83 Linux
/dev/sdb3 139 200 498015 82 Linux swap / Solaris
然后要在自己需要制作精简linux的系统磁盘上建立挂载点

1.接下来创建磁盘系统,都为ext3格式[root@localhost~]# mkfs -t ext3 /dev/sdb1
[root@localhost~]# mkfs -t ext3 /dev/sdb2
创建挂载点,以放置相关的文件,比如init,rc.c下的三个文件等等
[root@localhost~]# mkdir /mnt/boot
[root@localhost~]# mkdir /mnt/root
[root@localhost~]# mount /dev/sdb1 /mnt/boot/
[root@localhost~]# mount /dev/sdb2 /mnt/root/

第二阶段 -----》创建启动加载器grub

1.运用grub-install命令创建grub--root-directory=DIR install GRUB images under the directory DIR instead of the rootdirectory[root@localhost ~]# grub-install --root-directory=/mnt/dev/sdb他会试图在你指定的目录下面,找到一个boot目录,来创建grub的文件夹,后面指的肯定是在哪个一硬盘上来创建。最后使用grub命令创建MBR
grub> root(hd1,0) //因为是本机的第二块磁盘,所以hd1
Filesystem type is ext2fs, partition type 0x83

grub> setup(hd1)
Checking if "/boot/grub/stage1"exists... no
Checking if "/grub/stage1" exists...yes
Checking if "/grub/stage2" exists...yes
Checking if "/grub/e2fs_stage1_5"exists... yes
Running "embed /grub/e2fs_stage1_5(hd1)"... 15 sectors are embedded.
succeeded
Running "install /grub/stage1 (hd1) (hd1)1+15p (hd1,0)/grub/stage2 /grub/grub.conf"... succeeded

Done.

2.查看,是否安装完成,发现安装的目录中并没有,grub.conf配置文件,说明需要我们手动创建。[root@localhost ~]# ll/mnt/boot/drwxr-xr-x 2 root root 1024 07-11 01:51 grubdrwx------ 2 root root12288 07-11 01:47 lost+found可以看到这些说明文件,和描述文件[root@localhost ~]# ll/mnt/boot/grub/-rw-r--r-- 1 root root 45 07-11 01:51 device.map-rw-r--r-- 1 root root 7584 07-11 01:51 e2fs_stage1_5-rw-r--r-- 1 root root 7456 07-11 01:51 fat_stage1_5-rw-r--r-- 1 root root 6720 07-11 01:51 ffs_stage1_5-rw-r--r-- 1 root root 6720 07-11 01:51 iso9660_stage1_5-rw-r--r-- 1 root root 8192 07-11 01:51 jfs_stage1_5-rw-r--r-- 1 root root 6880 07-11 01:51 minix_stage1_5-rw-r--r-- 1 root root 9248 07-11 01:51 reiserfs_stage1_5-rw-r--r-- 1 root root 512 07-11 01:51 stage1-rw-r--r-- 1 root root104988 07-11 01:51 stage2-rw-r--r-- 1 root root 7072 07-11 01:51 ufs2_stage1_5-rw-r--r-- 1 root root 6272 07-11 01:51 vstafs_stage1_5-rw-r--r-- 1 root root 8904 07-11 01:51 xfs_stage1_5
我们可以对比一下宿主机虚拟机/boot/grub目录下的文件-rw-r--r-- 1 root root 63 07-10 23:32 device.map-rw-r--r-- 1 root root 7584 07-10 23:32 e2fs_stage1_5-rw-r--r-- 1 root root 7456 07-10 23:32 fat_stage1_5-rw-r--r-- 1 root root 6720 07-10 23:32 ffs_stage1_5-rw------- 1root root 598 07-10 23:32 grub.conf-rw-r--r-- 1 root root 6720 07-10 23:32 iso9660_stage1_5-rw-r--r-- 1 root root 8192 07-10 23:32 jfs_stage1_5lrwxrwxrwx 1 root root 11 07-10 23:32 menu.lst -> ./grub.conf-rw-r--r-- 1 root root 6880 07-10 23:32 minix_stage1_5-rw-r--r-- 1 root root 9248 07-10 23:32 reiserfs_stage1_5-rw-r--r-- 1 root root 32428 2007-01-05 splash.xpm.gz-rw-r--r-- 1 root root 512 07-10 23:32 stage1-rw-r--r-- 1 root root104988 07-10 23:32 stage2-rw-r--r-- 1 root root 7072 07-10 23:32 ufs2_stage1_5-rw-r--r-- 1 root root 6272 07-10 23:32 vstafs_stage1_5-rw-r--r-- 1 root root 8904 07-10 23:32 xfs_stage1_5
编辑grub引导程序【先手动创建一个 ,conf文件】
[root@localhostboot]# vim /mnt/boot/grub/grub.conf
default=0
timeout=5
title redhat linux for lining 【做一个标签】
root (hd0,0) 【指明引导分区所在的硬盘,其实本来是hd(1,0)在我们这个系统中,但是当我们把这个硬盘放到我们想要的linux系统中的时候使用,他就成为了第一块硬盘了,所以肯定要标志为第一块硬盘】kernel /vmlinuz-2.6.18-164.el5 ro root=/dev/sda2quiet【指明内核的位置,而且以只读的方式执行,内核文件】initrd /initrd.gz 【驱动】
【在写内核 与initrd的文件时,如果记不清名字,可以在vim 命令模式 .!ls

/mnt/boot/vmlinuz* 把名称显示出来,它就自动写到文件里,但是需要做小小的改动】3.处理内核,由于用的是虚拟机,硬件设施都一样,不用更改内核,直接复制

[root@localhost~]# cp /boot/vmlinuz-2.6.18-164.el5 /mnt/boot/

4.复制驱动模块
[root@localhostabc]# zcat /boot/initrd-2.6.18-164.el5.img | cpio –id
查看init服务,并且解压缩到abc目录下【abc目录手动创建的】
[root@localhostabc]# ll
total32
drwx------2 root root 4096 Jul 11 02:13 bin
drwx------3 root root 4096 Jul 11 02:13 dev
drwx------2 root root 4096 Jul 11 02:13 etc
-rwx------1 root root 2536 Jul 11 02:13 init
drwx------3 root root 4096 Jul 11 02:13 lib
drwx------2 root root 4096 Jul 11 02:13 proc
lrwxrwxrwx1 root root 3 Jul 11 02:13 sbin ->bin
drwx------2 root root 4096 Jul 11 02:13 sys
drwx------2 root root 4096 Jul 11 02:13 sysroot
这里面有一个很重要的目录,就是lib,里面放着许多模块,以.ko结尾
[root@localhostabc]# ll lib
total1196
-rw-------1 root root 30644 Jul 11 02:13ata_piix.ko
-rw-------1 root root 17908 Jul 11 02:13 dm-log.ko
-rw-------1 root root 11188 Jul 11 02:13dm-mem-cache.ko
-rw-------1 root root 8808 Jul 11 02:13dm-message.ko
-rw-------1 root root 75384 Jul 11 02:13 dm-mod.ko
-rw-------1 root root 74020 Jul 11 02:13dm-raid45.ko
-rw-------1 root root 18512 Jul 11 02:13dm-region_hash.ko
-rw-------1 root root 38980 Jul 11 02:13ehci-hcd.ko
-rw-------1 root root 146792 Jul 11 02:13 ext3.ko
drwx------2 root root 4096 Jul 11 02:13 firmware
-rw-------1 root root 72180 Jul 11 02:13 jbd.ko
-rw-------1 root root 189932 Jul 11 02:13 libata.ko
-rw-------1 root root 96456 Jul 11 02:13mptbase.ko
-rw-------1 root root 43256 Jul 11 02:13mptscsih.ko
-rw-------1 root root 27656 Jul 11 02:13 mptspi.ko
-rw-------1 root root 29016 Jul 11 02:13ohci-hcd.ko
-rw-------1 root root 177032 Jul 11 02:13 scsi_mod.ko
-rw-------1 root root 31564 Jul 11 02:13scsi_transport_spi.ko
-rw-------1 root root 30412 Jul 11 02:13 sd_mod.ko
-rw-------1 root root 30024 Jul 11 02:13uhci-hcd.ko

init脚本中,放置了 一些模块的启用方法。这里做精简linux时,要加载相应的驱动,但是要更改一些东西
87#resume LABEL=SWAP-sda3 关于swap分区的,但是我们在新的linux中不需要它,注释掉 这一行
!!init中还有很多,内容,按照不同的系统环境,和硬件环境要做不同的更改。[root@localhostabc]# find . | cpio -o -H newc --quiet | gzip -9 -n >/mnt/boot/initrd.gz
将更改后的驱动文件压缩 ,放置到新的boot目录下

在精简的linux系统下,建立相应的文件目录。
[root@localhostroot]# mkdir bin boot dev etc home lib media misc mnt net opt proc root sbinselinux srv sys tmp usr var
还有三个经常有的目录
[root@localhostroot]# mkdir usr/bin
[root@localhostroot]# mkdir usr/sbin
[root@localhostroot]# mkdir etc/rc.d

第三阶段:
关于init服务
1.将init文件拷贝到linux精简系统的硬盘下面,在现在的环境中就是/mnt/sbin/init同时,因为init是一个可执行文件,他还有有一些执行的时候的一些库文件【注意啦:/bin里面一般是普通可执行程序,而/sbin里多为系统管理程序和服务程序 s应该是system这个单词】
拷贝库文件
[root@localhostroot]# which init //which查看 该文件的路径
/sbin/init
[root@localhostroot]# ldd /sbin/init //ldd 显示所依赖的共享库文件
linux-gate.so.1 => (0x0097d000)
libsepol.so.1 => /lib/libsepol.so.1(0x00a94000)
libselinux.so.1 => /lib/libselinux.so.1(0x00a7a000)
libc.so.6 => /lib/libc.so.6(0x00110000)
libdl.so.2 => /lib/libdl.so.2(0x00a3b000)
/lib/ld-linux.so.2 (0x008ac000)
拷贝init的动态库文件
[root@localhostroot]# cp /lib/libsepol.so.1 /mnt/root/lib/
[root@localhostroot]# cp /lib/libselinux.so.1 /mnt/root/lib/
[root@localhostroot]# cp /lib/libc.so.6 /mnt/root/lib/
[root@localhostroot]# cp /lib/libdl.so.2 /mnt/root/lib/
[root@localhostroot]# cp /lib/ld-linux.so.2 /mnt/root/lib/
也可以添加我们要用到的三个指令 ls bash cat的应用,并分别拷贝链接库文件
还有将/bin/ls /bin/bash /bin/cat 也拷贝到 /mnt/root/bin/下
inittab文件
si::sysinit:/etc/rc.d/rc.sysinit

l0:0:wait:/etc/rc.d/rc0
l6:6:wait:/etc/rc.d/rc6
简易的系统,我们先只用这三条
rc.sysinit文件
/mnt/root/etc/rc.d 编辑一个 rc.sysinit文件
#!/bin/bash
echo-e "\033[31m "MY LINUX for lining \033[0m"
/bin/bash
[root@localhostrc.d]# chmod a+x rc.sysinit 给他一个可执行权限
在这里要用到/bin/bash 所以千万不要忘把/bin/bash 拷贝到 /mnt/root/bin下

sync 将内存中的信息,更新到硬盘中




就这样 一个专属自己的linux就创建好了,如果我们想用什么功能,可以以后再添加。这些问题我们下次再说。。。。不晓得对你对linux的启动流程是不是有了更深的了解。。

在后面添加一些陌生命令的解释:
LDD:

1.在制作自己的发行版时经常需要判断某条命令需要哪些共享库文件的支持,以确保指定的命令在独立的系统内可以可靠的运行;
在Linux环境下通过ldd命令即可实现,在终端下执行:
ldd /bin/ls //ldd命令通常使用"-v"或"--verbose"选项来显示所依赖的动态连接库的尽可能的详细信息。
即可得到/bin/ls命令的相关共享库文件列表:
libtermcap.so.2 => /lib/libtermcap.so.2 (0x4001c000) libc.so.6 => /lib/libc.so.6 (0x40020000) /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
注意:在 ldd 命令打印的结果中,“=>”左边的表示该程序需要连接的共享库之 so 名称,右边表示由 Linux 的共享库系统找到的对应的共享库在文件系统中的具体位置。默认情况下,/etc/ld.so.conf 文件中包含有默认的共享库搜索路径。

ZCAT:
zcat 命令允许用户扩展并查看压缩文件而 不用将该文件解压。zcat 命令并不重命名扩展的文件,也不除去 .Z 的扩展名。zcat 命令将扩展输出写入标准输出。

CPIO:
cpio是用来建立、还原备份档的工具程序,它可以加入、解开cpio或tar备份档内的文件。

-o :将数据copy到文件或设备上-i :将数据从文件或设备上还原到系统中-t :查看cpio建立的文件或设备内容-c :一种比较新的portable format方式存储-v :在屏幕上显示备份过程中的文件名-B :让预设的blocks可以增加到5120bytes,默认是512bytes,这样可以使备份速度加快-d :自动建立目录,这样还原时才不会出现找不到路径的问题-u :更新,用较新的文件覆盖旧的文件
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息