注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

itoedr的it学苑

记录从IT文盲学到专家的历程

 
 
 

日志

 
 

Linux系统裁剪原理与实验与定制U盘Linux系统  

2014-07-28 09:37:59|  分类: linux系统知识 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

先收集整理部分成功经验到这里备查.

************************************************************

linux系统启动过程分析中理解最小linux系统的实现

************************************************************

首先此篇先大体介绍下整个系统的开机流程,再来对其一一展开进行详细的说明

第一步:首先进行开机自检POST,确认硬件正常后进入下一步.

第二步:BIOS initialization(BOOT SEQ)BIOS初始化,并按照BIOS中设定的开机启动加载设备进行依次的检测

第三步:MBR(bootloader)在BIOS检测到某一设备可以启动后,开始加载MBR上的引导程序,在linux中,引导分为2个阶段,首 先加载在MBR上的一段极其精简的启动程序,由此启动程序引导boot目录中的grub,再由grub进行具体系统的引导启动(grub是一个很强大的系 统启动引导管理软件,也可以引导window)

第三步:Kernel initialization 在由grub引导linux内核后,启动内核,由内核检测基本硬件设备装载对应驱动,并装载rootfs和启动init(/etc/inittab)

第四步:系统启动和初始化,在启动init后,才开始真正的系统启动,内核退居到后台,由init来接管整个系统的加载和启动,init会根据设定进行系统进一步的初始化,下面是init启动后进行的一系列操作

1.完成系统整体初始化:/etc/rc.d/rc.sysinit (此脚本可以细细研读)

2.启动对应级别的各个服务:/etc/rc.d/rc 利用/etc/rc.d/ec[0-6].d/目录下的所有脚本启动或者停止服务

/etc/rc.d/ec[0-6].d/下都是链接文件,链接到/etc/rc.d/init.d/下的各个脚本

3./etc/rc.local (链接到/etc/rc.d/rc.local)给用户定义的额外开机操作项

4.启动虚拟终端,验证用户登录(图形界面则调用其他如XDM来验证用户登录)

至此 系统启动完整,可以说,整个系统的启动都是靠一堆脚本来完成的

第一二步骤涉及到硬件的POST和BIOS阶段就不再细说了,从bootloader开始说起

bootloader

这是一段放置在MBR钱446字节中的一段精简的引导程序(MBR一共有512字节,后64字节既是分区表,还有最后2个字节的填充)

常见的bootloader程序有

LILO:LInux LOader 可以引导多个操作系统,但不支持大硬盘

GRUB:GRand Unified Bootloader 目前比较常见的引导加载器,这是一个分段的引导加载器,在Ubunt上用的是GRUB1.9x。

时隔10年,最新的GRUB2在昨天正式发布了.

可以在开机时进入GRUB的交互模式,直接输入参数启动系统,在这里可以输入单用户启动参数直接进入单用户模式进行密码修改等操作

之前说这是一个分段的引导程序这里来说说具体是怎么分段的

第一段:MBR

用来引导进入第二段,在完成第一段后,初始化GRUB自我初始化后,并正常启动第二段

第二段:/boot/grub

由于MBR上的引导程序只有446字节,所以能放置的内容很少,功能很弱,所以通过引导启动第二段放置在磁盘中/boot/grub目录下强大的GRUB程序,来扩展其更为强大的引导功能

此目录下的配置文件

/boot/grub/grub.conf

