• 打造个人专属的微型Linux具体实现篇


    [日期:2012-07-09]
     
    这期间在制作过程中个人也遇到了些许问题,所以断断续续的才把此篇写完。
    问题是在initrd阶段识别不到磁盘设备,挂载不了rootfs,谷歌了查了很多资料都没得到解决。刚开始用的是CentOS6.2的内核,6.2更新了initrd,里面的init脚本和以前有很大的不同,于是我换到5.8的内核,还是不行,又切换到5.4的内核,问题依然存在。火大,又自己去官网下载了2.6.18的内核源代码,基于安装的centos5.4的config重新编译了一次(编译太耗时间),问题依旧存在。。。那时候真的是特别无语。最后还是找马哥交流了下,在这里还要多谢马哥的指导,找到了问题的关键所在。
    总结在上一篇的linux启动原理(见 http://www.linuxidc.com/Linux/2012-07/64753.htm ),我们知道要启动一个linux所必须的有的东西有以下几个
    1.bootloader:系统引导程序GRUB
    2.kernel:系统内核
    3.initrd:引导内核的ramdisk
    4.init:系统第一个进程
    5.用户接口bash
    5.init,bash等程序所依赖的库文件和脚本
     
    为了避免各位看官看的迷糊,首先先说下大概的一个流程
    整个实验的流程:安装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
     
    OK,just do it !
     
    ps:以下都在虚拟机中实现
     
     
    step1:
    首先添加一块硬盘
     
     
     
     
    step2:
    启动宿主linux系统,对新添加的硬盘进行分区。这里分一个boot分区,一个根分区和一个swap分区
     
    可以看到,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
     
     
    OK ,历经千辛万苦,有工作全部就绪,我们开始新建一个虚拟机加载制作好的微型linux的硬盘,看看能不能启动起来
    创建自定义虚拟机,使用刚刚在宿主机上制作的,上面放置着微型linux的硬盘
     
     
     
    看到了么?一个配置极其猥琐和寒酸的虚拟机,只搭载了64MB的内存,其余的配置能删的都删了。
     
    step8:
    好了,开始启动一下这个微型linux
    开机grub启动菜单
     
    初始化各种硬件
     
    成功进入系统
     
    使用一下ls命令
     
    进入到bin目录下,只有bash和ls这2个程序,想要移植其它程序按照上面的方法进行移植就行了
     
     
    至此,一个微型的linux的创建成功,只有64MB的内存就启动起来了,各种扩展功能就可以按照自己的需求自由定制了
     
    最后说下开篇说的我遇到的问题,其实很SB的一个问题,因为宿主机是CentOS6.2的系统,由于6.2中使用了比较新的initramfs,里面的脚本和以前的大不一样,于是后来使用了5.8的内核,但之前创建的minilinux的虚拟机是依照RedHat 6创建的,所以做好系统后一直启动不了。后来在马哥的提醒下重新创建了redhat 5的虚拟机,成功启动了。。。
     
    这里我想说的是,有时候一个疏漏的小细节会导致整个系统的失败。以后工作中要切记不要遗漏细节。。。细节决定成败。
     
    The End。
  • 相关阅读:
    光脚丫学LINQ(025):如何验证DBML和外部映射文件
    使用LINQ to SQL将数据从一个数据库复制到另一个数据库
    用VS2010 C#写DLL文件并且调用(原创)
    linux初识
    Run Only One Copy Of Application
    SQL Server 2008开启远程连接
    用Visual C#做DLL文件
    SQL Server代理服务无法启动的处理方法(转载)
    QTP连接Oracle
    What's AJAX?
  • 原文地址:https://www.cnblogs.com/huapox/p/3299969.html
Copyright © 2020-2023  润新知