手动制作mini linux详细步骤—之一

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了手动制作mini linux详细步骤—之一相关的知识,希望对你有一定的参考价值。

8.2.1、mini linux内核编译

实验目的:

对Linux内核以非模块化手动编译,并借助busybox安装根文件系统,来制作最小化的linux系统。所谓非模块化,就是将各种所需的硬件驱动、支持的文件系统等直接编译进内核,所以initramfs也就不需要了,对于网卡驱动,我们采用模块化编译,当然也可以根据自己网卡型号,直接将驱动编译进内核;最终在我们的mini linux上能通过DHCP自动获取ip并实现基于dropbear的远程终端登录。

实验环境:

操作系统:centos6.8(x86_64)

Linux内核版本:3.10.107

虚拟机:VirtualBox

GCC版本:4.4.7

 

1)安装前准备

官网下载内核及安装开发包组:

[[email protected] ~]# wget https://cdn.kernel.org/pub/linux/kernel/v3.x/linux-3.10.107.tar.xz

[[email protected] ~]# yum groupinstall"Development tools" "Server Platform Development" -y

[[email protected] ~]# yum install -y ncurses

[[email protected] ~]# yum install bc-y

2)解压缩

[[email protected] ~]# tar xf linux-3.10.107.tar.xz -C /usr/src

[[email protected] ~]# cd /usr/src

[[email protected] src]# ln -s linux-3.10.107.tar.xz linux

[[email protected] src]# cd linux

3)编译内核

先运行make help可以查看编译帮助,这里我们先运行make allnoconfig,对所有默认加载项全部设置为no,执行该命令后即在linux内核顶层目录下生成有.config文件。

[[email protected] linux]# make allnoconfig

[[email protected] linux]# make menuconfig

[*] 64-bit kernel                             ;64位

[*] Enableloadable module support  --->        ;支持模块装载

    [*]   Module unloading                 ;支持模块卸载

Processor type and features  --->

  [*] Symmetric multi-processing support     ;对称多处理器支持

    Processor family (Generic-x86-64) --->

      (X) Generic-x86-64                   ;处理器系列

[*] Networking support --->                  ;网络支持

     Networking options  --->

      <*> Packet socket

      [*]   IP:DHCP support      ;添加对dhcp的支持

[*]   IP: BOOTP support

[*]   Network packet filtering framework(Netfilter)  --->

      [*]   TCP/IP networking

      [*]   IP: multicasting

      [*]   IP: advanced router 

       [*]  IP: kernel level autoconfiguration

   Bus options (PCI etc.)  --->

     [*] PCI support                         ;支持PCI总线

查看主机硬盘型号,根据型号在内核设置对应的驱动:

[[email protected] ~]# lspci

技术分享

   [*]Enable the block layer  --->

Device Drivers --->

   Generic DriverOptions  --->

       [*] Maintain a devtmpfs filesystem tomount at /dev

       [*] Automount devtmpfs at /dev, afterthe kernel mounted the rootfs

       上面两项在于将内核探测到的硬件信息输出至/dev目录;

   [*]  Network device support  --->      ;网络设备驱动支持

       [*]  Ethernet driver support (NEW) --->

          [*]  Intel devices

          <M>  Intel(R) PRO/1000 Gigabit Ethernet support ;编译为模块

   <*> Serial ATA and Parallel ATA drivers --->  ;支持SATA驱动

       [*]   ATA ACPI Support

         <*>   AHCI SATA support

SCSI devicesupport  --->               ;支持SCSI驱动

       -*- SCSI device support

       <*> SCSI disk support

[*] Fusion MPTdevice support  --->      ;支持SCSI驱动

       <*>   Fusion MPT ScsiHost drivers for SPI

       <*>   Fusion MPT misc device (ioctl) driver

         [*]    Fusion MPT logging facility

     Input device support  --->

          <*>  Mouse interface            ;鼠标接口

          [*]  Keyboards  --->

             <*>   AT keyboard (NEW)       ;标准键盘

          [*]  Mice  --->                 ;鼠标支持

       [*]USB support  --->

           <*>  Support for Host-side USB

           <*>   EHCI HCD (USB 2.0) support           ;USB2.0

<*>   xHCI HCD (USB 3.0) support           ;USB3.0

<*>   OHCI HCD support                   ;USB1.0

<*>   UHCIHCD (most Intel and VIA) support  ;USB1.0

