Kernel Linux学习(一)——环境搭建

Kernel Linux学习——环境搭建

2020-08-02 20:14:19 hawkJW

  


  因为最近信息安全竞赛中经常出现Kernel Linux相关方面的习题,因此正好通过疫情这段时间学习一下Kernel Linux相关的知识。

  这一此主要介绍Kernel Linux的环境的搭建。分别需要Linux的源代码、Busybox的源代码、以及qemu模拟器


总体分析

  实际上,Linux的启动首先一定需要内核程序——其通过Linux的源代码进行下载,编译即可。

  除此之外,Linux的启动还需要根文件系统支持,因为当系统启动时,仅仅只有内核程序,需要从磁盘中加载各种模块,而这个过程需要文件系统;如果文件系统放置在磁盘中,这就成为了一个鸡生蛋、蛋生鸡的问题。因此,即在RAM上建立临时文件系统,即根文件系统,当所需模块加载完毕后再将根文件系统转移到磁盘上即可。这里通过Busybox进行构建。

  最后,如果在真机上直接进行运行,如果中间出现错误或者异常,则整个系统直接奔溃,对于运行或者调试都不方便。因此,通过模拟器运行并调试。


Linux内核

  我们首先需要下载Linux内核源代码,然后进行编译即可,其源代码的镜像文件如下链接所示https://mirrors.tuna.tsinghua.edu.cn/kernel/。我们进行下载即可,这里我选择了V4.x的4.4.72版本。

   当然,安装过程中可能会有一些依赖问题,我这里一并包括qemu等更新安装,代码如下所示

sudo apt-get install qemu build-essential libssl-dev kernel-package libncurses5-dev bison flex

   

  这里等待一段时间后,我们将下载的源代码文件进行解压,并进入对应的目录,代码如下所示

tar xf /path/to/linux-src.tar.gz
rm -rf /path/to/linux-src.tar.gz
mv /path/to/linux-src linux
cd linux

  

  然后我们需要进行编译的配置,执行如下命令

make menuconfig

  

  此时会进入编译配置的gui界面,然后我们依次选择如下的配置

——进入kernel hacking
    ——进入Compile-time checks and compiler options
        ——选择Compile the kernel with debug info
        ——选择Compile the kernel with frame pointers
    ——选中Kernel Debugging
    ——选中KGDB:Kernel Debugging
    ——关闭Write protect kernel read-only data structures

 

  退出保存后,执行如下命令

make -j 4

  这样子即完成了Kernel Linux的内核编译部分。


根文件系统编译

  下面我们将构建根文件系统,我们这里通过BusyBox来快速构建根文件系统。我们首先进行busybox的编译,其源代码的镜像链接如下图所示https://busybox.net/downloads/,这里我们选择(1.27.2版本)。下载完后进行如下的命令

tar -xf /path/to/busybox-1.27.2.tar.bz2
rm -rf /path/to/busybox-1.27.2.tar.bz2
mv /path/to/busybox-1.27.2.tar.bz2 /path/to/busybox

 

  下载并解压完毕后,我们进行编译的设置,命令如下所示

make defconfig
make menuconfig

 

  此时进入GUI界面后,我们选择如下配置

进入Busybox Settings
  ——选择Build BusyBox as a static binary(no shared libs)

 

  退出保存后,执行如下命令

make -j 4
make install

 

  这样子即完成了busybox的编译工作。然后我们继续构建根文件系统。根据一些网络资料,根文件系统至少需要包含所有支持完整Linux系统的结构和程序,目前至少需要

1.    基础文件系统结构
2.    必须的目录——/dev、/bin、/etc等  
3. 必须的程序——init4. 必须的配置文件——inittab等 5. 必须的设备文件——/dev/console6. 配置文件所需要的库文件

 

  我们创建一个目录,用来作为根文件系统的雏形,我们需要向目录内部填充数据,下面我们需要向该目录中写入构建根文件目录的内容——/dev、/proc、/etc、/sbin、/bin、/lib、/sys、/mnt以及/usr文件(有一些可以不用),其中,/proc、/mnt文件仅仅需要建立即可,内容可以为空,其构建的命令如下所示

