• 自制简易Linux系统



    l 要求:

    裁剪一个装载有网卡驱动可以上网并且使用到init的一个小系统

    l 准备;

    虚拟机,centos6.4

    l 步骤;

    一、在宿主机上添加一块硬盘,并为其安装grub

    1. 在宿主机上添加一块硬盘,这里添加的是sde这块硬盘。

    2. 使用fdisksde分两个区,sde1 100M)  sde22G)

    3. 创建目录/mnt/boot    /mnt/sysroot

    1
    mkdir -pv /mnt/{boot,sysroot}

    4. /dev/sde1挂载到/mnt/boot ,/dev/sde2挂载到/mnt/sysroot

    1
    2
    3
    4
    5
    6
    7
    mount /dev/sde1 /mnt/boot/
    mount /dev/sde2 /mnt/sysroot/
    [root@station57 mnt]# mount
    ......
    ......
    /dev/sde1 on /mnt/boot type ext4 (rw)
    /dev/sde2 on /mnt/sysroot type ext4 (rw)

    5. 当剪裁成功后sde2分区会当作新系统的跟分区,所以要给你sde2这个分区也就是/mnt/sysroot 这个目录创建linux系统常用的几个目录

    1
    [root@station57 sysroot]# mkdir -pv mnt proc root home cat sys lib lib64 dev media sbin tmp var

    6. 安装gurb

       注意此处的“--root-directory=/mnt”选项,sde1是挂载在/mnt/boot上边的,不要写成--root-directory=/mnt/boot

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [root@station57 mnt]# grub-install --root-directory=/mnt  /dev/sde
    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
    (hd2)/dev/sdc
    (hd3)/dev/sdd
    (hd4)/dev/sde


    7. 因为我的宿主机上有五块硬盘,所以此处列出了hd1--hd4.。我们的sde对应的硬盘是hd4,但是这个编号4仅仅对次主机有效,换到一个单独的主机上的时候就是hd0了。所以后边出来了(hd00)这样的硬盘标号。第一个0代表硬盘编号,第二个表示分区


    8. 此时硬盘sdegrub就算安装成功了,我们看一下里边的内容

    1
    2
    3
    4
    5
      [root@station57 mnt]# ls /mnt/boot/grub/
    device.map     iso9660_stage1_5   stage1           xfs_stage1_5
    e2fs_stage1_5  jfs_stage1_5       stage2
    fat_stage1_5   minix_stage1_5     ufs2_stage1_5
    ffs_stage1_5   reiserfs_stage1_5  vstafs_stage1_5


            Grub3stage


          1st stage: 位于MBR中,为了引导2nd stage

          1.5 stage: 位于boot基本磁盘分区中,为识别内核文件所在的文件系统提供文件系统识别扩展

          2nd stage: 位于boot基本磁盘分区中,GRUB的引导程序




    二、复制内核vmlinuz和内核加载部分硬件所依赖的initramfs

    1
    2
    1. [root@station57 mnt]# cp /boot/vmlinuz-2.6.32-358.el6.x86_64 /mnt/boot/
    2. [root@station57 mnt]# cp /boot/initramfs-2.6.32-358.el6.x86_64.img /mnt/boot/


    三、添加gurb的配置文件

    grub安装完成了如果不添加配置文件,那么每次启动都要手动写内核文件vmlinuz-和驱动相关的initramfs两个文件的路径,而且还要定义跟的位置,很不方便,于是就要用到gurb的配置文件grub.conf

    1
    2
    3
    4
    5
    6
    7
    [root@station57 mnt]# vim /mnt/boot/grub/grub.conf
     default=0
     timeout=5
       title CentOS (author:xuqimin)
             root (hd0,0)
             kernel /vmlinuz-2.6.32-358.el6.x86_64 ro selinux=0 root=/dev/sda2 init=/bin/bash
            initrd /initramfs-2.6.32-358.el6.x86_64.img


           在grub中,硬盘以hd开头紧跟一个数字做各磁盘设备的标记,从0开始编号

           Part表示方式:代表分区,从0开始编号


    配置文件代表的意义

      1default=#: 指定默认启动的内核或OS

      2timeout=#: 等待用户选择要启动的内核或OS的时长,单位为秒;

      3Kernel 后边给的参数为传递给内核的参数

      4Ro  表示以只读的方式挂载

      5Seliunx=0 表示不启用selinux ,因我们这里的小系统只要内核和几个简单的命令,启动不了selinux ,而gurb默认是开启selinux的,这样我们开机的时候会出现问题而无法启动系统

      6Root=/dev/sda2 表示等系统系统的时候会以sda2 ,也就是刚刚我们挂载的sde2来当作系统的根目录。




    四、编写复制命令及其对应的库的脚本,并完成命令迁移

        gurb和内核文件及驱动文件都已就绪,但是系统还只是一个只有内核的空壳而已,显然我们还不能用它做任何事情。因此我们就需要把linux中常用到的命令复制到我们制作的小系统中,以让它工作起来。

        我们知道命令是由二进制文件,极其依赖的库文件,再加上一些帮助文档组成的。而且一个命令的库文件不仅仅只有一个。所以我们单单手动复制起来的话势必会很麻烦。因此此时就需要把我们前面学到的脚本知识发挥一下,用shell脚本实现命令的复制,迁移。下边是我前几天做的复制命令的脚本。

        (脚本可能有不完善的地方,也可能在大神眼中显得很臃肿,不喜勿喷)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    #!/bin/bash
      2
      3 function EnterCommand {
      4 read -p "Enter a command:" command
      5 while true;do
      6    [[ "$command" == "quit" ]] && exit 2
      7    if which $command &> /dev/null ;then
      8          break
      9      else
     10          echo -e " 33[31mno such command,please try agiain.and quit to quit: 33[0m"
     11          read -p "Enter a command:" command
     12    fi
     13 done
     14 }
     15
     16
     17 function bincp {
     18    commandDir=`which --skip-alias $command`
     19    distintion="/mnt/sysroot$commandDir"
     20    if  [ -e $distintion ];then
     21          echo "bin of $command is already exist."
     22     else
     23       [ -d /mnt/sysroot`dirname $commandDir` ] || mkdir -p /mnt/sysroot`dirname $commandDir`
     24       cp $commandDir /mnt/sysroot`dirname $commandDir` &&  echo "the bin cp ok.." || echo "cp bin error"
     25    fi
     26 }
     27
     28
     29 function Libcp {
     30     commandLib=`ldd $commandDir | grep -o "/lib.*[[:space:]]"`
     31
     32        for i in $commandLib ;do
     33           distintionlib="/mnt/sysroot$i"
     34            if [ -e $distintionlib ];then
    5                echo "$i is exist."
     36
     37            else
     38
     39            [ -d /mnt/sysroot`dirname $i` ] || mkdir -p /mnt/sysroot`dirname $i`
     40            cp $i /mnt/sysroot`dirname $i` && echo "lib co ok.." || echo "cp lib erro "
     41            fi
     42        done
     43  }
     44
     45
     46
     47
     48 EnterCommand
     49
     50 while true;do
     51     bincp
     52     Libcp
     53     EnterCommand
     54 done


    执行这个脚本,分别将bashlscd vi cattreefdiskmvtouch,这些常用的命令复制到/mnt/sysroot中对用的路径下。


    此时将sde这块硬盘放到一个其他的电脑上就已经可以启动了,只不过有点简陋。只能在bash shell中执行cp过去的几个小命令。也没有网络功能,如果需要使用网络功能,就需要通过下边的几个步骤继续迁移网卡驱动模块了。

          新建虚拟机,把sde这块硬盘放到新虚拟机中当启动盘。(注意:使用sde这看硬盘的时候要讲原宿主机挂载)      


               无图无真像,贴个图给大家看看吧。


    wKiom1MVsgORbhfiAAHfrUo_cXc420.jpg

    wKioL1MVseqzMmpOAANfA77Ksmk044.jpg


    五、迁移e1000 网卡驱动内核模块

    系统要想上网得需要有网卡驱动。而linux中网卡驱动不是在内核中自带的,而是以模块的方式在内核中装载的,所以我们要想让我们迁移的小linu能够有网络功能还必须为其装载网卡驱动模块。

    下边列出关于管理内核模块所用到的几个命令,当然我们在做下边操作之前还需要通过上边的那个cp二进制的脚本来将几个命令cp过去,另外别忘了复制ifconfigping这些我们等会可能会用到命令了。


    1. 查找我们需要的模块在宿主机上的位置

    Lsmod:查看内核转载的模块

    Lspci:查看pci插口相关信息

    Modproc:转载相应模块

    Modproc -r :卸载模块

    Insmod:装载模块

    Rmmod:卸载模块


    有了这些命令接下来让我们找找网卡模块在哪吧。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    [root@station57 sysroot]# lsmod
    Module                  Size  Used by
    autofs4                26513  3
    8021q                  25317  0
    ipv6                  321422  96
    e1000                 170646  0
    sg                     29350  0
    ......
    ......
    dm_log                  9930  2 dm_mirror,dm_region_hash
    dm_mod                 82839  14 dm_mirror,dm_log


    上边的e1000就是我们要找的网卡模块,你是不是该问,那还是没有解决问题呀,e1000在哪呢。我们别忘了还有一个modinfo命令呢。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    [root@station57 sysroot]# modinfo e1000
    filename:       /lib/modules/2.6.32-358.el6.x86_64/kernel/drivers/net/e1000/e1000.ko
    version:        7.3.21-k8-NAPI
    license:        GPL
    description:    Intel(R) PRO/1000 Network Driver
    author:         Intel Corporation, <linux.nics@intel.com>
    srcversion:     1D4F1E82BB99EA36D320B1B
    alias:          pci:v00008086d00001000sv*sd*bc*sc*i*
    ........
    depends:    
    vermagic:       2.6.32-358.el6.x86_64 SMP mod_unload modversions
    parm:           TxDescriptors:Number of transmit descriptors (array of int)
    .....
    ......

    好大一串数据呀,反正大多数我是不懂干嘛的。暂时先不关心其他的内容吧,我们只关心这个路径在哪、还有下边的depends是此模块所依赖的别的模块。这里的e1000不依赖别的模块。

    filename:       /lib/modules/2.6.32-358.el6.x86_64/kernel/drivers/net/e1000/e1000.ko


    2. 复制该模块到我们的小型linux中安装

    1
    2
    3
      [root@station57 sysroot]# cp /lib/modules/2.6.32-358.el6.x86_64/kernel/drivers/net/e1000/e1000.ko  /mnt/sysroot/lib/modules/
    [root@station57 sysroot]# ls /mnt/sysroot/lib/modules/
    e1000.ko

    3. 挂起宿主机,开启目标主机,并用刚刚使用的sde来做启动盘开启主机。

    使用insmod 装载模块,然后就可以使用ifconfig配置ip地址了。这样我们的带有网络功能的小linux系统就做好了。


    wKiom1MVspjxGGJwAAK4dzoRe3A415.jpg

    wKioL1MVsnOTQh9aAAJ_bFPsMCo422.jpg


    l 使用init自启动服务脚本完成系统初始化

            我们的带有网络功能的小系统已经做好,但是你有没有发现每次重启后我们的网络模块都要重启装载,而且ip地址也要重新配置。这真是一件头疼的事情,有没有一个脚本可以自动化的帮我们完成这些模块的自动装载和ip的自动分配呢,当然有,init就是为了完成这个任务,但是init这个程序太过复杂,需要依赖的东西也太多,我们也不需要。那么就让我们来自己写一个脚本来代替init完成我们的小系统初始化吧。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    [root@station57 mnt]# vim /mnt/sysroot/sbin/init
    1 #!/bin/bash
      2 #
      3 echo -e " 33[31;5mI am a simple Linux, but I'll grow up soon33[0m"
      4
      5 insmod /lib/modules/e1000.ko && echo -e "Moduless e1000 loding33[60G33[32m[ ok ]33[0m "     || echo  "Moduless e1000 loging error"
      6 ifconfig lo 127.0.0.0/16 && echo -e "The ip lo add ...33[60G33[32m[ ok ]33[0m " || echo      "ip of lo add error"
      7 ifconfig eth0 172.16.20.11/16 && echo -e "The ip eth0 add ...33[60G33[32m[ ok ]33[0m "     || echo  "ip of eth0 add error"
      8   /bin/bash :::::别忘了最后启动shel呀!


    这个脚本完成了对模块e1000的自动挂载,并且自动配置ip的功能。

    不过需要注意的是,如果想让他开机自动生效,需要在grub.conf中定义,让init指向此脚本所在的路径。

    wKiom1MVstaisbJFAAEq-dTIRAE715.jpg

    wKiom1MVstnBxgKTAAP9u0MGnUo665.jpg


    ok,这样一个简单的经过剪裁的小linux已经站在了我们的面前。当然,他有待提升加强的功能还有太多。让我们在随后的日子继续学习来补充加强它吧~!!


    本文出自 “Sysinit” 博客,请务必保留此出处http://xuqimin.blog.51cto.com/3832456/1367760

  • 相关阅读:
    3.3测试复盘
    计算机网络-运输层面试题整理
    3.2专项测试复盘
    2.27专项测试复盘
    2.26排序专项测试复盘
    2.25专项测试复盘
    前端基础笔记1
    2.24专项测试复盘
    2.23专项测试复盘
    更新pip报错AttributeError: 'NoneType' object has no attribute 'bytes'
  • 原文地址:https://www.cnblogs.com/wq201703/p/6704283.html
Copyright © 2020-2023  润新知