Executable file formats / Emulations  --->

   [*] Kernel support for ELF binaries        ;支持Linux的ELF可执行程序

   <*> Kernel support for scriptsstarting with #! ;支持脚本程序

4)开始编译内核

[[email protected] linux]# make -j 4 bzImage

如果能成功编译,则在编译完成后,内核文件保存在:arch/x86/boot/bzImage

技术分享


[[email protected] linux]# sync  

5)添加一块新硬盘并安装grub

步骤如下:

①  、先将/dev/sdb按照基本分区分为3个:boot,swap(可无需添加),/,并在上面制作对应的文件系统,比如ext4;

②  、在当前宿主机系统上的/mnt目录下创建名为boot,sysroot(该目录下还包含linux系统所需的各子目录,如:etc,bin,sbin...)的目录;

③  、挂载/dev/sdb1至宿主机的/mnt/boot目录,作为文件系统访问入口;

④  、挂载/dev/sdb2至宿主机的/mnt/sysroot目录,作为文件系统访问入口;

⑤  、在宿主机上运行如下命令:

# grub-install --root-directory=/mnt/dev/sdb,该步骤就将grub安装到了宿主机第2 块磁盘(/dev/sdb)的mbr并安装了stage1_5和stage2;

⑥  、拷贝已编译好的内核:/usr/src/linux/arch/x86/boot/bzImage至/mnt/boot/目录;

⑦  、新增文件/mnt/boot/grub/grub.conf,并添加如下内容:

   default=0

   timeout=5

   title Mini Linux

         root (hd0,0)

         kernel /bzImage ro root=/dev/sda2 init=/sbin/init

⑧  、使用bincp脚本拷贝bash程序至/mnt/sysroot/bin/目录下,bincp脚本会自动拷贝二进制文件及其所依赖的库文件到/mnt/sysroot目录;

下面为bincp.sh脚本源码:

#!/bin/sh
sysdir=/mnt/sysroot

[ -d $sysdir ] || mkdir -p $sysdir
while : 
do
  echo -n "Please enter a binary executable program[q for quit]:"
  read prog
  if [ "$prog" = "quit" ] || [ "$prog" = "q" ] ;then
    break
  fi
  if which --skip-alias "$prog" &>/dev/null; then
    if [ -f ${sysdir}$(which --skip-alias $prog) ];then
      echo "File ${sysdir}$(which $prog) exists" 
      continue 
    else
      mkdir -p $(dirname ${sysdir}$(which --skip-alias $prog)) &>/dev/null
      cp $(which --skip-alias $prog) ${sysdir}$(which --skip-alias $prog)
      ldd $(which --skip-alias $prog) | while read line
      do
        var1=${line#*=>}
var2=${var1%(*}
var3=$(echo $var2|sed -r ‘s/^[[:space:]]?//‘)
if [ -n "$var3" ] && [ ! -d $(dirname ${sysdir}$var3) ];then
 mkdir -p $(dirname ${sysdir}$var3)
fi
[ -n "$var3" ]  && cp $var3 ${sysdir}$var3
      done
    fi
  else
    echo "Wrong binary executable program"
    continue
  fi
done

为了测试我们上面安装的grub以及编译好的linux内核,再配合移植到mini linux上的bash,为了测试其能否正常工作,这里我们再手动创建一个init程序进行测试。

新增init文件在/mnt/sysroot/sbin/init:

[[email protected] sysroot]# vi /mnt/sysroot/sbin/init

#!/bin/bash

mount -n -t proc proc /proc

mount -n -t sysfs sys /sys

mount -n -t ext4 /dev/sda1 /boot

mount -n -t ext4 -o remount,rw /dev/sda2 /

[[email protected] sysroot]# chmod +x /sbin/init

上面的init脚本在linux内核完成驱动加载后即为执行第一个程序:init,该程序可为二进制格式的ELF也可为上面编写的init脚本。

⑨  在宿主机系统上测试安装在/dev/sdb磁盘上的bash是否可用,使用命令: chroot /mnt/sysroot

⑩  重启宿主机,在Bios界面调整磁盘开机顺序:将第2块磁盘调整为第一个开机启动项即可。

在Mini Linux上启动后即可进入Bash,如果/sbin/init未能执行成功,也可手动挂载如下文件系统:

bash-4.1# mount -n -t ext4 -oremount,rw /dev/sda2 / ;重新挂载根文件系统,使其可写

bash-4.1# mount -n -t ext4 /dev/sda1/boot  ;将boot分区挂载至/boot目录

bash-4.1# mount -n -t proc proc /proc

bash-4.1# mount -n -t sysfs sys /sys

bash-4.1# cd /proc

bash-4.1# cat mounts

 

如果开机mini linux系统能进入bash提示符,则表明上面的步骤没有问题,下一步就该为mini linux系统定制根文件系统了:编译、安装busybox。

8.2.2、mini linux根文件系统:busybox编译安装

Mini Linux:kernel+busybox+dropbear

busybox提供了非常丰富的用户空间程序,可以在编译busybox时选择静态方式编译,这样就不依赖于库文件了,其通过一个静态编译的二进制程序以各种软链接(或者硬链接,脚本)的形式提供丰富多样的小程序。由于通过静态编译需要依赖于glibc-static,所以编译busybox前需要先安装此程序。

busybox编译安装步骤:

1)  下载busybox源码包:

官网地址:https://busybox.net/

busybox-1.23.0版本地址:

https://busybox.net/downloads/busybox-1.23.0.tar.bz2

2)  解压缩、编译

[[email protected] ~]# yum install glibc-static -y          ;安装依赖库

[[email protected] ~]# tar xf busybox-1.23.0.tar.bz2

[[email protected] ~]# cd busybox-1.23.0

具体编译步骤可通过查看busybox根目录下INSTALL文件查看:

[[email protected] busybox-1.23.0]# less INSTALL

技术分享


从文档可以看出编译分为三步:make menuconfig, make ,make install这点与编译安装kernel比较类似。

配置选项中比较关键的一项就是确定以静态方式编译:

Busybox Settings --->BuildOptions --->[*] Build BusyBox as a static binary (no shared libs)

另外一个选项是配置安装后的程序文件存放位置:

BusyboxSettings--->Installation Options ("make install" behavior)--->(./_install) BusyBox installation prefix

从默认配置可以看出,安装完之后的程序保存在busybox顶层目录下名为_install的目录,安装完后可将该目录下生成的所有程序文件拷贝至需要的根文件系统上,如/mnt/sysroot。

另外,为了添加对dhcp客户端的支持,需要开启udhcp:

Networking Utilities --->  [*] udhcp client (udhcpc)


下面进入busybox选项配置界面:

[[email protected] busybox-1.23.2]# make menuconfig

技术分享


上图是一个基于ncurses的文本配置界面,可以根据需要对busybox各选项进行配置。

最后执行编译和安装指令:

[[email protected] busybox-1.23.2]# make && make install

3)  拷贝程序至mini linux根文件系统

