【内核学习】001编译和运行

compile the kernel

clone和compile在容器中操作

1
2
3
4
docker run --privileged -d -it --name angel -v `pwd`:/root/code -w /root/code ghcr.io/falcon-infra/dev:ubuntu24.04
docker exec -it angel /bin/zsh
git config --global user.name $your_name
git config --global user.email $your_email

clone code

1
2
3
git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git
cd linux-stable
gco v5.15.194

compile

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1. 生成默认配置
make defconfig

# 2. 启用调试选项
./scripts/config --enable DEBUG_KERNEL
./scripts/config --enable DEBUG_INFO
./scripts/config --enable KGDB
./scripts/config --enable FTRACE
./scripts/config --set-val DEBUG_INFO_DWARF4 y

# 3. 自动处理依赖关系
make olddefconfig

# 4. 可选:检查配置
grep -E "DEBUG_KERNEL|DEBUG_INFO|KGDB|FTRACE" .config

# 5. 编译内核
make CC=clang -j$(nproc)

使用 BusyBox 创建最小 rootfs 的步骤如下:

  1. 下载并编译 BusyBox
    1
    2
    3
    4
    5
    6
    7
    wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2
    tar xf busybox-1.36.1.tar.bz2
    cd busybox-1.36.1
    make defconfig
    make menuconfig # 可选:静态编译 Settings → Build static binary (no shared libs)
    make -j$(nproc)
    make install
1
2
3
4
5
6
7
8
9
# 1. 先拿一份默认配置
make defconfig

# 2. 用 sed 三行命令完成上述三项修改
sed -i 's/^# CONFIG_STATIC is not set/CONFIG_STATIC=y/' .config
sed -i 's|CONFIG_PREFIX=.*|CONFIG_PREFIX="./rootfs"|' .config

# 3. 让 Kbuild 自动补齐依赖(重要!)
make oldconfig >/dev/null </dev/null

这里回到mac宿主机。

  1. 创建必要的目录结构
1
2
cd rootfs
mkdir -p {etc,dev,proc,sys,tmp,var,usr/bin,usr/sbin,lib,root}
  1. 创建基础设备节点
1
2
3
4
5
6
7
8
cd rootfs/dev

# 创建设备文件
sudo mknod console c 5 1
sudo mknod null c 1 3
sudo mknod zero c 1 5
sudo mknod ttyAMA0 c 204 64
sudo chmod 666 console null zero ttyAMA0
  1. 创建初始化脚本
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
cd rootfs
cat > init << 'EOF'
#!/bin/sh

echo "Starting system..."

# 挂载必要文件系统
mount -t proc proc /proc
mount -t sysfs sysfs /sys
mount -t devtmpfs devtmpfs /dev
mount -t tmpfs tmpfs /tmp

# 设置终端
exec </dev/ttyAMA0 >/dev/ttyAMA0 2>&1

# 设置环境变量
export PATH=/bin:/sbin:/usr/bin:/usr/sbin
export HOME=/root
export USER=root

# 显示系统信息
echo "=== BusyBox Linux ==="
echo "Kernel: $(uname -r)"
echo "System is ready!"

# 启动shell(修复job control)
exec setsid sh -c 'exec sh </dev/ttyAMA0 >/dev/ttyAMA0 2>&1'
EOF
chmod +x init
  1. 创建简单的fstab
1
2
3
4
5
cat > etc/fstab << 'EOF'
proc /proc proc defaults 0 0
sysfs /sys sysfs defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
EOF
  1. 创建rootfs镜像
1
2
3
4
5
6
7
8
9
10
11
12
cd rootfs

# 创建CPIO格式的rootfs(用于initrd)
find . | cpio -H newc -o | gzip > ../rootfs.cpio.gz

# 或者创建ext4文件系统镜像
dd if=/dev/zero of=../rootfs.ext4 bs=1M count=64
mkfs.ext4 ../rootfs.ext4
mkdir -p /mnt/rootfs
sudo mount ../rootfs.ext4 /mnt/rootfs
sudo cp -ra . /mnt/rootfs/
sudo umount /mnt/rootfs
  1. 使用QEMU启动
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    qemu-system-aarch64 \
    -machine virt \
    -cpu cortex-a72 \
    -smp 4 \
    -m 2G \
    -kernel linux-stable/arch/arm64/boot/Image \
    -initrd busybox-1.36.1/rootfs.cpio.gz \
    -append "console=ttyAMA0 rdinit=/init" \
    -nographic \
    -no-reboot