编译mini linux,手动制作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)安装前准备

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

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

[root@bbs ~]# yum groupinstall"Development tools" "Server Platform Development" -y

[root@bbs ~]# yum install -y ncurses

[root@bbs ~]# yum install bc-y

2)解压缩

[root@bbs ~]# tar xf linux-3.10.107.tar.xz -C /usr/src

[root@bbs ~]# cd /usr/src

[root@bbs src]# ln -s linux-3.10.107.tar.xz linux

[root@bbs src]# cd linux

3)编译内核

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

[root@bbs linux]# make allnoconfig

[root@bbs 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总线

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

[root@bbs ~]# lspci

6db13a1a4dfccd19b96b741fd6337cf0.png

[*]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

 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)开始编译内核

[root@bbs linux]# make -j 4 bzImage

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

668dd058a229f63c0a612fa8fb07f390.png

[root@bbs 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:

[root@bbs 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 /

[root@bbs 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源码包:

busybox-1.23.0版本地址:

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

2)  解压缩、编译

[root@bbs ~]# yum install glibc-static -y          ;安装依赖库

[root@bbs ~]# tar xf busybox-1.23.0.tar.bz2

[root@bbs ~]# cd busybox-1.23.0

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

[root@bbs busybox-1.23.0]# less INSTALL

cd09ef48e0321c8213a20656a44493e2.png

从文档可以看出编译分为三步: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选项配置界面:

[root@bbs busybox-1.23.2]# make menuconfig

62a34dc5e2fe1d5eaf452648b949925e.png

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

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

[root@bbs busybox-1.23.2]# make && make install

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

[root@bbs busybox-1.23.2]# mount /dev/sdb2 /mnt/sysroot

[root@bbs busybox-1.23.2]# cp -a _install/* /mnt/sysroot

[root@bbs busybox-1.23.2]# cd /mnt/sysroot

[root@bbs sysroot]# rm -f linuxrc

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

[root@bbs 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根文件系统上成功生成用户空间程序:

[root@bbs sysroot]# ls

fe6cb5f811f3891bf49ede29c76c468b.png

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

[root@bbs sysroot]# chroot /mnt/sysroot/ /bin/ash

34251e81456e92e8d6071aad2bc16257.png

注意: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

[root@bbs 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

[root@bbs 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目录下自动创建设备文件,查看其使用说明如下截图:

34f753e3ce1ea24587c938805a1d5909.png

[root@bbs 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的硬盘,随后即可开机启动,下面是开机后的画面:

e749387848b512c5f7580e044eea5ce8.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值