mkdir rootfs
cd rootfs
mkdir
proc mkdir mnt
mkdir sys
mkdir tmp

   

  对于/usr、/sbin以及/bin,直接将busybox编译后的文件全部赋值即可,命令如图所示

cp -r ../busybox/_install/* ./

 

  而/dev文件包含所有设备文件,通过mknod命令创建设备文件。这里我们创建console、null、tty1设备文件,可以在自己的Linux主机上通过如下命令进行查看

ls -al /dev/

 

  根据上面的结果,可以发现其命令如下图所示

mkdir dev
sudo mknod dev/console c 5 1
sudo mknod dev/null c 1 3
sudo mknod dev/tty1 c 4 1

 

  /etc文件中包含各种设置文件,这里我们构建inittab、init.d/rcS和fstab文件。

  其中inittab文件指挥init进行进行工作,其内容如下

#/etc/inittab
::sysinit:/etc/init.d/rcS
::askfirst:-/bin/sh
::shutdown:/bin/umount -a -r

  稍微分析一下该文件的含义,所有的/etc/inittab每一行相当于一个脚本,其内容类似于id:runlevel:action:precess

这里第一行表示初始化时执行/etc/init.d/rcS文件内容;第二行表按键后进入shell;第三行表示当关闭时umount所有挂载的文件。

  可以看到,其中第一句中执行了/etc/init.d/rcS文件,则我们需要填充完善/etc/init.d/reS文件,其内容如下所示

#!/bin/sh
mount -a

  注意需要给其可执行权限。这里面的内容很简单,就是挂载所有的文件系统,至于具体如何进行挂载,其按照/etc/fstab文件中所描述的进行挂载,内容如下所示

 
  
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /dev tmpfs defaults 0 0

  这里我们需要详细说明一下挂载这个概念。实际上如果你并没有再fstab中写这些规则,也就是并没有进行如下的挂载,但是你仍然可以按照下面的流程进行内核的启动,并且仍然可以在linux中看到这两个目录,如下图所示

Kernel Linux学习(一)——环境搭建_第1张图片

 

 

  但是如果您进行了上述的挂载,然后再去观察,结果如图所示

 

 Kernel Linux学习(一)——环境搭建_第2张图片

 

   实际上,根据这个实验结果,并且配合上一些相关的网络资料,我们很容易就可以对于挂载这个概念有更深刻的了解。整个文件系统实际上相当于这样一个数据结构

union fileSystem{
    memory data;
    union fileSystem *next;
}

  如果没有进行挂载,则显示其fileSystem.data中的数据;如果挂载了话,则显示fileSystem.next中指向的数据。所以我们可以对上述现象进行合理解释——首先正如上面分析的,一定会挂载根目录,也就是这里我们创建的这些目录;如果没有挂载,则显示的就是目前信息(空);如果进行了挂载,则显示挂载的信息——这里可能有人会问,那这里挂载的信息是什么?这里一开始我也不清楚,根据我在网络上的资料,实际上其挂载的内容是Linux内核中的一些相关信息,也就是如果你不挂载,这些信息仍然存在,但你无法查看和操作,而挂载之后,你可以直接进行查看和操作。我们可以再做个实验,如果我们在一开始的sys目录下放一个README.md文件,则如果不进行挂载的话,应该会显示该文件,结果如图所示

 

  这样子,我们基本完成了目录中的数据填充,然后我们将其打包为qemu可以直接使用的根目录文件格式,命令如下

find . | cpio -o --format=newc > ../rootfs.img

 

  这里顺便说一句,cpio同样可以解压出来,其命令如下

mkdir rootfs
cd rootfs
cpio -idmv < ../rootfs.img

 

  这样子,就将前面压缩的文件重新解压到rootfs目录中

 

  最后,就完成了根文件系统的制作


启动内核

  下面,我们即利用qemu,模拟Linux内核的启动,我们需要指定一下linux内核、根文件系统以及一些设置即可,-initrd后面跟的就是根文件系统,命令如下

qemu-system-x86_64 -kernel linux/arch/x86_64/boot/bzImage -initrd rootfs.img -append "rdinit=/linuxrc"

你可能感兴趣的:(Kernel Linux学习(一)——环境搭建)