搬照我的配置文件来详细说明

  1. # grub.conf generated by anaconda  
  2. #  
  3. # Note that you do not have to rerun grub after making changes to this file  
  4. # NOTICE:  You do not have a /boot partition.  This means that  
  5. #          all kernel and initrd paths are relative to /, eg.  
  6. #          root (hd0,0)  
  7. #          kernel /boot/vmlinuz-version ro root=/dev/sda1  
  8. #          initrd /boot/initrd-[generic-]version.img  
  9. #boot=/dev/sda 
  10.  
  11. #以上是注释说明 
  12.  
  13. #以下是全局设定  
  14. default=0 #默认启动的系统顺序,从0开始数 
  1. timeout=5 #等待用户选择系统的超时时间  
  2.  
  3. splashimage= (hd0,0)/boot/grub/splash.xpm.gz #开机图片的位置,这里的位置,由于GRUB是直接识别硬盘的,所以和在linux的 树状文件系统要区分一下,如果在linux中boot挂载点是和单独分区,那么只要指向boot分区下的目录,不用从boot开始,直接写成splashimage=(hd0,0)/grub/splash.xpm.gz 我这里将boot和根放在同一分区,所以从boot目录开始写  
  4.  
  5. hiddenmenu #是否隐藏菜单 
  6.  
  7.   
  8.  
  9. #以下是各个引导系统的设定  
  10. title CentOS (2.6.32-220.el6.i686) #菜单显示名称  
  11.  
  12.     root (hd0,0) #内核所在分区  
  13.  
  14.     kernel /boot/vmlinuz-2.6.32-220.el6.i686 ro root=UUID=f7ba45db-7d52-407e-996d-0d7c087f7a1a rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD quiet SYSFONT=latarcyrheb-sun16 rhgb crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM #内核所在位置和需要向内核传递的参数  
  15.  
  16.     initrd /boot/initramfs- 2.6.32-220.el6.i686.img #这是一个小linux,完整,精悍。 为了防止内核中没有根系统文件的驱动产生系统启动死循环(比如 根是放在lvm设备中),先加载initrd这个精简的linux,然后内核借助这个精简的linux加载根文件系统的驱动,然后切换到真正的根文件系统 继续进行系统加载 
  17.  
  18.     password 123456 #启动此系统需要的密码,也可以放在全局设定中,表示在开机进入交互式GRUB编辑需要输入密码 

Kernel initialization

1、硬件探测

2、硬件驱动初始化(initrd)

3、挂载根文件系统(为了避免额外进程写操作破坏文件系统,所以在这里是使用只读挂载)

4、启动/sbin/init (PID:1)

在Kernel阶段,需要挂在根目录,而linux单内核系统,但它也吸收了微内核的特性,所以它包括了内核模块。

内核:/boot/vmlinuz-version 模块:/libmodules/version/

把模块集成进内核能提高效率,但也增大了内核体积,所以使用加载模块的方式提高了可管理性

这里就造就了一个问题,由于内核比较精简,所以不可能集成进很多的驱动进去,由内核初始化后是必须要加载根文件系统的,一旦根文件系统放在RAID 或LVM设备上,由于内核缺少这些高级文件系统的驱动,会导致无法加载。于是就在这里加了一层中间层,就是这里的initrd了。initrd是一个微型 的根文件系统,内置额外内核中没有的驱动模块

首先内核借助initrd加载根文件系统,然后加载真实根文件系统驱动和其它必须驱动后,切换到真正的根文件系统。所以initrd只是起到一个过渡的作用

内核初始化产生的所有信息保存在/var/log/dmesg 二进制文件,使用dmesg命令查看

init 系统初始化

加载完成内核后,启动整个系统的父进程,PID为1 的init

init接管系统后,结合/etc/initab的配置,加载各种需要的库文件,启动各个进程,比如bash,用户登录验证等......

**************************************
实验部分
*********************
总结上文:
启动一个linux所必须的有的东西有以下几个步骤:
1.bootloader:系统引导程序GRUB
2.kernel:系统内核
3.initrd:引导内核的ramdisk
4.init:系统第一个进程
5.用户接口bash
6.init,bash等程序所依赖的库文件和脚本
......
桌面版本就该启动startx了.
 
****************
实验规划流程
****************
安装bootloader-->复制kernel到硬盘-->提供initrd-->配置GRUB-->提供init,bash,等必须的软件和库文件
 
由以上流程罗列出以下所需要的一些配置文件,程序等元素
 
配置文件 /etc/inittab /boot/grub/grub.conf
脚本 /etc/rc.d/rc.sysinit
必须的程序
kernel
/sbin/init
/bin/bash
库文件:用ldd查看具体需要哪些库文件
 
最小化linux的实验设想:

在一个安装好的linux宿主机中添加一块新硬盘,在这块硬盘上安装一个微型的linux,再用另外一台虚拟机加载那块硬盘启动微型linux;

精简linux系统在虚拟机中的实现测试
 
 step1:
首先添加一块硬盘
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
 
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
 
step2:
启动宿主linux系统,对新添加的硬盘进行分区。这里分一个boot分区,一个根分区和一个swap分区
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
可以看到,boot分区用了100MB,根分区我只使用了512MB。从中可以看出这是一个极其精简的linux。SWAP分区用了128MB,所以下面我将只会使用64MB的内存来启动这个linux。

