前言:
常見 linux 內核編譯有兩種方式,一是直接在 Linux 系統上編譯得到二進制文件,并對原有 Linux 內核進行替換,即更換 Linux 內核,此方法可能因新內核有 bug 導致系統崩潰,且難以返回原版本內核而不得不重裝;第二種方法則是在模擬器中運行新的 Linux 內核,以避免對系統內核的修改。
BusyBox 是一個集成了三百多個最常用 Linux 命令和工具的軟件,因為單獨的 Linux 內核無任何用于用戶交互的 UI,所以需要通過其它工具與新編譯的Linux 內核交互。
QEMU 是以 GPL 許可證分發源碼的模擬處理器,可用于模擬常見的硬件平臺,常用于在 Linux 系統中建立虛擬機。
本文在阿里云 Ubuntu 18.04 64 位操作系統環境下編譯 ARM Linux 內核。過程中主要是用交叉編譯工具鏈 gcc-arm-linux-gnueabi 編譯系統源碼,并使用 QEMU 軟件仿真硬件平臺測試對象系統。
建議使用 root 用戶操作
本文所使用的環境:
操作系統:4.15.0-96-generic #97-Ubuntu SMP Wed Apr 1 03:25:46 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
gcc: 7.5.0
qemu: 2.11.1(Debian 1:2.11+dfsg-1ubuntu7.26)
make:GNU Make 4.1
1.工具準備
Busybox 需手動下載安裝,QEMU 等其他工具可在線安裝。
Linux內核下載:https://www.kernel.org/
本文使用5.4.45版本的,并使用清華大學鏡像
wget https://mirrors.tuna.tsinghua.edu.cn/kernel/v5.x/linux-5.4.5.tar.gz
Busybox :
wget https://busybox.net/downloads/busybox-1.28.4.tar.bz2
2.環境配置
Linux 內核編譯環境需要大量軟件包,可提前直接在線安裝,或在內核編譯的過程中安裝,若缺少安裝包,內核編譯過程中會提示缺失錯誤。以下是部分需要的軟件包,其中部分相同功能的軟件包在不同的 Linux 版本下會以不同的名字存在。
apt-get install gcc qemu qemu-system-arm gcc-arm-linux-gnueabi libncurses5-dev build-essential flex bison bc
3.編譯內核
解壓 Linux 內核文件包:
tar -xzvf linux-5.4.5.tar.gz
編譯最小文件系統:
解壓 busybox,進入目錄并編譯:
tar -jxvf busybox-1.28.4.tar.bz2
cd busybox-1.28.4
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
make menuconfig
以上內容中,“export”后是指定交叉編譯工具鏈,指定芯片框架為 ARM。如下圖所示是圖形化界面進行內核配置。
按照以下路徑配置成靜態編譯(回車進入,空格選中) :
Settings ---->
Build Options [*]Build static binary(no shared libs)
配置完畢退出后繼續完成編譯:
make install
完成后會在目錄中生成“_install”目錄,本目錄存放了編譯好的文件系統需要的命令集合,如下圖所示:
將上一步驟中生成的“_install”目錄拷貝至之前解壓后的內核目錄,進入“_install”目錄,分別創建 etc、dev、mnt、etc/init.d 等目錄。
cp -r ./busybox-1.28.4/_install ./linux-5.4.5/_install
cd ./linux-5.4.5/_install/
mkdir etc
mkdir dev
mkdir mnt6mkdir -p etc/init.d
在“_install/etc/init.d”目錄下新建“rcS”文件,并寫入以下內容:
mkdir -p /proc
mkdir -p /tmp
mkdir -p /sys
mkdir -p /mnt
/bin/mount -a
mkdir -p /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev –s
在“_install/etc”目錄創建“fstab”文件,并寫入以下內容:
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
tempfs /dev tmpfs defaults 0 0
debugfs /sys/kernel/debug debugfs defaults 0 0
在“_install/etc”目錄創建“inittab”文件,并寫入以下內容:
::sysinit:/etc/init.d/rcS
::respawn:-/bin/sh
::askfirst:-/bin/sh
::ctrlaltdel:/bin/umount -a -r
在“_install/dev”目錄中創建如下設備節點 :
mknod console c 5 1
mknod null c 1 3
完成上述設置后,在內核目錄中編譯內核 :
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabi-
make vexpress_defconfig
make menuconfig
在內核目錄下編譯內核(此步驟時間較長)
make bzImage ARCH=arm CROSS_COMPILE=arm-linux-gnueabi-
make dtbs
可能會出現“./usr/gen_initramfs_list.sh: 131: local: 1: bad variable name”的錯誤,原因是以前用的bash執行而現在使用sh。
解決辦法:131行改為 :
local dev="`LC_ALL=C ls -l "${location}"`"
編譯完成后會有如下提示,并顯示編譯后內核的存儲路徑。
4.運行 QEMU
如下所示,輸入 QEMU 啟動命令,成功啟動 QEMU,注意需指定 bzImage路徑,并注意使用當前命令與 bzImage 路徑的關系。
qemu-system-arm -M vexpress-a9 -m 256M -kernel arch/arm/boot/zImage -Append "rdinit=/linuxrc console=ttyAMA0 loglevel=8" -dtb arch/arm/boot/dts/vexpress-v2p-ca9.dtb -nographic
- 以上命令中參數含義如下;
- -M:指定硬件芯片框架
- -m:指定運行內存大小
- -kernel:指定運行的內核鏡像
- -dtb:指定具體芯片的配置信息
- -nographic:指定不使用圖形界面
5.完成
如下圖可以看到,成功運行了我們剛剛編譯的新內核
頭條對markdown太不友好了~辛苦改了格式分享給大家,可能還是有點亂,大家可以點下方鏈接看我的知乎。