运行及调试Linux内核的方法

世界杯波兰排名 2025-07-08 11:43:23

操作系统内核分析 实验一 Linux系统启动过程

需要的基本工具及文件:

VMware Workstation 15 playerubuntu-18.04.3-desktop-amd64.iso镜像文件Linux源码busybox源码

一、准备实验环境

(一)、下载ubuntu镜像

进入 ubuntu 官网下载页,如图1。点击 Ubuntu Desktop,进入图2。再点击 Ubuntu 18.04.3 LTS 版本右侧的 Download ,开始下载。得到 ubuntu-18.04.3-desktop-amd64.iso 镜像文件。

(二)、安装Ubuntu虚拟机

进入VMware官网,按下图下载 VMware Workstation 15 Player ,安装完成后继续,此处安装过程省略。 打开 VMware Workstation 15 Player ,点击 创建新虚拟机 ,之后按图5操作,之后耐心等待安装完成。 安装结束,自动进入登录界面,可点击之前简易安装创建的用户,输入密码登录。到此安装Ubuntu虚拟机完成。

二、配置、编译linux内核以及busybox

因为刚开始学Linux,本文产生文件统一放在桌面,便于理解。大家可以按照自己需要,自行修改教程中的命令代码,选择存放位置。 若自行修改了文件路径,后面使用该文件时,也请注意修改文件路径

(一)安装开发套件及工具

在桌面右键单击,选择 Open Terminal菜单项,进入终端界面。在命令提示符后面,依次输入执行以下命令,过程中需要输入账户密码。sudo apt update #检查更新

sudo apt install build-essential #基本开发套件

sudo apt install gcc-multilib

sudo apt install git #分布式版本控制系统

安装结束后,可通过gcc --version检验gcc安装是否成功,成功将显示gcc版本信息。 同样,也可通过git --version检验git安装是否成功,成功将显示git版本信息。git配置(仅使用git克隆远程仓库,可跳过此步):git config --global user.name "nickname" #其中nickname,改成你想要的用户名

git config --global user.email "XXX@mail.com" #XXX@mail.com,改成你的个人邮箱

获取Linux源码和Busybox源码到桌面,时间因网速而异,耐心等待。执行完,会在桌面生成一个名为linux的文件夹和一个名为busybox的文件夹。 cd ~/Desktop #改变路径,用于后面克隆代码到桌面

git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux.git #linux内核源码(国外源较慢,这里从清华大学镜像服务器获取内核源码)

git clone git://git.busybox.net/busybox #Busybox 是一个集成了大多数常用 Linux 命令 和工具的软件。

安装编译内核所需的软件包 sudo apt install flex

sudo apt install bison

sudo apt install libncurses5-dev

sudo apt install pkg-config

sudo apt install libglade2-dev

sudo apt install libssl-dev

sudo apt install libelf-dev

(二)配置、编译linux内核

首先进入linux文件夹cd ~/Desktop/linux

清除以前的编译结果及配置信息(可跳过) 若之前有配置、编译过内核可执行该操作清除编译、配置结果,对于新克隆的源码可跳过此步make mrproper

配置linux内核make defconfig #配置内核(按默认选项配置)

make menuconfig #进入图形化的内核配置界面,自定义配置

进入图形化的内核配置界面后,接着按下面操作

1)按【↓】箭头键,找到最下面的 Kernel hacking,按【enter】键进入该配置项

2)按【↓】箭头键,找到 Compile-time checks and compiler options ,按【enter】键进入该配置项

3)按【↑】【↓】箭头键调整选项,找到 Compile the kernel with debug info,按【空格键】选中

4)此时,出现一些Compile the kernel with debug info的子配置项,找到Provide GDB scripts for kernel debugging,也按【空格键】选中

5)连按两下【ESC】键,退出该配置项,再连按两下【ESC】键,退回配置主页。

6)找到并回车进入 Processor type and features 选项,再在接近底部的Build a relocatable kernel 项下,按【空格键】去掉配置项Randomize the address of the kernel image (KASLR)

7)多次连按【ESC】,退出配置,此时提示是否希望保存新的配置,回车选择Yes。回到终端,继续执行本文后面命令。

编译linux内核make #编译内核,持续时间比较久,耐心等待

(三)配置、编译busybox

配置 Busybox,生成配置文件

cd ~/Desktop/busybox #进入之前克隆的busybox源码目录

make defconfig #配置 Busybox,生成配置文件(按默认选项配置)

make menuconfig #进入图形化的配置界面

进入图形化的配置界面后,接着按下面操作

1) 进入Setting --直接按【enter】进入配置组

2) 按【↓】箭头键,找到构建选项 build options

3) 按【↓】箭头键,找到构建选项下的 build static binary (no shared libs),按【空格键】,选中

4) 按下【esc】退出配置组

5) 再按下【esc】,提示保存修改,按【enter】键选择 yes 确认保存

6) 配置完成,回到终端继续执行本文后面命令

编译busybox

make install -j2 #编译busybox

#-j 参数指定了可并行执行的作业数,通常设为计算机 CPU 数目的两倍以提高编译速度。