[[email protected] busybox-1.23.2]# mount /dev/sdb2 /mnt/sysroot

[[email protected] busybox-1.23.2]# cp -a _install/* /mnt/sysroot

[[email protected] busybox-1.23.2]# cd /mnt/sysroot

[[email protected] sysroot]# rm -f linuxrc

创建根文件系统下其它所需目录,可用如下脚本生成:

[[email protected] sysroot]# sh createDirs.sh  ;运行脚本生成根文件系统下所需其它目录

#!/bin/sh

#内核版本

kernel_vers="3.10.107"

for dir in etc/{rc.d,init.d,sysconfig/modules} home var/{log,lib,lock,run,lastlog} tmp root usr/{local,src,bin,sbin,lib,lib64,include,etc,share} bin sbin lib/modules/${kernel_vers}/kernel/drivers/net/e1000 lib64 dev/pts sys proc media mnt boot src opt

do

   if [ ! -d $dir ];then

      mkdir -pv $dir

   fi

done

touch lib/modules/${kernel_vers}/modules.dep

chmod 1777 ./tmp

最后在mini linux根文件系统上成功生成用户空间程序:

[[email protected] sysroot]# ls

技术分享


测试安装之后的busybox程序是否可用:

[[email protected] sysroot]# chroot /mnt/sysroot/ /bin/ash

技术分享


注意:busybox上的shell是能兼容bash的ash,如果想使用bash,则用bincp脚本拷贝至/mnt/sysroot。

4)  创建、配置mini linux文件系统上etc/inittab和etc/rc.d/rc.sysinit

根据linux系统启动流程我们知道,linux内核在内存自解压运行后读取硬件信息、加载硬件驱动、以只读方式挂载根文件系统之后就执行第一个init程序,我们这里制作的mini linux的init程序是由busybox提供,其会读取根文件系统上/etc/inittab配置文件,执行/etc/rc.d/rc.sysinit系统初始化等过程。所以我们需要手动创建文件etc/inittab和etc/rc.d/rc.sysinit用于busybox的init程序读取该配置文件,以便执行系统初始化和登录控制台等功能,另外为了实现自动挂载文件系统,我们还需要创建etc/fstab文件:

