【LINUX】QEMU执行第一个驱动

QEMU 执行第一个驱动(hello_drv.ko)全过程总结

核心流程:获取源码 → 设置工具链 → 编译内核 / 设备树 → 编译驱动 → 部署驱动到 QEMU 根文件系统 → 启动 QEMU 加载测试驱动,全程在主机 Ubuntu 操作,QEMU 仅负责运行验证。

一、获取全套源码(主机 Ubuntu 终端,基础前提)

作用:下载 QEMU 模拟器、内核、工具链等所有开发必需的源码,后续编译、运行都依赖这些文件。

bash 复制代码
# 1. 配置Git(首次使用需设置,邮箱和用户名可随意填)
book@100ask:~$ git config --global user.email "abc@123.com"
book@100ask:~$ git config --global user.name "MyName"

# 2. 下载repo工具(多仓库管理工具,用于同步全套源码)
book@100ask:~$ git clone https://e.coding.net/codebug8/repo.git

# 3. 创建源码目录并进入
book@100ask:~$ mkdir -p 100ask_imx6ull-qemu 
book@100ask:~$ cd 100ask_imx6ull-qemu

# 4. 初始化repo并关联源码仓库(国内仓库,下载更快)
book@100ask:~/100ask_imx6ull-qemu$ ../repo/repo init -u https://e.coding.net/weidongshan/manifests.git -b linux-sdk -m imx6ull/100ask-imx6ull_qemu_release_v1.0.xml --no-repo-verify

# 5. 同步源码(4线程加速,约10-30分钟,中断后重新执行此命令续传)
book@100ask:~/100ask_imx6ull-qemu$ ../repo/repo sync -j4

# 6. 下载QEMU模拟器镜像(含启动脚本、根文件系统等)
book@100ask:~$ git clone https://e.coding.net/weidongshan/ubuntu-18.04_imx6ul_qemu_system.git

# 7. 验证源码是否下载成功(查看目录内容)
book@100ask:~$ ls ~/100ask_imx6ull-qemu  # 应显示 buildroot2019.02、Linux-4.9.88、ToolChain 等目录
book@100ask:~$ ls ~/ubuntu-18.04_imx6ul_qemu_system  # 应显示 imx6ul-system-image、qemu-imx6ull-gui.sh 等文件
二、设置交叉编译工具链(主机 Ubuntu 终端)

作用:让主机能编译出 ARM 架构的内核、驱动(适配 QEMU 模拟的 IMX6ULL)

1. 临时生效(推荐小白,仅当前终端有效)
bash 复制代码
# 添加交叉编译器路径到环境变量
export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
# 指定目标架构为ARM
export ARCH=arm
# 指定交叉编译器前缀
export CROSS_COMPILE=arm-linux-gnueabihf-
2. 永久生效(可选,重启终端仍有效)
bash 复制代码
# 编辑用户配置文件
vi ~/.bashrc
# 在文件末尾添加以下3行,保存退出(按Esc→:wq)
export ARCH=arm
export CROSS_COMPILE=arm-linux-gnueabihf-
export PATH=$PATH:/home/book/100ask_imx6ull-qemu/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin
# 使配置生效
source ~/.bashrc

验证工具链是否配置成功

bash 复制代码
arm-linux-gnueabihf-gcc -v  # 输出编译器版本信息即正常
三、编译 QEMU 专用内核和设备树(主机 Ubuntu 终端)

作用:生成适配 QEMU 的内核(zImage)和硬件配置(设备树.dtb),驱动需依赖内核运行

bash 复制代码
# 1. 进入内核源码目录
cd ~/100ask_imx6ull-qemu/linux-4.9.88

# 2. 清理编译残留
make mrproper

# 3. 加载QEMU专用配置(无需手动配置驱动)
make 100ask_imx6ull_qemu_defconfig

# 4. 编译内核镜像(-j4按CPU核心数调整,如-j8加速,先执行nproc查看核心数)
nproc
make zImage -j4

# 5. 编译设备树(硬件配置文件)
make dtbs

# 6. 替换QEMU原有的内核和设备树(备份旧文件,复制新文件)
cd ~/ubuntu-18.04_imx6ul_qemu_system/imx6ul-system-image
mv zImage zImage_old
mv 100ask_imx6ull_qemu.dtb 100ask_imx6ull_qemu.dtb_old
cp ~/100ask_imx6ull-qemu/linux-4.9.88/arch/arm/boot/zImage ./
cp ~/100ask_imx6ull-qemu/linux-4.9.88/arch/arm/boot/dts/100ask_imx6ull_qemu.dtb ./
四、编译第一个驱动(hello_drv.ko)(主机 Ubuntu 终端)

作用:将驱动源码编译为 ARM 架构的.ko 模块,供 QEMU 加载

1. 准备驱动文件
bash 复制代码
# 1. 创建驱动目录并进入
mkdir -p ~/nfs_rootfs/01_hello_drv && cd ~/nfs_rootfs/01_hello_drv