分区完成后进行格式化,命令如下
[root@localhost ~]# partprobe /dev/sdb
[root@localhost ~]# mkfs.ext2 /dev/sdb1
[root@localhost ~]# mkfs.ext3 /dev/sdb2
[root@localhost ~]# mkswap /dev/sdb3
 
step3:
在宿主机上挂在boot分区和根分区
[root@localhost ~]# mkdir /mnt/{boot,sysroot} –p
[root@localhost mnt]# mount /dev/sdb1 /mnt/boot/
[root@localhost mnt]# mount /dev/sdb2 /mnt/sysroot/
下面会将宿主系统的内核,程序等需要的文件移植到这2个目录
 
step4:
安装bootloader,这里用比较常用的grub作为引导程序
[root@localhost mnt]# grub-install --root-directory=/mnt /dev/sdb #这里指定root目录时,会自动搜寻此目录下的boot目录,此命令就直接将grub全部安装完成,包括第一段的MBR和第二段放置在boot目录下的 grub程序
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后,等放置好内核后再回来配置grub
 
step5:
在根目录下移植系统必须的一些基本的程序
首先创建根目录下所必须的目录
[root@localhost sysroot]# mkdir -p root home proc sys dev etc/rc.d bin sbin lib var tmp opt boot misc mnt media usr
然后先移植init这个系统父进程,这个进程的配置文件为/etc/inittab,加载配置文件后会执行/etc/rc.d/rc.sysinit这个系统初始化脚本来对系统进行一系列的操作
注意移植的时候要移植到相对应的目录
[root@localhost sysroot]# cp /sbin/init /mnt/sysroot/sbin/
除了主程序,还要移植相应的库文件,init所依赖的库文件可以使用ldd命令来查看
[root@localhost sysroot]# ldd /sbin/init
    linux-gate.so.1 =>  (0x00ca5000)
    libnih.so.1 => /lib/libnih.so.1 (0x00514000)
    libnih-dbus.so.1 => /lib/libnih-dbus.so.1 (0x00a1e000)
    libdbus-1.so.3 => /lib/libdbus-1.so.3 (0x006a9000)
    libpthread.so.0 => /lib/libpthread.so.0 (0x00d92000)
    librt.so.1 => /lib/librt.so.1 (0x0020e000)
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x005e1000)
    libc.so.6 => /lib/libc.so.6 (0x00217000)
    /lib/ld-linux.so.2 (0x0080c000)
查询到所需的库文件后,将这些库文件移植到对应的目录。
[root@localhost sysroot]# cp /lib/libnih.so.1 /lib/libnih-dbus.so.1 /lib/libdbus-1.so.3 /lib/libpthread.so.0 /lib/librt.so.1 /lib/libgcc_s.so.1 /lib/libc.so.6 /mnt/sysroot/lib/
 
用同样的方法再移植bash
[root@localhost sysroot]# cp /bin/bash /mnt/sysroot/bin/
[root@localhost bin]# ln -s bash sh #不要忘了为bash创建链接文件
[root@localhost sysroot]# ldd /bin/bash
    linux-gate.so.1 =>  (0x004c4000)
    libtinfo.so.5 => /lib/libtinfo.so.5 (0x00e05000)
    libdl.so.2 => /lib/libdl.so.2 (0x00c1d000)
    libc.so.6 => /lib/libc.so.6 (0x00110000)
    /lib/ld-linux.so.2 (0x00954000)
[root@localhost sysroot]# cp /lib/libtinfo.so.5 /lib/libdl.so.2 /lib/ld-linux.so.2 /mnt/sysroot/lib/
/lib/libc.so.6这个库文件是init和bash都需要使用到的,之前移植init时已经cp过去了,这次就不用重复cp了
其它需要用到的程序都可以使用这种方法进行移植,这里只提供了最基本的bash,其它程序可以按照自己的需要进行移植
这里我再移植了一个ls命令,步骤这里就不再罗列出了,等制作好后登录到这个微型linux后,出了bash内置的命令外,我将只能在bash下使用ls命令
 
之前移植了init后,还没有创建init的配置文件,接下来就先创建init配置文件inittab
[root@localhost bin]# vim /mnt/sysroot/etc/inittab
写入下面2行
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
表示默认启动的运行级别为3,和系统开机时初始化脚本的位置
创建系统初始化脚本
[root@localhost bin]# vim /mnt/sysroot/etc/rc.d/rc.sysinit
#!/bin/bash
#
echo -e "\t hello world ,welcome to the mini linux by lustlost"
/bin/bash
 
