1. 程式人生 > 實用技巧 >Kernel Linux學習(一)——環境搭建

Kernel Linux學習(一)——環境搭建

Kernel Linux學習——環境搭建

2020-08-0220: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中看到這兩個目錄,如下圖所示

  但是如果您進行了上述的掛載,然後再去觀察,結果如圖所示

  實際上,根據這個實驗結果,並且配合上一些相關的網路資料,我們很容易就可以對於掛載這個概念有更深刻的瞭解。整個檔案系統實際上相當於這樣一個數據結構

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

  如果沒有進行掛載,則顯示其fileSystem.data中的資料;如果掛載了話,則顯示fileSystem.next中指向的資料。所以我們可以對上述現象進行合理解釋——首先正如上面分析的,一定會掛載根目錄,也就是這裡我們建立的這些目錄;如果沒有掛載,則顯示的就是目前資訊(空);如果進行了掛載,則顯示掛載的資訊。我們可以再做個實驗,如果我們在一開始的sys目錄下放一個README.md檔案,則如果不進行掛載的話,應該會顯示該檔案,結果如圖所示

  這樣子,我們基本完成了目錄中的資料填充,然後我們將其打包為qemu可以直接使用的根目錄檔案格式,命令如下

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

  這樣子就完成了根檔案系統的製作


啟動核心

  下面,我們即利用qemu,模擬Linux核心的啟動,我們需要制定一下linux核心、根檔案系統以及一些設定即可,-initrd後面跟的就是根檔案系統,命令如下

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