qemu直接启动内核+内存文件系统+双终端+文件共享+USB直通


author: hjjdebug

date: 2026年 05月 02日 星期六 16:50:42 CST

descrip: qemu直接启动内核+内存文件系统+双终端+文件共享+USB直通


文章目录

  • [1. qemu 启动脚本文件](#1. qemu 启动脚本文件)
    • [1.1 脚本解释](#1.1 脚本解释)
  • [2 配套的制作根内存文件系统的脚本](#2 配套的制作根内存文件系统的脚本)

直接启动内核 + 内存文件系统 + 双终端 + 文件共享 + USB 直通
适合场景:Linux 内核开发,驱动调试,usb驱动调试,嵌入式系统调试
这些命令组合,本人花了不少时间来实验和体会. 是一个基础命令

1. qemu 启动脚本文件

cpp 复制代码
$ cat qemu_run.sh
#!/bin/bash
qemu-system-x86_64 \
  -m 2G -smp 1 \
  -enable-kvm -cpu host \
  -kernel arch/x86/boot/bzImage \
  -initrd ~/test/rootfs/initramfs.cpio.gz \
  -append "root=/dev/ram0 console=ttyS0 console=ttyS1 nokaslr" \
  -serial stdio \
  -serial telnet:127.0.0.1:5555,server=on,wait=off \
  -fsdev local,security_model=passthrough,id=hostshare,path=/mnt/share \
  -device virtio-9p-pci,fsdev=hostshare,mount_tag=host_share \
  -usb \
  -device usb-host,vendorid=0x067b,productid=0x2303 \
  -display none

1.1 脚本解释

cpp 复制代码
-m 2G        # 给虚拟机分配 2GB 内存
-smp 1       # 给虚拟机分配 1个CPU核心, 调试时不会乱跳,如果不调试,可以给多个
cpp 复制代码
-enable-kvm   # 开启Linux KVM 硬件虚拟化,速度接近物理机
-cpu host     # 让虚拟机CPU模型和物理主机完全一致,发挥cpu性能
cpp 复制代码
-kernel arch/x86/boot/bzImage 

直接使用编译好的 Linux 内核镜像,不需要 ISO / 磁盘镜像,适合内核开发 / 调试。

cpp 复制代码
-initrd ~/test/rootfs/initramfs.cpio.gz

initramfs 是内存文件系统(压缩包),内核启动后直接把它加载到内存作为根目录,不需要硬盘。

cpp 复制代码
-append "root=/dev/ram0 console=ttyS0 console=ttyS1 nokaslr"

内核启动参数

root=/dev/ram0:告诉内核根文件系统在内存盘(对应 initramfs)

/dev/ram0 是现代写法,代表主设备号1,次设备号0的内存盘.

console=ttyS0 console=ttyS1:把内核日志 / 终端输出重定向到两个串口

nokaslr:关闭内核地址随机化,方便内核调试、GDB 跟踪

cpp 复制代码
-serial stdio: 把串口0 直接映射到你当前执行命令的终端,内核日志会直接打印在这里
-serial telnet:127.0.0.1:5555,server=on,wait=off

串口 1 绑定到 localhost:5555

server=on: localhost 服务器.

你可以用:telnet 127.0.0.1 5555 连接服务器,服务器时第二个串口终端设备

wait=off:QEMU 不用等待 Telnet 连接,继续执行

在启动脚本中你需要启动第二个shell

cpp 复制代码
-fsdev local,security_model=passthrough,id=hostshare,path=/mnt/share \
-device virtio-9p-pci,fsdev=hostshare,mount_tag=host_share

这是主机和虚拟机共享文件夹的配置:

主机路径:/mnt/share

虚拟机挂载标签:host_share

虚拟机内挂载命令:mount -t 9p -o trans=virtio host_share /mnt

cpp 复制代码
-usb                         # 开启虚拟机USB控制器
-device usb-host,vendorid=0x067b,productid=0x2303

ust-host, USB 直通:使用物理 USB / 串口硬件

0x067b:0x2303 主机上开放的usb转串口的VID:PID

虚拟机可以直接使用这个硬件

cpp 复制代码
-display none

没有显卡、没有窗口、没有虚拟控制台tty0(键盘+显示器终端)

模拟了两路硬件串口:ttyS0、ttyS1

内核只能把日志 / 控制台绑到 存在的串口设备

适合服务器 / 调试场景

2 配套的制作根内存文件系统的脚本

注释都在脚本中了.

cpp 复制代码
$ cat build_initramfs.sh 

#!/bin/bash

# 配置项
BUSYBOX="/bin/busybox"  # 改成你自己的静态 busybox 路径,要静态的,否则不能运行
OUTPUT="initramfs.cpio.gz"
WORKDIR="./initramfs.tmp"

# 清理
rm -rf "$WORKDIR" "$OUTPUT"
mkdir -p "$WORKDIR"
cd "$WORKDIR" || exit 1

# 1. 创建目录结构
mkdir -p bin dev etc proc sys host


# 2. 创建 etc/fstab(mount -a 调用, 9P 自动挂载)
cat > etc/fstab <<EOF
devtmpfs		/dev		devtmpfs defaults                       0 0
proc            /proc       proc    defaults                        0 0
sysfs           /sys        sysfs   defaults                        0 0
host_share      /host       9p      trans=virtio,version=9p2000.L   0 0
EOF

# 3. 创建 profile, login shell 调用
cat > etc/profile <<EOF
alias ls='ls --color'
alias ll='ls -l'
alias his='history'
mknod /dev/demo_drv c 247 0
insmod /host/demo_drv.ko
EOF

# 4. 生成 init 脚本, 内核默认调用该用户态文件
cat > init <<'EOF'
#!/bin/sh
# 按 fstab 自动挂载
mount -a
# setsid,开新会话,是后面程序成为组长
# cttyhack 修复终端, 我碰到的是消除一个Can't access tty; job control turned off的警告
# sh 跑shell
# -l 会启用login shell, 从而执行profile文件
setsid /bin/cttyhack /bin/sh -l &
# -c 是执行一个子shell命令
# 把当前 shell 的 键盘输入、屏幕输出、报错输出,全部切换到 /dev/ttyS1 这个串口上
# 用新sh替换当前进程
setsid sh -c 'exec 0<>/dev/ttyS1 1>&0 2>&0; exec sh' &
wait
EOF

chmod +x init

# 5. 放入 busybox
cp "$BUSYBOX" bin/
chmod +x bin/busybox

# 建立软链接
cd bin || exit 1
for cmd in sh setsid cttyhack mount modprobe ls cat mkdir dmesg insmod rmmod; do
  ln -s busybox "$cmd"
done
cd ..

# 6. 打包 cpio+gzip
find . | cpio -o -H newc | gzip -9 > ../"$OUTPUT"

# 完成
cd ..
rm -rf "$WORKDIR"
echo "✅ 生成成功:$OUTPUT"
相关推荐
charlie1145141915 天前
嵌入式Linux驱动开发(7) 从虚拟设备到真实硬件 —— LED驱动硬件基础
linux·开发语言·驱动开发·内核·c
Paraverse_徐志斌14 天前
Linux 内核与 Zero-Copy 零拷贝
linux·运维·内核·零拷贝
REDcker18 天前
iOS 与 Android:浏览器引擎、WebView 与生态差异概览
android·ios·内核·浏览器·webview
程序猿编码21 天前
一个授予普通进程ROOT权限的Linux内核级后门:原理与实现深度解析
linux·运维·服务器·内核·root权限
-SGlow-25 天前
Linux相关概念和易错知识点(51)(mmap文件映射、共享内存原理、malloc的原理)
linux·c语言·算法·内核
mounter6251 个月前
深度解析 Linux 内核 devlink:从硬件控制到跨功能速率调度的演进
linux·运维·服务器·网络·内核
零K沁雪1 个月前
Linux 内核中网络地址快速打印符
linux·内核
零K沁雪1 个月前
Linux 内核中与网络地址相关的函数
linux·内核
零K沁雪1 个月前
Linux 内核遍历宏介绍
linux·内核