编译环境搭建
结束CTF的旅程之后,要投身Kernel的开发。除了日常会偶尔用到的一些脚本环境需要安装在本机之外,我决定所有的环境都打包成Docker使用,避免环境爆炸。
目前来看,我暂时主要需要两个环境,一个是学习Rust的环境,该环境有一个Rust和Windows下的Clion即可。另一个是一个可以编译、模拟Unix内核的环境,该环境需要支持FreeBSD和Linux内核的编译,并使用Qemu可以模拟执行、使用GDB调试这些内核的环境
Sys编译调试环境
2.1 环境准备
首先编写Dockerfile,使用Ubuntu22.04 作为基础镜像,换了下apt源,安装一些工具,然后拷贝了linux6.4和freebsd13.2并解压,还准备了一份busybox。
当然,你也可以选择用我push好的镜像。
docker pull yirannn/modular-zswap-env
FROM ubuntu:22.04
RUN sed -ri.bak -e 's/\/\/.*?(archive.ubuntu.com|mirrors.*?)\/ubuntu/\/\/mirrors.pku.edu.cn\/ubuntu/g' -e '/security.ubuntu.com\/ubuntu/d' /etc/apt/sources.list
RUN apt-get update && \
apt-get install -y \
# 常用环境和工具
qemu-system make gcc g++ gdb \
git xz-utils bzip2 wget file\
# 用于编译过程
flex bison \
build-essential libncurses-dev \
libelf-dev bc libssl-dev \
# 用于源码阅读
clangd bear
RUN mkdir /root/source && \
mkdir /root/tools
COPY linux-6.4.tar.gz /root/source
COPY freebsd-13.2.tar.txz /root/source
COPY busybox-1.36.1.tar.bz2 /root/tools
# 其实拷贝压缩包多了个 overlay, 但是影响很小,放在这还方便改
RUN tar xzf /root/source/linux-6.4.tar.gz -C /root/source/ && \
tar xJf /root/source/freebsd-13.2.tar.txz -C /root/source/ && \
tar xjf /root/tools/busybox-1.36.1.tar.bz2 -C /root/tools && \
rm /root/source/linux-6.4.tar.gz /root/source/freebsd-13.2.tar.txz /root/tools/busybox-1.36.1.tar.bz2 && \
mv /root/source/usr /root/source/freebsd
WORKDIR /root/source
这之后,编译镜像并启动
docker build -t $image_name .
docker run -it --name $container_name --privileged=true $image_name bash
2.2 Linux内核
2.2.1 编译选项
逐行执行以下命令
cd linux-6.4
export ARCH=x86
make x86_64_defconfig
make menuconfig
在menuconfig中,开启debuginfo、关闭地址随机化。也可以看一看其他的选项
Kernel hacking --->
[*] Kernel debugging
Compile-time checks and compiler options --->
[*] Provide GDB scripts for kernel debugging
Debug infomation ([Disable debug infomation]) --->
(X) Generate DWARF Version 5 debuginfo
Processor type and features ---->
[] Randomize the address of the kernel image (KASLR)
2.2.2 开始编译
这之后开始编译,我的笔记本8c16t,设置并发数为16了
make -j16
ls /root/source/linux-6.4/arch/x86/boot
> bzImage
2.3 准备文件系统
2.3.1 准备busybox
启动内核还需要一个具有根文件系统的磁盘镜像文件,根文件系统中提供可供交互的shell程序以及一些常用工具命令,我们借助busybox工具来制作根文件系统。
cd /root/tools/busybox-1.36.1
make menuconfig
在config中设置为静态编译
Settings --->
[*] Build BusyBox as a static binary (no shared libs)
2.3.2 准备rootfs
创建一个文件,并格式化为ext4
dd if=/dev/zero of=rootfs.img bs=1M count=10
mkfs.ext4 rootfs.img
创建挂载镜像文件的目录,挂载之后写入,然而我在这一步遇到了阻碍,提示没权限。
网上教程可能不会遇到这个问题,但是其实用docker久了就知道很可能是privileged没开的问题,当然,在上面的命令里我已经补充好了。对于mount之类的命令,即使docker内部是root,但是在外部没有权限,也是会报权限问题的,我对这里并没有细究,加上之后没问题就放过了。
挂载好之后,把busybox直接编译到挂载目录下
mkdir fs
mount -t ext4 -o loop rootfs.img ./fs
> mount: ./fs: mount failed: Operation not permitted.
# docker创建容器的命令加上 --privileged=true解决
make install CONFIG_PREFIX=./fs
cd fs
mkdir proc dev etc home mnt
cp -r ../examples/bootfloppy/etc/* etc/
chmod -R 777 ./
2.4 运行Linux内核
qemu-system-x86_64 -kernel /root/source/linux-6.4/arch/x86/boot/bzImage -hda /root/tools/busybox-1.36.1/rootfs.img \
-append "root=/dev/sda console=ttyS0" -nographic
可以看到成功运行之, Ctrl-A 后按X退出qemu
评论 (0)