[root@localhost bin]# chmod +x /mnt/sysroot/etc/rc.d/rc.sysinit #不要忘了给脚本加上执行权限
 
step6:
[root@localhost dev]# yum groupinstall "Development Libraries" -y
[root@localhost dev]# yum groupinstall "Development Tools" -y
好了,程序都移植好了,下面就可以移植内核和initrd了
我们直接使用宿主机上的内核(之前忘了说了,宿主机是最新的CentOS6.2 minimal版本,使用的是内核版本是2.6.32-220.el6.i686)
[root@localhost ~]# cp /boot/vmlinuz-2.6.18-308.el5 /mnt/boot/vmlinuz #内核的移植很简单,直接cp就行了
接下来要移植引导内核的initrd.img了。如果宿主机和要移植的微型linux的分区不一样的话,解包initrd编辑一下里面的init修改这一行
mkrootdev -t ext3 -o defaults,ro /dev/sda2
确保这一行指定的根文件系统是对应的,然后重新打包
[root@localhost ~]# zcat /boot/initrd-2.6.18-164.el5.img | cpio –id #解包命令
[root@localhost tmp]# find . | cpio -o -H newc --quiet | gzip > /mnt/boot/initrd.gz #重新打包命令
然后继续移植......
我这里宿主机和微型linux分区是一样的,所以就重新打包演示了
 
[root@localhost tmp]# cp /boot/initrd-2.6.18-308.el5.img /mnt/boot/initrd.img
step7:
移植好内核和initrd,就可以配置grub的引导配置文件了
[root@localhost ~]# vi /mnt/boot/grub/grub.conf
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
 
OK ,历经千辛万苦,有工作全部就绪,我们开始新建一个虚拟机加载制作好的微型linux的硬盘,看看能不能启动起来
创建自定义虚拟机,使用刚刚在宿主机上制作的,上面放置着微型linux的硬盘
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
看到了么?一个配置极其精简的虚拟机,只搭载了64MB的内存,其余的配置能删的都删了。

step8:
好了,开始启动一下这个微型linux
开机grub启动菜单
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
初始化各种硬件
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
成功进入系统
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
使用一下ls命令
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
进入到bin目录下,只有bash和ls这2个程序,想要移植其它程序按照上面的方法进行移植就行了
Linux系统裁剪原理与实验 - itoedr - itoedr的it学苑
 
至此,一个微型的linux的创建成功,只有64MB的内存就启动起来了,各种扩展功能就可以按照自己的需求自由定制了.
附:
*************************
定制U盘Linux系统的案例
*************************
::方法一

   1.把U盘分成一个MSDOS的分区(fdisk )并格式化(mkfs.msdos)
   2. 复制镜像文件和镜像文件中的isolinux目录到U盘中并更名为syslinux  
   3. 将syslinux目录中的isolinux.cfg更名为syslinux.cfg;并修改其中的配置项,如append ks=hd:sdb1:/ks.cfg initrd=initrd.img
   4. 以anaconda-ks.cfg 为模板定制自己的ks文件并拷贝到u盘根目录 ,ks中注意安装方式为 harddrive --partition=sdb1 --dir=(dir后面可省略,指定映像文件位置)
  5. 在win平台执行 syslinux.exe -a -m -d -g:  写入mbr(g:为u盘盘符)
   6. ok u盘引导自动安装系统。

::方法二

  1.把U盘分成一个ext3的分区(fdisk )并格式化(mkfs.ext3)
  2. 在u盘中创建一个boot和iso目录,复制镜像文件到iso目录,复制映像中isolinux目录下的vmlinuz和initrd.img到U盘boot目录下,并添加grub.conf菜单文件到boot目录。
grub.conf文件为:
tiltle install Linux
root(hd0,0)
kernel /boot/vmlinuz
initrd /boot/initrd.img   ks=hd:sdb1:/ks.cfg
  3. 以anaconda-ks.cfg 为模板定制自己的ks文件并拷贝到u盘根目录 ,ks中注意安装方式为 harddrive --partition=sdb1 --dir=/iso(dir后面可省略,指定映像文件位置)
4. 安装mbr到u盘,grub-install --no-floppy –root-directory=/mnt /dev/sdb   
  5. ok u盘引导自动安装系统。

此外分析ubuntu的live-cd也是一个好办法.
  评论这张
 
阅读(168)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017