# 2. 新建驱动源码hello_drv.c(复制以下内容粘贴)
vi hello_drv.c
2. 新建 Makefile(指定编译规则)
bash 复制代码
# 1. 使用不同的开发板内核时, 一定要修改KERN_DIR
# 2. KERN_DIR中的内核要事先配置、编译, 为了能编译内核, 要先设置下列环境变量:
# 2.1 ARCH,          比如: export ARCH=arm64
# 2.2 CROSS_COMPILE, 比如: export CROSS_COMPILE=aarch64-linux-gnu-
# 2.3 PATH,          比如: export PATH=$PATH:/home/book/100ask_roc-rk3399-pc/ToolChain-6.3.1/gcc-linaro-6.3.1-2017.05-x86_64_aarch64-linux-gnu/bin
# 注意: 不同的开发板不同的编译器上述3个环境变量不一定相同,
#       请参考各开发板的高级用户使用手册

KERN_DIR = /home/book/100ask_imx6ull-qemu/linux-4.9.88

all:
        make -C $(KERN_DIR) M=`pwd` modules
        $(CROSS_COMPILE)gcc -o hello_drv_test hello_drv_test.c

clean:
        make -C $(KERN_DIR) M=`pwd` modules clean
        rm -rf modules.order
        rm -f hello_drv_test

obj-m   += hello_drv.o
~
~
"Makefile" 21L, 853C    
3. 编译驱动
bash 复制代码
# 执行编译(无报错则生成hello_drv.ko)
make -j4
五、部署驱动到 QEMU 根文件系统(主机 Ubuntu 终端)

作用:将编译好的驱动拷贝到 QEMU 的 "系统盘"(rootfs.img),QEMU 启动后可访问

bash 复制代码
# 1. 挂载QEMU根文件系统镜像(rootfs.img)到主机/mnt
sudo mount -o loop ~/ubuntu-18.04_imx6ul_qemu_system/imx6ul-system-image/rootfs.img /mnt

# 2. 拷贝驱动到QEMU的/root目录(临时测试用,方便查找)
sudo cp ~/nfs_rootfs/01_hello_drv/hello_drv.ko /mnt/root/
sudo cp ~/nfs_rootfs/01_hello_drv/hello_drv_test /mnt/root/

# 3. 卸载镜像(必须执行,否则镜像损坏)
sudo umount /mnt
六、启动 QEMU 并加载测试驱动(主机→QEMU 终端)
1. 启动 QEMU(主机 Ubuntu 终端)
bash 复制代码
# 进入QEMU主目录,启动带GUI的模拟器(首次启动需安装SDL环境)
cd ~/ubuntu-18.04_imx6ul_qemu_system
sudo ./install_sdl.sh  # 首次启动执行,输入密码123456
./qemu-imx6ull-gui.sh
# QEMU启动后,在登录界面输入root(无需密码)登录
2. 加载驱动(QEMU 终端,root 用户)
bash 复制代码
# 1. 查看驱动文件是否存在
ls /root/hello_drv.ko

# 2. 加载驱动模块
insmod /root/hello_drv.ko

# 3. 验证驱动加载成功
lsmod # 查看模块列表,能看到hello_drv
dmesg | tail # 查看内核打印,显示"hello_drv init success!"
cat /proc/devices
3.运行程序驱动

根据实际程序来

bash 复制代码
./hello_drv_test
七、关键注意事项
  1. 所有编译操作需确保工具链已配置(终端输入arm-linux-gnueabihf-gcc -v,有版本输出则正常);
  2. 挂载 / 卸载 rootfs.img 时,需保证无其他程序占用 /mnt 目录,否则报错(执行cd ~退出 /mnt 再卸载);
  3. 驱动加载报错 "Invalid module format",需确认内核版本一致(主机内核目录执行make kernelrelease,QEMU 终端执行uname -r,两者需相同);
  4. QEMU 快捷键:鼠标锁定按Ctrl+Alt+g解锁;退出 QEMU 按Ctrl+a松开后按x;
  5. 若 QEMU 启动无 GUI,需重新执行sudo ./install_sdl.sh安装 SDL 环境。

最后谢谢阅读,笔者记录驱动学习过程,如有错误之处还请指正。

相关推荐
RisunJan5 小时前
Linux命令-getsebool命令(查询 SELinux 策略中各项布尔值(boolean)的当前状态)
linux·运维·服务器
郭涤生5 小时前
大白话Proactor模式
linux·网络·c++
Cat God 0075 小时前
CentOS 搭建 SFTP 服务器(一)
linux·服务器·centos
晚风予卿云月5 小时前
Linux编辑器—vim的使用
linux·编辑器·vim
蒸蒸yyyyzwd5 小时前
Linux网络编程-udp
linux·网络·udp
MYMOTOE65 小时前
ISC-3000S的U-Boot 镜像头部解析
java·linux·spring boot
郭涤生5 小时前
大白话Reactor模式
linux·c++
DN金猿6 小时前
jenkins 权限控制(用户只能看指定的项目)
linux·运维·服务器·jenkins
長安一片月6 小时前
操作系统之进程和线程
linux·运维·服务器