本文记录如何在 Ubuntu 24.04 系统上编译和运行 Linux kernel.

主机配置如下:

                         ./+o+-       wgxls@server
                 yyyyy- -yyyyyy+      OS: Ubuntu 24.04 noble
              ://+//////-yyyyyyo      Kernel: x86_64 Linux 6.8.0-49-generic
          .++ .:/++++++/-.+sss/`      Uptime: 22h 2m
        .:++o:  /++++++++/:--:/-      Packages: 1924
       o:+o+:++.`..```.-/oo+++++/     Shell: bash
      .:+o:+o/.          `+sssoo+/    Resolution: 2560x1440
 .++/+:+oo+o:`             /sssooo.   DE: GNOME 46.0.1
/+++//+:`oo+o               /::--:.   WM: Mutter
\+/+o+++`o++o               ++////.   WM Theme: Adwaita
 .++.o+++oo+:`             /dddhhh.   GTK Theme: Yaru-purple-dark [GTK2/3]
      .+.o+oo:.          `oddhhhh+    Icon Theme: Yaru-purple
       \+.++o+o``-````.:ohdhhhhh+     Font: Ubuntu Sans 11
        `:o+++ `ohhhhhhhhyo++os:      Disk: 701G / 2.3T (31%)
          .o:`.syhhhhhhh/.oo++o`      CPU: AMD Ryzen 7 4800U with Radeon Graphics @ 16x 1.8GHz
              /osyyyyyyo++ooo+++/     GPU: AMD/ATI Renoir [Radeon RX Vega 6 (Ryzen 4000/5000 Mobile Series)]
                  ````` +oo+++o\:     RAM: 10147MiB / 15489MiB
                         `oo++.      

下载 Linux Kernel 源码

下载 Linux Kernel 源码可以分为两种方式,一种是下载源码包,另一种是使用 Git 下载源码。

  1. 下载源码包

打开 Linux Kernel 官方网址: https://www.kernel.org/

点击黄色按钮,下载最新版本的源码包。

  1. 使用 Git 下载源码

使用 Git 下载源码会包括所有的历史版本,所以下载的内容比较大,时间也比较长。

可以从 Linux 的 GitHub 镜像仓库下载代码,地址为: https://github.com/torvalds/linux

git clone https://github.com/torvalds/linux.git

也可以从 Linux 的官方仓库下载代码,地址为: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/

从以下三个链接 clone 其中一个就可以了。

git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git

编译 Linux Kernel

安装编译工具和依赖

以下是一个包含了足够冗余的编译工具和依赖的列表,可以根据自己的需求进行调整。

当然,我也不能保证这些依赖对于你的操作系统是有用的,具体问题需要具体问AI分析。

sudo apt update
sudo apt install build-essential libncurses-dev bison flex libssl-dev libelf-dev \
libudev-dev libpci-dev libiberty-dev autoconf automake ccache dwarves bc \
liblz4-tool liblzma-dev libzstd-dev libcap-dev libcap-ng-dev libattr1-dev \
libselinux1-dev libpopt-dev libmount-dev libblkid-dev uuid-dev

配置内核

编译内核需要用到一下常用的命令:

make mrproper # 清理内核源码
make clean # 清理编译过程中生成的文件

make menuconfig # 配置内核 
make xconfig # 使用 Qt 配置内核
make gconfig # 使用 GTK 配置内核

make -j$(nproc) # 编译内核
  1. make mrproper 是 Linux 内核源码树中的一个命令,用于清理内核源码树。它的作用是删除所有生成的文件和配置文件,使源码树恢复到一个干净的状态。具体来说,make mrproper 会执行以下操作:
  • 删除所有编译生成的文件,包括目标文件(.o 文件)、依赖文件(.d 文件)和可执行文件。
  • 删除所有配置文件,包括 .config 文件和生成的头文件(如 include/config 目录下的文件)。
  • 删除一些其他生成的文件和目录,如 arch/*/boot 目录下的文件。
  1. make clean 用于清理编译过程中生成的文件。它的作用是删除所有生成的文件,但不会删除配置文件。具体来说,make clean 会执行以下操作:
  • 删除所有编译生成的文件,包括目标文件(.o 文件)、依赖文件(.d 文件)和可执行文件。
  1. make menuconfig 是 Linux 内核的配置工具,用于配置内核的编译选项。它提供了一个基于文本的菜单界面,可以让用户方便地选择内核的编译选项。具体来说,make menuconfig 会打开一个菜单界面,用户可以在这个界面上选择内核的编译选项,然后保存配置文件。

Linux 的内核配置在 Kconfig 文件中,这些文件位于内核源码树的各个目录中。make menuconfig 会读取这些文件,然后生成一个菜单界面,用户可以在这个界面上选择内核的编译选项。用户选择完毕后,make menuconfig 会将用户的选择保存到 .config 文件中。

make xconfigmake gconfig 所作的事情和 make menuconfig 是一样的,只是它们提供了不同的界面。make xconfig 使用 Qt 库,make gconfig 使用 GTK 库。

在本文中,我们使用 make menuconfig 来配置内核。

  1. make -j$(nproc) 是编译内核的命令。-j 选项用于指定并行编译的任务数,$(nproc) 是一个 shell 命令,用于获取系统的 CPU 核心数。这样,make -j$(nproc) 就会使用系统的所有 CPU 核心来编译内核。

接下来重点介绍一下 make menuconfig 的使用。

make menuconfig 需要终端有足够的 Size, 最小可以接受的尺寸是 19 行 80 列,否则会出现如下错误:

wgxls@server:~/Desktop/kernel/linux$ make menuconfig
Your display is too small to run Menuconfig!
It must be at least 19 lines by 80 columns.
make[2]: *** [scripts/kconfig/Makefile:56:menuconfig] 错误 1
make[1]: *** [/home/wgxls/Desktop/kernel/linux/Makefile:679:menuconfig] 错误 2
make: *** [Makefile:224:__sub-make] 错误 2

调整好终端的大小后,重新运行 make menuconfig 即可进入配置界面。

操作规则写在了界面的上方,翻译成中文如下:

Enter: 进入子菜单
高亮的字母是快捷键
Y 是选中,N 是不选中,M 是模块化编译 (也可以使用空格键进行切换)
按两次 Esc 键退出
上下左右移动光标
/ 搜索

这里面由 [ ] 指示的选项只有 选中 和 非选中 两种状态,< > 指示的选项有 选中、非选中、模块化编译 三种状态。

首次编译我们先不作任何修改,直接退出即可。

退出时被询问是否保存配置,选择 Yes 即可。

此时,内核的配置文件 .config 就被保存了。

编译内核

直接执行 make -j$(nproc) 即可开始编译内核。

此过程需要一些时间,根据电脑的性能不同,时间也会有所差异,几分钟到几小时不等。

编译成功的内核镜像位于 arch/x86/boot/bzImage

我们可以看一下编译生成的文件大小:

wgxls@server:~/Desktop/kernel/linux$ ls -lh arch/x86/boot/bzImage
-rw-rw-r-- 1 wgxls wgxls 15M 1122 12:23 arch/x86/boot/bzImage

以及查bzImage的版本信息:

wgxls@server:~/Desktop/kernel/linux$ file arch/x86/boot/bzImage
arch/x86/boot/bzImage: Linux kernel x86 boot executable bzImage, version 6.12.0 (root@server) #3 SMP PREEMPT_DYNAMIC Fri Nov 22 12:21:34 CST 2024, RO-rootFS, swap_dev 0XE, Normal VGA

这个 bzImage 和 Ubuntu /boot 目录下的 vmlinuz 是一样的,只是名字不一样。

wgxls@server:~/Desktop/kernel/linux$ sudo file /boot/vmlinuz-6.8.0-49-generic
[sudo] wgxls 的密码: 
/boot/vmlinuz-6.8.0-49-generic: Linux kernel x86 boot executable bzImage, version 6.8.0-49-generic (buildd@lcy02-amd64-028) #49-Ubuntu SMP PREEMPT_DYNAMIC Mon Nov  4 02:06:24 UTC 2024, RO-rootFS, swap_dev 0XE, Normal VGA

稍后,我们会用 QEMU 来启动这个 bzImage。

踩坑一:

在编译过程中,可能会出现如下错误:

make[3]: *** 没有规则可制作目标“debian/canonical-certs.pem”,由“certs/x509_certificate_list” 需求。 停止。
make[3]: *** 正在等待未完成的任务....

可以通过清空 SYSTEM_TRUSTED_KEYS 来解决:

重新执行 make menuconfig, 定位到如下位置

-> Cryptographic API (CRYPTO [=y])
-> Certificates for signature checking
-> Provide system-wide ring of trusted keys (SYSTEM_TRUSTED_KEYRING [=y]) 
-> Additional X.509 keys for default system keyring (SYSTEM_TRUSTED_KEYS [=debian/canonical-certs.pem]) 

清空后的配置菜单显示如下:

然后保存退出,重新执行 make -j$(nproc) 即可。

踩坑二:

make[3]: *** 没有规则可制作目标“debian/canonical-revoked-certs.pem”,由“certs/x509_revocation_list” 需求。 停止。
make[3]: *** 正在等待未完成的任务....

和上面是同样的道理,把 “debian/canonical-revoked-certs.pem” 清空即可。
位置如下:

-> Cryptographic API -> Certificates for signature checking ->

使用 Busybox 创建 initramfs

编译 Busybox

Busybox 是一个集成了一百多个 Linux 命令和工具的软件包,它可以用来创建一个最小的 Linux 系统。

Busybox 的官方网站是: https://www.busybox.net/

Busybox 的源码可以从官方网站下载,也可以使用 Git 下载。

git clone git://git.busybox.net/busybox

目前最新的版本是 1.37 , 我们把 clone 的代码切换到 1.37 版本。

git checkout remotes/origin/1_37_stable -b 1_37_stable

Busybox 的编译过程和 Linux Kernel 类似,首先需要进行配置。

make menuconfig

Build static binary (no shared libs) 选项选中,这样编译出来的 Busybox 就是一个静态链接的二进制文件。

它位于 Settings 下。

然后开始编译。

make -j$(nproc)

编译完成输出如下:

  LINK    busybox_unstripped
Static linking against glibc, can't use --gc-sections
Trying libraries: crypt m resolv rt
 Library crypt is not needed, excluding it
 Library m is needed, can't exclude it (yet)
 Library resolv is needed, can't exclude it (yet)
 Library rt is not needed, excluding it
 Library m is needed, can't exclude it (yet)
 Library resolv is needed, can't exclude it (yet)
Final link with: m resolv

然后执行 make install 安装 Busybox。

make install

输出如下:

  ./_install//usr/sbin/ubiupdatevol -> ../../bin/busybox
  ./_install//usr/sbin/udhcpd -> ../../bin/busybox


--------------------------------------------------
You will probably need to make your busybox binary
setuid root to ensure all configured applets will
work properly.
--------------------------------------------------

Busybox 的二进制文件位于 _install/bin/busybox

创建 initramfs

initramfs 是一个临时的根文件系统,用于启动 Linux 内核。

首先我们创建一个目录,用于存放 initramfs 的文件。

把 Busybox 的二进制文件和 bzImage 复制到这个目录下。

mkdir -p ~/Desktop/kernel/workspace/initramfs
cp _install/bin/busybox ~/Desktop/kernel/workspace
cp ~/Desktop/kernel/linux/arch/x86/boot/bzImage ~/Desktop/kernel/workspace

cd ~/Desktop/kernel/workspace

在 initramfs 目录下创建一个 bin 目录,并把 busybox 复制到这个目录下。

mkdir -p initramfs/{bin,sbin,etc,proc,sys}
cp busybox initramfs/bin
cd initramfs/bin
for cmd in $(./busybox --list); do ln -s busybox $cmd; done
cd ../..

在 initramfs 目录下创建一个 init 文件,用于启动 Linux 内核。
并给 init 文件添加可执行权限。

touch initramfs/init
chmod +x initramfs/init

init 是 Linux 内核启动时的第一个进程,它负责初始化系统,并启动其他进程。

我们将 init 的内容设置为如下:

#!/bin/busybox sh

/bin/busybox echo "Hello, Linux Kernel!"
/bin/busybox mount -t proc none /proc
/bin/busybox mount -t sysfs none /sys
/bin/busybox mount -t devtmpfs none /dev

/bin/busybox sh

接下来我们需要把 initramfs 目录打包成一个 cpio 归档文件。

这里我们编写一个 Makefile 来完成这个任务。

vim Makefile

Makefile 的内容如下:

.PHONY: initramfs run clean

initramfs:
    cd initramfs && find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../initramfs.img

run:
    qemu-system-x86_64 -kernel bzImage -initrd initramfs.img -nographic -append "console=ttyS0" -m 1024

clean:
    rm -f initramfs.cpio initramfs.img

Makefile 要使用 Tab 键缩进,不能使用空格。

设置完成后,workspace 目录结构如下:

workspace 目录结构
wgxls@server:~/Desktop/kernel/workspace$ tree
.
├── busybox
├── bzImage
├── initramfs
│   ├── bin
│   │   ├── [ -> busybox
│   │   ├── [[ -> busybox
│   │   ├── acpid -> busybox
│   │   ├── addgroup -> busybox
│   │   ├── add-shell -> busybox
│   │   ├── adduser -> busybox
│   │   ├── adjtimex -> busybox
│   │   ├── arch -> busybox
│   │   ├── arp -> busybox
│   │   ├── arping -> busybox
│   │   ├── ascii -> busybox
│   │   ├── ash -> busybox
│   │   ├── awk -> busybox
│   │   ├── base32 -> busybox
│   │   ├── base64 -> busybox
│   │   ├── basename -> busybox
│   │   ├── bc -> busybox
│   │   ├── beep -> busybox
│   │   ├── blkdiscard -> busybox
│   │   ├── blkid -> busybox
│   │   ├── blockdev -> busybox
│   │   ├── bootchartd -> busybox
│   │   ├── brctl -> busybox
│   │   ├── bunzip2 -> busybox
│   │   ├── busybox
│   │   ├── bzcat -> busybox
│   │   ├── bzip2 -> busybox
│   │   ├── cal -> busybox
│   │   ├── cat -> busybox
│   │   ├── chat -> busybox
│   │   ├── chattr -> busybox
│   │   ├── chgrp -> busybox
│   │   ├── chmod -> busybox
│   │   ├── chown -> busybox
│   │   ├── chpasswd -> busybox
│   │   ├── chpst -> busybox
│   │   ├── chroot -> busybox
│   │   ├── chrt -> busybox
│   │   ├── chvt -> busybox
│   │   ├── cksum -> busybox
│   │   ├── clear -> busybox
│   │   ├── cmp -> busybox
│   │   ├── comm -> busybox
│   │   ├── conspy -> busybox
│   │   ├── cp -> busybox
│   │   ├── cpio -> busybox
│   │   ├── crc32 -> busybox
│   │   ├── crond -> busybox
│   │   ├── crontab -> busybox
│   │   ├── cryptpw -> busybox
│   │   ├── cttyhack -> busybox
│   │   ├── cut -> busybox
│   │   ├── date -> busybox
│   │   ├── dc -> busybox
│   │   ├── dd -> busybox
│   │   ├── deallocvt -> busybox
│   │   ├── delgroup -> busybox
│   │   ├── deluser -> busybox
│   │   ├── depmod -> busybox
│   │   ├── devmem -> busybox
│   │   ├── df -> busybox
│   │   ├── dhcprelay -> busybox
│   │   ├── diff -> busybox
│   │   ├── dirname -> busybox
│   │   ├── dmesg -> busybox
│   │   ├── dnsd -> busybox
│   │   ├── dnsdomainname -> busybox
│   │   ├── dos2unix -> busybox
│   │   ├── dpkg -> busybox
│   │   ├── dpkg-deb -> busybox
│   │   ├── du -> busybox
│   │   ├── dumpkmap -> busybox
│   │   ├── dumpleases -> busybox
│   │   ├── echo -> busybox
│   │   ├── ed -> busybox
│   │   ├── egrep -> busybox
│   │   ├── eject -> busybox
│   │   ├── env -> busybox
│   │   ├── envdir -> busybox
│   │   ├── envuidgid -> busybox
│   │   ├── ether-wake -> busybox
│   │   ├── expand -> busybox
│   │   ├── expr -> busybox
│   │   ├── factor -> busybox
│   │   ├── fakeidentd -> busybox
│   │   ├── fallocate -> busybox
│   │   ├── false -> busybox
│   │   ├── fatattr -> busybox
│   │   ├── fbset -> busybox
│   │   ├── fbsplash -> busybox
│   │   ├── fdflush -> busybox
│   │   ├── fdformat -> busybox
│   │   ├── fdisk -> busybox
│   │   ├── fgconsole -> busybox
│   │   ├── fgrep -> busybox
│   │   ├── find -> busybox
│   │   ├── findfs -> busybox
│   │   ├── flock -> busybox
│   │   ├── fold -> busybox
│   │   ├── free -> busybox
│   │   ├── freeramdisk -> busybox
│   │   ├── fsck -> busybox
│   │   ├── fsck.minix -> busybox
│   │   ├── fsfreeze -> busybox
│   │   ├── fstrim -> busybox
│   │   ├── fsync -> busybox
│   │   ├── ftpd -> busybox
│   │   ├── ftpget -> busybox
│   │   ├── ftpput -> busybox
│   │   ├── fuser -> busybox
│   │   ├── getfattr -> busybox
│   │   ├── getopt -> busybox
│   │   ├── getty -> busybox
│   │   ├── grep -> busybox
│   │   ├── groups -> busybox
│   │   ├── gunzip -> busybox
│   │   ├── gzip -> busybox
│   │   ├── halt -> busybox
│   │   ├── hd -> busybox
│   │   ├── hdparm -> busybox
│   │   ├── head -> busybox
│   │   ├── hexdump -> busybox
│   │   ├── hexedit -> busybox
│   │   ├── hostid -> busybox
│   │   ├── hostname -> busybox
│   │   ├── httpd -> busybox
│   │   ├── hush -> busybox
│   │   ├── hwclock -> busybox
│   │   ├── i2cdetect -> busybox
│   │   ├── i2cdump -> busybox
│   │   ├── i2cget -> busybox
│   │   ├── i2cset -> busybox
│   │   ├── i2ctransfer -> busybox
│   │   ├── id -> busybox
│   │   ├── ifconfig -> busybox
│   │   ├── ifdown -> busybox
│   │   ├── ifenslave -> busybox
│   │   ├── ifplugd -> busybox
│   │   ├── ifup -> busybox
│   │   ├── inetd -> busybox
│   │   ├── init -> busybox
│   │   ├── insmod -> busybox
│   │   ├── install -> busybox
│   │   ├── ionice -> busybox
│   │   ├── iostat -> busybox
│   │   ├── ip -> busybox
│   │   ├── ipaddr -> busybox
│   │   ├── ipcalc -> busybox
│   │   ├── ipcrm -> busybox
│   │   ├── ipcs -> busybox
│   │   ├── iplink -> busybox
│   │   ├── ipneigh -> busybox
│   │   ├── iproute -> busybox
│   │   ├── iprule -> busybox
│   │   ├── iptunnel -> busybox
│   │   ├── kbd_mode -> busybox
│   │   ├── kill -> busybox
│   │   ├── killall -> busybox
│   │   ├── killall5 -> busybox
│   │   ├── klogd -> busybox
│   │   ├── last -> busybox
│   │   ├── less -> busybox
│   │   ├── link -> busybox
│   │   ├── linux32 -> busybox
│   │   ├── linux64 -> busybox
│   │   ├── linuxrc -> busybox
│   │   ├── ln -> busybox
│   │   ├── loadfont -> busybox
│   │   ├── loadkmap -> busybox
│   │   ├── logger -> busybox
│   │   ├── login -> busybox
│   │   ├── logname -> busybox
│   │   ├── logread -> busybox
│   │   ├── losetup -> busybox
│   │   ├── lpd -> busybox
│   │   ├── lpq -> busybox
│   │   ├── lpr -> busybox
│   │   ├── ls -> busybox
│   │   ├── lsattr -> busybox
│   │   ├── lsmod -> busybox
│   │   ├── lsof -> busybox
│   │   ├── lspci -> busybox
│   │   ├── lsscsi -> busybox
│   │   ├── lsusb -> busybox
│   │   ├── lzcat -> busybox
│   │   ├── lzma -> busybox
│   │   ├── lzop -> busybox
│   │   ├── makedevs -> busybox
│   │   ├── makemime -> busybox
│   │   ├── man -> busybox
│   │   ├── md5sum -> busybox
│   │   ├── mdev -> busybox
│   │   ├── mesg -> busybox
│   │   ├── microcom -> busybox
│   │   ├── mim -> busybox
│   │   ├── mkdir -> busybox
│   │   ├── mkdosfs -> busybox
│   │   ├── mke2fs -> busybox
│   │   ├── mkfifo -> busybox
│   │   ├── mkfs.ext2 -> busybox
│   │   ├── mkfs.minix -> busybox
│   │   ├── mkfs.vfat -> busybox
│   │   ├── mknod -> busybox
│   │   ├── mkpasswd -> busybox
│   │   ├── mkswap -> busybox
│   │   ├── mktemp -> busybox
│   │   ├── modinfo -> busybox
│   │   ├── modprobe -> busybox
│   │   ├── more -> busybox
│   │   ├── mount -> busybox
│   │   ├── mountpoint -> busybox
│   │   ├── mpstat -> busybox
│   │   ├── mt -> busybox
│   │   ├── mv -> busybox
│   │   ├── nameif -> busybox
│   │   ├── nanddump -> busybox
│   │   ├── nandwrite -> busybox
│   │   ├── nbd-client -> busybox
│   │   ├── nc -> busybox
│   │   ├── netstat -> busybox
│   │   ├── nice -> busybox
│   │   ├── nl -> busybox
│   │   ├── nmeter -> busybox
│   │   ├── nohup -> busybox
│   │   ├── nologin -> busybox
│   │   ├── nproc -> busybox
│   │   ├── nsenter -> busybox
│   │   ├── nslookup -> busybox
│   │   ├── ntpd -> busybox
│   │   ├── od -> busybox
│   │   ├── openvt -> busybox
│   │   ├── partprobe -> busybox
│   │   ├── passwd -> busybox
│   │   ├── paste -> busybox
│   │   ├── patch -> busybox
│   │   ├── pgrep -> busybox
│   │   ├── pidof -> busybox
│   │   ├── ping -> busybox
│   │   ├── ping6 -> busybox
│   │   ├── pipe_progress -> busybox
│   │   ├── pivot_root -> busybox
│   │   ├── pkill -> busybox
│   │   ├── pmap -> busybox
│   │   ├── popmaildir -> busybox
│   │   ├── poweroff -> busybox
│   │   ├── powertop -> busybox
│   │   ├── printenv -> busybox
│   │   ├── printf -> busybox
│   │   ├── ps -> busybox
│   │   ├── pscan -> busybox
│   │   ├── pstree -> busybox
│   │   ├── pwd -> busybox
│   │   ├── pwdx -> busybox
│   │   ├── raidautorun -> busybox
│   │   ├── rdate -> busybox
│   │   ├── rdev -> busybox
│   │   ├── readahead -> busybox
│   │   ├── readlink -> busybox
│   │   ├── readprofile -> busybox
│   │   ├── realpath -> busybox
│   │   ├── reboot -> busybox
│   │   ├── reformime -> busybox
│   │   ├── remove-shell -> busybox
│   │   ├── renice -> busybox
│   │   ├── reset -> busybox
│   │   ├── resize -> busybox
│   │   ├── resume -> busybox
│   │   ├── rev -> busybox
│   │   ├── rm -> busybox
│   │   ├── rmdir -> busybox
│   │   ├── rmmod -> busybox
│   │   ├── route -> busybox
│   │   ├── rpm -> busybox
│   │   ├── rpm2cpio -> busybox
│   │   ├── rtcwake -> busybox
│   │   ├── run-init -> busybox
│   │   ├── runlevel -> busybox
│   │   ├── run-parts -> busybox
│   │   ├── runsv -> busybox
│   │   ├── runsvdir -> busybox
│   │   ├── rx -> busybox
│   │   ├── script -> busybox
│   │   ├── scriptreplay -> busybox
│   │   ├── sed -> busybox
│   │   ├── seedrng -> busybox
│   │   ├── sendmail -> busybox
│   │   ├── seq -> busybox
│   │   ├── setarch -> busybox
│   │   ├── setconsole -> busybox
│   │   ├── setfattr -> busybox
│   │   ├── setfont -> busybox
│   │   ├── setkeycodes -> busybox
│   │   ├── setlogcons -> busybox
│   │   ├── setpriv -> busybox
│   │   ├── setserial -> busybox
│   │   ├── setsid -> busybox
│   │   ├── setuidgid -> busybox
│   │   ├── sh -> busybox
│   │   ├── sha1sum -> busybox
│   │   ├── sha256sum -> busybox
│   │   ├── sha3sum -> busybox
│   │   ├── sha512sum -> busybox
│   │   ├── showkey -> busybox
│   │   ├── shred -> busybox
│   │   ├── shuf -> busybox
│   │   ├── slattach -> busybox
│   │   ├── sleep -> busybox
│   │   ├── smemcap -> busybox
│   │   ├── softlimit -> busybox
│   │   ├── sort -> busybox
│   │   ├── split -> busybox
│   │   ├── ssl_client -> busybox
│   │   ├── start-stop-daemon -> busybox
│   │   ├── stat -> busybox
│   │   ├── strings -> busybox
│   │   ├── stty -> busybox
│   │   ├── su -> busybox
│   │   ├── sulogin -> busybox
│   │   ├── sum -> busybox
│   │   ├── sv -> busybox
│   │   ├── svc -> busybox
│   │   ├── svlogd -> busybox
│   │   ├── svok -> busybox
│   │   ├── swapoff -> busybox
│   │   ├── swapon -> busybox
│   │   ├── switch_root -> busybox
│   │   ├── sync -> busybox
│   │   ├── sysctl -> busybox
│   │   ├── syslogd -> busybox
│   │   ├── tac -> busybox
│   │   ├── tail -> busybox
│   │   ├── tar -> busybox
│   │   ├── taskset -> busybox
│   │   ├── tcpsvd -> busybox
│   │   ├── tee -> busybox
│   │   ├── telnet -> busybox
│   │   ├── telnetd -> busybox
│   │   ├── test -> busybox
│   │   ├── tftp -> busybox
│   │   ├── tftpd -> busybox
│   │   ├── time -> busybox
│   │   ├── timeout -> busybox
│   │   ├── top -> busybox
│   │   ├── touch -> busybox
│   │   ├── tr -> busybox
│   │   ├── traceroute -> busybox
│   │   ├── traceroute6 -> busybox
│   │   ├── tree -> busybox
│   │   ├── true -> busybox
│   │   ├── truncate -> busybox
│   │   ├── ts -> busybox
│   │   ├── tsort -> busybox
│   │   ├── tty -> busybox
│   │   ├── ttysize -> busybox
│   │   ├── tunctl -> busybox
│   │   ├── ubiattach -> busybox
│   │   ├── ubidetach -> busybox
│   │   ├── ubimkvol -> busybox
│   │   ├── ubirename -> busybox
│   │   ├── ubirmvol -> busybox
│   │   ├── ubirsvol -> busybox
│   │   ├── ubiupdatevol -> busybox
│   │   ├── udhcpc -> busybox
│   │   ├── udhcpc6 -> busybox
│   │   ├── udhcpd -> busybox
│   │   ├── udpsvd -> busybox
│   │   ├── uevent -> busybox
│   │   ├── umount -> busybox
│   │   ├── uname -> busybox
│   │   ├── unexpand -> busybox
│   │   ├── uniq -> busybox
│   │   ├── unix2dos -> busybox
│   │   ├── unlink -> busybox
│   │   ├── unlzma -> busybox
│   │   ├── unshare -> busybox
│   │   ├── unxz -> busybox
│   │   ├── unzip -> busybox
│   │   ├── uptime -> busybox
│   │   ├── users -> busybox
│   │   ├── usleep -> busybox
│   │   ├── uudecode -> busybox
│   │   ├── uuencode -> busybox
│   │   ├── vconfig -> busybox
│   │   ├── vi -> busybox
│   │   ├── vlock -> busybox
│   │   ├── volname -> busybox
│   │   ├── w -> busybox
│   │   ├── wall -> busybox
│   │   ├── watch -> busybox
│   │   ├── watchdog -> busybox
│   │   ├── wc -> busybox
│   │   ├── wget -> busybox
│   │   ├── which -> busybox
│   │   ├── who -> busybox
│   │   ├── whoami -> busybox
│   │   ├── whois -> busybox
│   │   ├── xargs -> busybox
│   │   ├── xxd -> busybox
│   │   ├── xz -> busybox
│   │   ├── xzcat -> busybox
│   │   ├── yes -> busybox
│   │   ├── zcat -> busybox
│   │   └── zcip -> busybox
│   ├── etc
│   ├── init
│   ├── proc
│   ├── sbin
│   └── sys
├── initramfs.img
└── Makefile

7 directories, 408 files

然后执行 make initramfs 即可生成 initramfs.cpio 和 initramfs.img。

initramfs.cpio 和 initramfs.img 是一样的,只是 initramfs.img 是 initramfs.cpio 的压缩版本。

wgxls@server:~/Desktop/kernel/workspace$ file initramfs.cpio 
initramfs.cpio: ASCII cpio archive (SVR4 with no CRC)
wgxls@server:~/Desktop/kernel/workspace$ file initramfs.img 
initramfs.img: gzip compressed data, from Unix, original size modulo 2^32 0

使用 QEMU 启动内核

QEMU 是一个开源的虚拟机软件,可以模拟多种硬件平台,包括 x86、ARM、MIPS 等。

我们可以使用 QEMU 来启动 Linux 内核。

首先我们需要安装 QEMU。

sudo apt install qemu-system-x86

上一节中我们已经写好了 Makefile,现在我们执行 make run 即可启动内核。

启动日志如下:
[    0.000000] Linux version 6.12.0 (root@server) (gcc (Ubuntu 13.2.0-23ubuntu4) 13.2.0, GNU ld (GNU Binutils for Ubuntu) 2.42) #3 SMP PREEMPT_DYNAMIC Fri Nov 22 12:21:34 CST 2024
[    0.000000] Command line: console=ttyS0
[    0.000000] KERNEL supported cpus:
[    0.000000]   Intel GenuineIntel
[    0.000000]   AMD AuthenticAMD
[    0.000000]   Hygon HygonGenuine
[    0.000000]   Centaur CentaurHauls
[    0.000000]   zhaoxin   Shanghai  
[    0.000000] BIOS-provided physical RAM map:
[    0.000000] BIOS-e820: [mem 0x0000000000000000-0x000000000009fbff] usable
[    0.000000] BIOS-e820: [mem 0x000000000009fc00-0x000000000009ffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000000f0000-0x00000000000fffff] reserved
[    0.000000] BIOS-e820: [mem 0x0000000000100000-0x000000003ffdffff] usable
[    0.000000] BIOS-e820: [mem 0x000000003ffe0000-0x000000003fffffff] reserved
[    0.000000] BIOS-e820: [mem 0x00000000fffc0000-0x00000000ffffffff] reserved
[    0.000000] BIOS-e820: [mem 0x000000fd00000000-0x000000ffffffffff] reserved
[    0.000000] NX (Execute Disable) protection: active
[    0.000000] APIC: Static calls initialized
[    0.000000] SMBIOS 3.0.0 present.
[    0.000000] DMI: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[    0.000000] DMI: Memory slots populated: 1/1
[    0.000000] tsc: Fast TSC calibration using PIT
[    0.000000] tsc: Detected 1796.640 MHz processor
[    0.018476] AGP: No AGP bridge found
[    0.018792] last_pfn = 0x3ffe0 max_arch_pfn = 0x400000000
[    0.019674] MTRR map: 4 entries (3 fixed + 1 variable; max 19), built from 8 variable MTRRs
[    0.019912] x86/PAT: Configuration [0-7]: WB  WC  UC- UC  WB  WP  UC- WT  
[    0.042004] found SMP MP-table at [mem 0x000f5480-0x000f548f]
[    0.047898] RAMDISK: [mem 0x3fea1000-0x3ffdffff]
[    0.048467] ACPI: Early table checksum verification disabled
[    0.048989] ACPI: RSDP 0x00000000000F52A0 000014 (v00 BOCHS )
[    0.049332] ACPI: RSDT 0x000000003FFE1C40 000034 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.050121] ACPI: FACP 0x000000003FFE1AF4 000074 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.050985] ACPI: DSDT 0x000000003FFE0040 001AB4 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.051091] ACPI: FACS 0x000000003FFE0000 000040
[    0.051162] ACPI: APIC 0x000000003FFE1B68 000078 (v03 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.051197] ACPI: HPET 0x000000003FFE1BE0 000038 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.051229] ACPI: WAET 0x000000003FFE1C18 000028 (v01 BOCHS  BXPC     00000001 BXPC 00000001)
[    0.051359] ACPI: Reserving FACP table memory at [mem 0x3ffe1af4-0x3ffe1b67]
[    0.051383] ACPI: Reserving DSDT table memory at [mem 0x3ffe0040-0x3ffe1af3]
[    0.051392] ACPI: Reserving FACS table memory at [mem 0x3ffe0000-0x3ffe003f]
[    0.051401] ACPI: Reserving APIC table memory at [mem 0x3ffe1b68-0x3ffe1bdf]
[    0.051409] ACPI: Reserving HPET table memory at [mem 0x3ffe1be0-0x3ffe1c17]
[    0.051418] ACPI: Reserving WAET table memory at [mem 0x3ffe1c18-0x3ffe1c3f]
[    0.054754] No NUMA configuration found
[    0.054778] Faking a node at [mem 0x0000000000000000-0x000000003ffdffff]
[    0.055810] NODE_DATA(0) allocated [mem 0x3fe76680-0x3fea0fff]
[    0.059850] Zone ranges:
[    0.059880]   DMA      [mem 0x0000000000001000-0x0000000000ffffff]
[    0.060257]   DMA32    [mem 0x0000000001000000-0x000000003ffdffff]
[    0.060273]   Normal   empty
[    0.060294]   Device   empty
[    0.060309] Movable zone start for each node
[    0.060345] Early memory node ranges
[    0.060378]   node   0: [mem 0x0000000000001000-0x000000000009efff]
[    0.060553]   node   0: [mem 0x0000000000100000-0x000000003ffdffff]
[    0.060720] Initmem setup node 0 [mem 0x0000000000001000-0x000000003ffdffff]
[    0.061895] On node 0, zone DMA: 1 pages in unavailable ranges
[    0.062152] On node 0, zone DMA: 97 pages in unavailable ranges
[    0.080291] On node 0, zone DMA32: 32 pages in unavailable ranges
[    0.081199] ACPI: PM-Timer IO Port: 0x608
[    0.081699] ACPI: LAPIC_NMI (acpi_id[0xff] dfl dfl lint[0x1])
[    0.082286] IOAPIC[0]: apic_id 0, version 32, address 0xfec00000, GSI 0-23
[    0.082419] ACPI: INT_SRC_OVR (bus 0 bus_irq 0 global_irq 2 dfl dfl)
[    0.082831] ACPI: INT_SRC_OVR (bus 0 bus_irq 5 global_irq 5 high level)
[    0.082901] ACPI: INT_SRC_OVR (bus 0 bus_irq 9 global_irq 9 high level)
[    0.083025] ACPI: INT_SRC_OVR (bus 0 bus_irq 10 global_irq 10 high level)
[    0.083039] ACPI: INT_SRC_OVR (bus 0 bus_irq 11 global_irq 11 high level)
[    0.083276] ACPI: Using ACPI (MADT) for SMP configuration information
[    0.083332] ACPI: HPET id: 0x8086a201 base: 0xfed00000
[    0.083817] CPU topo: Max. logical packages:   1
[    0.083834] CPU topo: Max. logical dies:       1
[    0.083846] CPU topo: Max. dies per package:   1
[    0.083908] CPU topo: Max. threads per core:   1
[    0.084101] CPU topo: Num. cores per package:     1
[    0.084121] CPU topo: Num. threads per package:   1
[    0.084133] CPU topo: Allowing 1 present CPUs plus 0 hotplug CPUs
[    0.085279] PM: hibernation: Registered nosave memory: [mem 0x00000000-0x00000fff]
[    0.085338] PM: hibernation: Registered nosave memory: [mem 0x0009f000-0x0009ffff]
[    0.085370] PM: hibernation: Registered nosave memory: [mem 0x000a0000-0x000effff]
[    0.085378] PM: hibernation: Registered nosave memory: [mem 0x000f0000-0x000fffff]
[    0.085535] [mem 0x40000000-0xfffbffff] available for PCI devices
[    0.085614] Booting paravirtualized kernel on bare hardware
[    0.085991] clocksource: refined-jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1910969940391419 ns
[    0.087218] setup_percpu: NR_CPUS:8192 nr_cpumask_bits:1 nr_cpu_ids:1 nr_node_ids:1
[    0.088897] percpu: Embedded 88 pages/cpu s237568 r8192 d114688 u2097152
[    0.090728] Kernel command line: console=ttyS0
[    0.092124] Dentry cache hash table entries: 131072 (order: 8, 1048576 bytes, linear)
[    0.092353] Inode-cache hash table entries: 65536 (order: 7, 524288 bytes, linear)
[    0.096079] Fallback order for Node 0: 0 
[    0.096479] Built 1 zonelists, mobility grouping on.  Total pages: 262014
[    0.096508] Policy zone: DMA32
[    0.097125] mem auto-init: stack:all(zero), heap alloc:on, heap free:off
[    0.097318] AGP: Checking aperture...
[    0.099104] AGP: No AGP bridge found
[    0.349372] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[    0.353701] ftrace: allocating 56198 entries in 220 pages
[    0.409726] ftrace: allocated 220 pages with 5 groups
[    0.422365] Dynamic Preempt: voluntary
[    0.427877] rcu: Preemptible hierarchical RCU implementation.
[    0.427941] rcu: 	RCU restricting CPUs from NR_CPUS=8192 to nr_cpu_ids=1.
[    0.428112] 	Trampoline variant of Tasks RCU enabled.
[    0.428123] 	Rude variant of Tasks RCU enabled.
[    0.428130] 	Tracing variant of Tasks RCU enabled.
[    0.428255] rcu: RCU calculated value of scheduler-enlistment delay is 100 jiffies.
[    0.428290] rcu: Adjusting geometry for rcu_fanout_leaf=16, nr_cpu_ids=1
[    0.430033] RCU Tasks: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=1.
[    0.430071] RCU Tasks Rude: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=1.
[    0.430084] RCU Tasks Trace: Setting shift to 0 and lim to 1 rcu_task_cb_adjust=1 rcu_task_cpu_ids=1.
[    0.459659] NR_IRQS: 524544, nr_irqs: 256, preallocated irqs: 16
[    0.471796] rcu: srcu_init: Setting srcu_struct sizes based on contention.
[    0.480013] Console: colour VGA+ 80x25
[    0.482509] printk: legacy console [ttyS0] enabled
[    0.520941] ACPI: Core revision 20240827
[    0.530338] clocksource: hpet: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 19112604467 ns
[    0.538396] APIC: Switch to symmetric I/O mode setup
[    0.546649] ..TIMER: vector=0x30 apic1=0 pin1=2 apic2=-1 pin2=-1
[    0.552864] clocksource: tsc-early: mask: 0xffffffffffffffff max_cycles: 0x19e5c383d73, max_idle_ns: 440795275710 ns
[    0.554075] Calibrating delay loop (skipped), value calculated using timer frequency.. 3593.28 BogoMIPS (lpj=1796640)
[    0.560344] Last level iTLB entries: 4KB 512, 2MB 255, 4MB 127
[    0.560645] Last level dTLB entries: 4KB 512, 2MB 255, 4MB 127, 1GB 0
[    0.561764] Spectre V1 : Mitigation: usercopy/swapgs barriers and __user pointer sanitization
[    0.562402] Spectre V2 : Mitigation: Retpolines
[    0.562653] Spectre V2 : Spectre v2 / SpectreRSB mitigation: Filling RSB on context switch
[    0.563119] Spectre V2 : Spectre v2 / SpectreRSB : Filling RSB on VMEXIT
[    0.567451] x86/fpu: x87 FPU will use FXSAVE
[    1.036106] Freeing SMP alternatives memory: 48K
[    1.037915] pid_max: default: 32768 minimum: 301
[    1.051633] LSM: initializing lsm=lockdown,capability,landlock,yama,apparmor,ima,evm
[    1.056515] landlock: Up and running.
[    1.056912] Yama: becoming mindful.
[    1.064450] AppArmor: AppArmor initialized
[    1.073537] Mount-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    1.074105] Mountpoint-cache hash table entries: 2048 (order: 2, 16384 bytes, linear)
[    1.223604] smpboot: CPU0: AMD QEMU Virtual CPU version 2.5+ (family: 0xf, model: 0x6b, stepping: 0x1)
[    1.246116] Performance Events: PMU not available due to virtualization, using software events only.
[    1.248732] signal: max sigframe size: 1440
[    1.252116] rcu: Hierarchical SRCU implementation.
[    1.252686] rcu: 	Max phase no-delay instances is 400.
[    1.268498] NMI watchdog: Perf NMI watchdog permanently disabled
[    1.273875] smp: Bringing up secondary CPUs ...
[    1.277299] smp: Brought up 1 node, 1 CPU
[    1.277954] smpboot: Total of 1 processors activated (3593.28 BogoMIPS)
[    1.289088] Memory: 971260K/1048056K available (22528K kernel code, 4585K rwdata, 14292K rodata, 5060K init, 4496K bss, 71624K reserved, 0K cma-reserved)
[    1.302379] devtmpfs: initialized
[    1.308086] x86/mm: Memory block size: 128MB
[    1.323010] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 1911260446275000 ns
[    1.324106] futex hash table entries: 256 (order: 2, 16384 bytes, linear)
[    1.333447] pinctrl core: initialized pinctrl subsystem
[    1.340100] PM: RTC time: 13:36:43, date: 2024-11-23
[    1.367174] NET: Registered PF_NETLINK/PF_ROUTE protocol family
[    1.374193] DMA: preallocated 128 KiB GFP_KERNEL pool for atomic allocations
[    1.375653] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA pool for atomic allocations
[    1.376412] DMA: preallocated 128 KiB GFP_KERNEL|GFP_DMA32 pool for atomic allocations
[    1.377744] audit: initializing netlink subsys (disabled)
[    1.381551] audit: type=2000 audit(1732369002.842:1): state=initialized audit_enabled=0 res=1
[    1.392412] thermal_sys: Registered thermal governor 'fair_share'
[    1.392518] thermal_sys: Registered thermal governor 'bang_bang'
[    1.393048] thermal_sys: Registered thermal governor 'step_wise'
[    1.393429] thermal_sys: Registered thermal governor 'user_space'
[    1.393634] thermal_sys: Registered thermal governor 'power_allocator'
[    1.394805] EISA bus registered
[    1.396131] cpuidle: using governor ladder
[    1.396730] cpuidle: using governor menu
[    1.399541] acpiphp: ACPI Hot Plug PCI Controller Driver version: 0.5
[    1.406704] PCI: Using configuration type 1 for base access
[    1.415250] kprobes: kprobe jump-optimization is enabled. All kprobes are optimized if possible.
[    1.537068] HugeTLB: registered 2.00 MiB page size, pre-allocated 0 pages
[    1.537565] HugeTLB: 28 KiB vmemmap can be freed for a 2.00 MiB page
[    1.599747] ACPI: Added _OSI(Module Device)
[    1.602712] ACPI: Added _OSI(Processor Device)
[    1.603124] ACPI: Added _OSI(3.0 _SCP Extensions)
[    1.603464] ACPI: Added _OSI(Processor Aggregator Device)
[    1.651648] ACPI: 1 ACPI AML tables successfully acquired and loaded
[    1.678706] ACPI: Interpreter enabled
[    1.681068] ACPI: PM: (supports S0 S3 S4 S5)
[    1.681456] ACPI: Using IOAPIC for interrupt routing
[    1.684062] PCI: Using host bridge windows from ACPI; if necessary, use "pci=nocrs" and report a bug
[    1.684671] PCI: Using E820 reservations for host bridge windows
[    1.688793] ACPI: Enabled 2 GPEs in block 00 to 0F
[    1.739365] ACPI: PCI Root Bridge [PCI0] (domain 0000 [bus 00-ff])
[    1.740835] acpi PNP0A03:00: _OSC: OS supports [ASPM ClockPM Segments MSI EDR HPX-Type3]
[    1.741766] acpi PNP0A03:00: _OSC: not requesting OS control; OS requires [ExtendedConfig ASPM ClockPM MSI]
[    1.743352] acpi PNP0A03:00: fail to add MMCONFIG information, can't access extended configuration space under this bridge
[    1.753022] acpiphp: Slot [3] registered
[    1.753784] acpiphp: Slot [4] registered
[    1.754190] acpiphp: Slot [5] registered
[    1.754646] acpiphp: Slot [6] registered
[    1.755107] acpiphp: Slot [7] registered
[    1.755788] acpiphp: Slot [8] registered
[    1.756218] acpiphp: Slot [9] registered
[    1.756718] acpiphp: Slot [10] registered
[    1.757097] acpiphp: Slot [11] registered
[    1.757483] acpiphp: Slot [12] registered
[    1.757737] acpiphp: Slot [13] registered
[    1.758141] acpiphp: Slot [14] registered
[    1.758726] acpiphp: Slot [15] registered
[    1.759192] acpiphp: Slot [16] registered
[    1.759743] acpiphp: Slot [17] registered
[    1.760065] acpiphp: Slot [18] registered
[    1.760501] acpiphp: Slot [19] registered
[    1.760756] acpiphp: Slot [20] registered
[    1.761138] acpiphp: Slot [21] registered
[    1.761730] acpiphp: Slot [22] registered
[    1.762197] acpiphp: Slot [23] registered
[    1.762751] acpiphp: Slot [24] registered
[    1.763097] acpiphp: Slot [25] registered
[    1.763481] acpiphp: Slot [26] registered
[    1.763763] acpiphp: Slot [27] registered
[    1.764155] acpiphp: Slot [28] registered
[    1.764788] acpiphp: Slot [29] registered
[    1.765220] acpiphp: Slot [30] registered
[    1.765924] acpiphp: Slot [31] registered
[    1.766944] PCI host bridge to bus 0000:00
[    1.767659] pci_bus 0000:00: root bus resource [io  0x0000-0x0cf7 window]
[    1.768277] pci_bus 0000:00: root bus resource [io  0x0d00-0xffff window]
[    1.768628] pci_bus 0000:00: root bus resource [mem 0x000a0000-0x000bffff window]
[    1.769149] pci_bus 0000:00: root bus resource [mem 0x40000000-0xfebfffff window]
[    1.769627] pci_bus 0000:00: root bus resource [mem 0x100000000-0x17fffffff window]
[    1.770279] pci_bus 0000:00: root bus resource [bus 00-ff]
[    1.772753] pci 0000:00:00.0: [8086:1237] type 00 class 0x060000 conventional PCI endpoint
[    1.780187] pci 0000:00:01.0: [8086:7000] type 00 class 0x060100 conventional PCI endpoint
[    1.782023] pci 0000:00:01.1: [8086:7010] type 00 class 0x010180 conventional PCI endpoint
[    1.785812] pci 0000:00:01.1: BAR 4 [io  0xc040-0xc04f]
[    1.787421] pci 0000:00:01.1: BAR 0 [io  0x01f0-0x01f7]: legacy IDE quirk
[    1.787664] pci 0000:00:01.1: BAR 1 [io  0x03f6]: legacy IDE quirk
[    1.788078] pci 0000:00:01.1: BAR 2 [io  0x0170-0x0177]: legacy IDE quirk
[    1.788647] pci 0000:00:01.1: BAR 3 [io  0x0376]: legacy IDE quirk
[    1.790907] pci 0000:00:01.3: [8086:7113] type 00 class 0x068000 conventional PCI endpoint
[    1.792237] pci 0000:00:01.3: quirk: [io  0x0600-0x063f] claimed by PIIX4 ACPI
[    1.792686] pci 0000:00:01.3: quirk: [io  0x0700-0x070f] claimed by PIIX4 SMB
[    1.795251] pci 0000:00:02.0: [1234:1111] type 00 class 0x030000 conventional PCI endpoint
[    1.796247] pci 0000:00:02.0: BAR 0 [mem 0xfd000000-0xfdffffff pref]
[    1.798211] pci 0000:00:02.0: BAR 2 [mem 0xfebb0000-0xfebb0fff]
[    1.802646] pci 0000:00:02.0: ROM [mem 0xfeba0000-0xfebaffff pref]
[    1.803796] pci 0000:00:02.0: Video device with shadowed ROM at [mem 0x000c0000-0x000dffff]
[    1.806075] pci 0000:00:03.0: [8086:100e] type 00 class 0x020000 conventional PCI endpoint
[    1.807651] pci 0000:00:03.0: BAR 0 [mem 0xfeb80000-0xfeb9ffff]
[    1.808636] pci 0000:00:03.0: BAR 1 [io  0xc000-0xc03f]
[    1.811662] pci 0000:00:03.0: ROM [mem 0xfeb00000-0xfeb7ffff pref]
[    1.831838] ACPI: PCI: Interrupt link LNKA configured for IRQ 10
[    1.833643] ACPI: PCI: Interrupt link LNKB configured for IRQ 10
[    1.834902] ACPI: PCI: Interrupt link LNKC configured for IRQ 11
[    1.836066] ACPI: PCI: Interrupt link LNKD configured for IRQ 11
[    1.836903] ACPI: PCI: Interrupt link LNKS configured for IRQ 9
[    1.843062] iommu: Default domain type: Translated
[    1.843442] iommu: DMA domain TLB invalidation policy: lazy mode
[    1.848714] SCSI subsystem initialized
[    1.851332] ACPI: bus type USB registered
[    1.852201] usbcore: registered new interface driver usbfs
[    1.853097] usbcore: registered new interface driver hub
[    1.853877] usbcore: registered new device driver usb
[    1.854869] pps_core: LinuxPPS API ver. 1 registered
[    1.855198] pps_core: Software ver. 5.3.6 - Copyright 2005-2007 Rodolfo Giometti <giometti@linux.it>
[    1.855731] PTP clock support registered
[    1.858899] EDAC MC: Ver: 3.0.0
[    1.877367] NetLabel: Initializing
[    1.877635] NetLabel:  domain hash size = 128
[    1.877868] NetLabel:  protocols = UNLABELED CIPSOv4 CALIPSO
[    1.879978] NetLabel:  unlabeled traffic allowed by default
[    1.886770] mctp: management component transport protocol core
[    1.887179] NET: Registered PF_MCTP protocol family
[    1.888267] PCI: Using ACPI for IRQ routing
[    1.891807] pci 0000:00:02.0: vgaarb: setting as boot VGA device
[    1.892204] pci 0000:00:02.0: vgaarb: bridge control possible
[    1.892586] pci 0000:00:02.0: vgaarb: VGA device added: decodes=io+mem,owns=io+mem,locks=none
[    1.892667] vgaarb: loaded
[    1.895700] hpet: 3 channels of 0 reserved for per-cpu timers
[    1.896348] hpet0: at MMIO 0xfed00000, IRQs 2, 8, 0
[    1.896644] hpet0: 3 comparators, 64-bit 100.000000 MHz counter
[    1.907373] clocksource: Switched to clocksource tsc-early
[    1.927646] VFS: Disk quotas dquot_6.6.0
[    1.928385] VFS: Dquot-cache hash table entries: 512 (order 0, 4096 bytes)
[    1.933244] AppArmor: AppArmor Filesystem Enabled
[    1.934034] pnp: PnP ACPI init
[    1.940445] pnp: PnP ACPI: found 6 devices
[    1.976099] clocksource: acpi_pm: mask: 0xffffff max_cycles: 0xffffff, max_idle_ns: 2085701024 ns
[    1.978537] NET: Registered PF_INET protocol family
[    1.980470] IP idents hash table entries: 16384 (order: 5, 131072 bytes, linear)
[    2.065606] tcp_listen_portaddr_hash hash table entries: 512 (order: 1, 8192 bytes, linear)
[    2.066407] Table-perturb hash table entries: 65536 (order: 6, 262144 bytes, linear)
[    2.066883] TCP established hash table entries: 8192 (order: 4, 65536 bytes, linear)
[    2.067709] TCP bind hash table entries: 8192 (order: 6, 262144 bytes, linear)
[    2.068606] TCP: Hash tables configured (established 8192 bind 8192)
[    2.071071] MPTCP token hash table entries: 1024 (order: 2, 24576 bytes, linear)
[    2.072013] UDP hash table entries: 512 (order: 2, 16384 bytes, linear)
[    2.072711] UDP-Lite hash table entries: 512 (order: 2, 16384 bytes, linear)
[    2.075460] NET: Registered PF_UNIX/PF_LOCAL protocol family
[    2.076541] NET: Registered PF_XDP protocol family
[    2.078307] pci_bus 0000:00: resource 4 [io  0x0000-0x0cf7 window]
[    2.078756] pci_bus 0000:00: resource 5 [io  0x0d00-0xffff window]
[    2.079093] pci_bus 0000:00: resource 6 [mem 0x000a0000-0x000bffff window]
[    2.079544] pci_bus 0000:00: resource 7 [mem 0x40000000-0xfebfffff window]
[    2.079911] pci_bus 0000:00: resource 8 [mem 0x100000000-0x17fffffff window]
[    2.081309] pci 0000:00:01.0: PIIX3: Enabling Passive Release
[    2.081783] pci 0000:00:00.0: Limiting direct PCI/PCI transfers
[    2.082448] PCI: CLS 0 bytes, default 64
[    2.094832] Trying to unpack rootfs image as initramfs...
[    2.104888] Initialise system trusted keyrings
[    2.112359] Key type blacklist registered
[    2.115730] workingset: timestamp_bits=36 max_order=18 bucket_order=0
[    2.117839] zbud: loaded
[    2.149135] squashfs: version 4.0 (2009/01/31) Phillip Lougher
[    2.162678] fuse: init (API version 7.41)
[    2.177126] integrity: Platform Keyring initialized
[    2.178740] integrity: Machine keyring initialized
[    2.336917] Freeing initrd memory: 1276K
[    2.337589] Key type asymmetric registered
[    2.337858] Asymmetric key parser 'x509' registered
[    2.339038] Block layer SCSI generic (bsg) driver version 0.4 loaded (major 243)
[    2.342470] io scheduler mq-deadline registered
[    2.346667] ledtrig-cpu: registered to indicate activity on CPUs
[    2.348297] shpchp: Standard Hot Plug PCI Controller Driver version: 0.4
[    2.354032] input: Power Button as /devices/LNXSYSTM:00/LNXPWRBN:00/input/input0
[    2.359941] ACPI: button: Power Button [PWRF]
[    2.367858] Serial: 8250/16550 driver, 32 ports, IRQ sharing enabled
[    2.396034] 00:04: ttyS0 at I/O 0x3f8 (irq = 4, base_baud = 115200) is a 16550A
[    2.440610] Linux agpgart interface v0.103
[    2.444317] ACPI: bus type drm_connector registered
[    2.480311] loop: module loaded
[    2.501332] scsi host0: ata_piix
[    2.507315] scsi host1: ata_piix
[    2.508809] ata1: PATA max MWDMA2 cmd 0x1f0 ctl 0x3f6 bmdma 0xc040 irq 14 lpm-pol 0
[    2.509511] ata2: PATA max MWDMA2 cmd 0x170 ctl 0x376 bmdma 0xc048 irq 15 lpm-pol 0
[    2.521412] tun: Universal TUN/TAP device driver, 1.6
[    2.523750] PPP generic driver version 2.4.2
[    2.531056] i8042: PNP: PS/2 Controller [PNP0303:KBD,PNP0f13:MOU] at 0x60,0x64 irq 1,12
[    2.536865] serio: i8042 KBD port at 0x60,0x64 irq 1
[    2.537604] serio: i8042 AUX port at 0x60,0x64 irq 12
[    2.540749] mousedev: PS/2 mouse device common for all mice
[    2.546359] rtc_cmos 00:05: RTC can wake from S4
[    2.550612] input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input1
[    2.556542] rtc_cmos 00:05: registered as rtc0
[    2.558074] rtc_cmos 00:05: setting system clock to 2024-11-23T13:36:45 UTC (1732369005)
[    2.560994] rtc_cmos 00:05: alarms up to one day, y3k, 242 bytes nvram, hpet irqs
[    2.561812] i2c_dev: i2c /dev entries driver
[    2.562843] device-mapper: core: CONFIG_IMA_DISABLE_HTABLE is disabled. Duplicate IMA measurements will not be recorded in the IMA log.
[    2.563990] device-mapper: uevent: version 1.0.3
[    2.566154] device-mapper: ioctl: 4.48.0-ioctl (2023-03-01) initialised: dm-devel@lists.linux.dev
[    2.567769] platform eisa.0: Probing EISA bus 0
[    2.568348] platform eisa.0: EISA: Cannot allocate resource for mainboard
[    2.568874] platform eisa.0: Cannot allocate resource for EISA slot 1
[    2.569331] platform eisa.0: Cannot allocate resource for EISA slot 2
[    2.569695] platform eisa.0: Cannot allocate resource for EISA slot 3
[    2.570034] platform eisa.0: Cannot allocate resource for EISA slot 4
[    2.570447] platform eisa.0: Cannot allocate resource for EISA slot 5
[    2.570826] platform eisa.0: Cannot allocate resource for EISA slot 6
[    2.571178] platform eisa.0: Cannot allocate resource for EISA slot 7
[    2.571596] platform eisa.0: Cannot allocate resource for EISA slot 8
[    2.572010] platform eisa.0: EISA: Detected 0 cards
[    2.572596] amd_pstate: the _CPC object is not present in SBIOS or ACPI disabled
[    2.575286] drop_monitor: Initializing network drop monitor service
[    2.578073] NET: Registered PF_INET6 protocol family
[    2.607560] Segment Routing with IPv6
[    2.608587] In-situ OAM (IOAM) with IPv6
[    2.609726] NET: Registered PF_PACKET protocol family
[    2.611089] Key type dns_resolver registered
[    2.614990] IPI shorthand broadcast: enabled
[    2.639498] sched_clock: Marking stable (2574087480, 65113412)->(2776835677, -137634785)
[    2.643692] registered taskstats version 1
[    2.648287] Loading compiled-in X.509 certificates
[    2.667091] ata2: found unknown device (class 0)
[    2.677459] ata2.00: ATAPI: QEMU DVD-ROM, 2.5+, max UDMA/100
[    2.701581] scsi 1:0:0:0: CD-ROM            QEMU     QEMU DVD-ROM     2.5+ PQ: 0 ANSI: 5
[    2.734996] sr 1:0:0:0: [sr0] scsi3-mmc drive: 4x/4x cd/rw xa/form2 tray
[    2.735696] cdrom: Uniform CD-ROM driver Revision: 3.20
[    2.738842] Demotion targets for Node 0: null
[    2.742381] Key type .fscrypt registered
[    2.742699] Key type fscrypt-provisioning registered
[    2.767829] sr 1:0:0:0: Attached scsi generic sg0 type 5
[    2.773049] Key type encrypted registered
[    2.774318] AppArmor: AppArmor sha256 policy hashing enabled
[    2.775729] ima: No TPM chip found, activating TPM-bypass!
[    2.776339] Loading compiled-in module X.509 certificates
[    2.776677] ima: Allocated hash algorithm: sha256
[    2.780860] ima: No architecture policies found
[    2.782065] evm: Initialising EVM extended attributes:
[    2.782450] evm: security.selinux
[    2.782637] evm: security.SMACK64
[    2.782818] evm: security.SMACK64EXEC
[    2.783006] evm: security.SMACK64TRANSMUTE
[    2.783319] evm: security.SMACK64MMAP
[    2.783557] evm: security.apparmor
[    2.783725] evm: security.ima
[    2.783881] evm: security.capability
[    2.784113] evm: HMAC attrs: 0x1
[    2.789370] PM:   Magic number: 0:719:635
[    2.791760] powernow_k8: Power state transitions not supported
[    2.814307] RAS: Correctable Errors collector initialized.
[    2.882909] clk: Disabling unused clocks
[    2.883764] PM: genpd: Disabling unused power domains
[    2.904566] Freeing unused decrypted memory: 2028K
[    3.001126] Freeing unused kernel image (initmem) memory: 5060K
[    3.001984] Write protecting the kernel read-only data: 36864k
[    3.004320] Freeing unused kernel image (rodata/data gap) memory: 44K
[    3.227919] x86/mm: Checked W+X mappings: passed, no W+X pages found.
[    3.228916] tsc: Refined TSC clocksource calibration: 1796.606 MHz
[    3.229654] clocksource: tsc: mask: 0xffffffffffffffff max_cycles: 0x19e5a36c268, max_idle_ns: 440795214549 ns
[    3.230430] clocksource: Switched to clocksource tsc
[    3.233016] Run /init as init process
Hello, Linux Kernel!
sh: can't access tty; job control turned off

退出 QEMU 的方法是按下 Ctrl + a 然后再按下 x

我们已经看到了 “Hello, Linux Kernel!”,这表示我们的内核已经成功启动了。

并且成功启动了 init 进程。

🎉 实验成功 🎉

你已经成功编译并启动了一个 Linux 内核。开启了你的 Linux 内核之旅。