# 持续时间一丢丢久,耐心等待,直到显示

# --------------------------------------------------

# You will probably need to make your busybox binary

# setuid root to ensure all configured applets will

# work properly.

# --------------------------------------------------

三、用 Busybox 制作根文件系统

进入桌面文件夹

cd ~/Desktop

创建 100M 磁盘镜像 rootfs.img

dd if=/dev/zero of=rootfs.img bs=1M count=100

在磁盘镜像中创建 ext4 根文件系统

mkfs.ext4 rootfs.img

挂载刚刚创建的根文件系统

mkdir rootfs

sudo mount -o loop rootfs.img rootfs #需要输入密码

创建文件夹

cd rootfs

sudo rm -rf lost+found

sudo mkdir -pv {bin,sbin,etc/init.d,proc,sys,usr/{bin,sbin},tmp,dev}

在根文件系统上安装 busybox

sudo cp -drv ~/Desktop/busybox/_install/* .

sudo chmod u+s bin/busybox #给bin文件夹下busybox文件设置setuid标志

#即 使文件在执行阶段具有文件所有者的权限

创建系统配置文件 /etc/inittab (若权限不足,则先执行sudo bash)

sudo cat > etc/inittab << EOF

出现大于号【>】形状的提示符后,复制下面五行代码,粘贴进去(代码前面无空格)

::sysinit:/etc/init.d/rcS

::respawn:-/bin/sh

::restart:/sbin/init

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

EOF

创建系统设置脚本 /etc/init.d/rcS

sudo cat > etc/init.d/rcS << EOF

出现大于号【>】形状的提示符后,复制下面十行代码,粘贴进去(代码前面无空格)

#!/bin/sh

echo "INIT SCRIPT"

mount -t proc proc /proc

mount -t sysfs sysfs /sys

mount -t debugfs debugfs /sys/kernel/debug

mount -t tmpfs tmpfs /tmp

mdev -s

mount -n -o remount,rw /

echo -e "\nBoot took $(cut -d' ' -f1 /proc/uptime) seconds\n"

EOF

赋予rcS文件执行权限

sudo chmod +x etc/init.d/rcS

卸载根文件系统

cd ../

sudo umount rootfs

若卸载时提示target is busy,则执行fuser -v rootfs 查看占用rootfs的进程。 查看没什么特别大的问题,则执行fuser -k rootfs可以直接结束使用rootfs文件的进程。 然后可能需要打开终端,cd ~/Desktop进入桌面后,再次卸载根文件系统sudo umount rootfs。

四、运行及调试内核

安装 qemu 虚拟机软件

sudo apt install qemu

在 home 目录下创建 .gdbinit 文件

cd /home

cat > ~/.gdbinit << EOF

出现大于号【>】形状的提示符后,复制下面2行代码,粘贴进去(代码前面无空格)

add-auto-load-safe-path path/to/linux

EOF

qemu 创建并运行虚拟机

sudo qemu-system-x86_64 -kernel ~/Desktop/linux/arch/x86_64/boot/bzImage -hda ~/Desktop/rootfs.img -append "console=ttyS0 root=/dev/sda" -nographic -s -S

#执行该命令之后,因为加了-S参数,会挂起虚拟机,所以没有执行迹象请不要惊慌,继续后面步骤

【部分参数说明】: -s 参数:为虚拟机启动一个 gdbserver ,等待 gdb 客户端连接。默认 tcp 端口 1234 。 -S 参数:挂起虚拟机,直到 gdb 客户端连接并 给出继续执行的指令。

用 gdb 调试内核 前面终端中虚拟机处于挂起状态,我们要调试内核,必须要另外再开一个终端,通过tcp端口1234执行gdb调试,所以以下代码在另一个终端中进行。

#新开一个终端,执行以下命令

cd ~/Desktop/linux #进入linux内核源码根目录

gdb vmlinux #以内核可执行文件作为参数运行 gdb

target remote :1234 #连接至 gdbserver

break start_kernel #使用break设置函数断点

break rest_init

break kernel_init

break run_init_process

info breakpoints #查看所有设置的断点

continue #继续程序执行(遇到断点会停止运行)

添加断点成功后,即可开始调试 调试过程中,可以激活源码浏览窗口,查看执行位置附件的源码。 快捷键 【Ctrl + x, a】(重复这一操作可以反复隐藏/显示源码浏览窗口。)

当内核程序运行至断点处时将暂停运行,在终端B的gdb调试环境中综合运用下列调试指令来跟踪调试内核程序

• step(单步执行,当执行函数调用时会跟踪进入函数内部)

• next(单步执行,执行函数调用时不会跟踪进入函数内部)

• finish(从一个函数内部返回到上一层调用它的地方)

• continue(运行暂停的程序直到下一个断点处)

• backtrace(查看当前正在调试的程序的函数调用栈)

调试内核,了解linux启动过程

正常调试截图

正常退出

1)先结束 qemu ,按【ctrl+a,x】,提示 QEMU: Terminated即为qemu退出成功 2)再退出 gdb ,在 gdb 所在终端,输入quit回车即可。