配置文件:etc/inittab

[[email protected] sysroot]# vi etc/inittab

::sysinit:/etc/rc.d/rc.sysinit

tty1::respawn:/bin/sh       ;虚拟终端,ctrl+alt+F1可打开此终端

tty2::askfirst:/bin/sh        ;虚拟终端,ctrl+alt+F2可打开此终端

tty3::respawn:/bin/sh

tty4::respawn:/bin/sh

ca::ctrlaltdel:/sbin/reboot

::shutdown:/bin/umount -a -r

系统初始化脚本:etc/rc.d/rc.sysinit

[[email protected] sysroot]# vi etc/rc.d/rc.sysinit

#!/bin/sh

#设置主机名

HOSTNAME=$(/bin/hostname)

[ -f /etc/sysconfig/network ] && . /etc/sysconfig/network

if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ];then

   echo "Seting host name to localhost..."

   hostname "localhost"

else

   echo "Seting host name to $HOSTNAME..."

   hostname $HOSTNAME

fi

#打印欢迎信息

echo -e "Welcome to \033[32mMini\033[0m Linux"

#扫描/sys目录,运行mdev用于生成/dev设备文件

echo "Scan /sysand populate /dev..."

mdev -s

#生成/dev/pts目录,用于dropbear远程登录软件所用

mkdir -pv /dev/pts

#挂载/etc/fstab中的文件系统

echo "Mountingfile system in fstab..."

mount -a

#再次以读写方式挂载根文件系统

echo "Remountingroot file system rw..."

mount -t ext4 -o remount,rw /dev/sda2 /

#开机加载/etc/sysconfig/modules/*.modules模块

for file in /etc/sysconfig/modules/*.modules ; do

   [ -x $file ] && $file

done

#手动配置固定ip及默认路由,如果有用dhcp则注释掉

#echo "CoufiguringIP address to 192.168.0.119..."

#ifconfig eth0192.168.0.119 up

#ifconfig lo 127.0.0.1up

#route add default gw 192.168.0.1

#启动dropbear

echo "Startingdropbear..."

if /usr/local/sbin/dropbear ;then

   echo -e "Dropbear started \033[32m[ OK ]\033[0m"

else

   echo -e "Dropbear started\033[31m[FAILED]\033[0m"

fi

#启动udhcpc程序

echo "Starting udhcpc..."

for ifc in $(ifconfig-a|awk ‘{print $1}‘|egrep -o eth[0-9]+);do

   if ifconfig $ifc up ;then

#senddiscover最大发送5,若未能获得租约则立即退出

      if /sbin/udhcpc -t 5 -n -i $ifc ;then

         echo -e "Start udhcpc on $ifc \033[32m[ OK ]\033[0m"

      else

         echo -e "Start udhcpc on $ifc \033[31m[FAILED]\033[0m"

      fi

   else

      echo -e "Initialization interface $ifc \033[31m[FAILED]\033[0m"

   fi

done

ifconfig lo 127.0.0.1 up

 

注:mdev工具是busybox用于在系统启动时扫描/sys目录下文件并在/dev目录下自动创建设备文件,查看其使用说明如下截图:

技术分享


[[email protected] sysroot]# vi etc/fstab

proc              /proc     proc       defaults        0 0

sysfs              /sys        sysfs       defaults        0 0

/dev/sda1     /boot     ext4       defaults        00

/dev/sda2     /             ext4       defaults        00

 

至此我们已经实现mini linux两项重要功能:kernel+busybox,下面就可以创建一个新的虚拟机,添加一块我们安装有kernel+grub+busybox的硬盘,随后即可开机启动,下面是开机后的画面:

技术分享


本文出自 “11819889” 博客,请务必保留此出处http://11829889.blog.51cto.com/11819889/1966234

以上是关于手动制作mini linux详细步骤—之一的主要内容,如果未能解决你的问题,请参考以下文章

Linux 手动制作U盘系统

Linux操作系统使用RPMBUILD命令打包RPM的详细步骤

debian 9.4 安装教程 linux系统debian9.4图文详细安装步骤

Centos史上新版最详细步骤-Linux无脑命令式oracle11g静默安装

Centos7安装Nginx详细安装步骤

Redis 超详细的手动搭建Cluster集群步骤