无标题
BSP大作业
[BSP前置培养大作业.pdf](H:\123\新建文件夹\WeChat Files\wxid_m7uts4kc8omo22\FileStorage\TempFromPhone\BSP前置培养大作业.pdf)
虚拟机配置Ubuntu20.04
虚拟机配置Ubuntu20.04新手全流程【其他系统版本安装同理】_哔哩哔哩_bilibili
搭建qemu
无需开发板,8分钟通过qemu搭建嵌入式linux自学环境_哔哩哔哩_bilibili
配置完后
安装qemu
1 | wget https://download.qemu.org/qemu-9.2.4.tar.xz |
解压
1 | tar xJf qemu-9.2.4.tar.xz.tar.xz |
报错 安装gcc
1 | sudo apt install gcc |
ubuntu20.04源码编译安装qemu(qemu8.2)_either install ensurepip, or alleviate the need fo-CSDN博客
安装一些基础配置
(35 封私信 / 14 条消息) qemu源码编译(完整图文教程) - 知乎
vscode+bear+clangd实现阅读代码精准跳转
有其他版本吗 这个文件夹
1我已经准备好了 大概需要多久 已经在编译了
2也准备好了
3.编译完成了 qumu已经启动了
做一个启动文件把 在这
qumu在/home/linqiutian/workspace/
启动脚本 方式
qemu-system-aarch64
-machine virt
-cpu cortex-a57
-m 2G
-kernel /home/linqiutian/workspace/linux/arch/arm64/boot/Image
-initrd /home/linqiutian/workspace/initramfs_arm64.img
-append “console=ttyAMA0 root=/dev/ram rdinit=/sbin/init”
-fsdev local,id=fsdev0,path=/home/linqiutian/workspace/hello,security_model=none
-device virtio-9p-pci,fsdev=fsdev0,mount_tag=hostshare
-nographic
挂载共享空间
mkdir -p /mnt/share
mount -t 9p -o trans=virtio,version=9p2000.L hostshare /mnt/share
为了正确编译驱动模块,我需要知道QEMU虚拟机中v5.10内核的源代码路径。请提供以下信息:
- QEMU虚拟机中v5.10内核源代码的完整路径 /home/linqiutian/workspace/linux
是要在qemu make 还是在这里make
在主机环境为什么要编译内核环境?
QEMU共享文件夹设置完整流程
主机端准备
创建共享目录:
mkdir -p /home/linqiutian/workspace/qemu_shared
cp -r /home/linqiutian/workspace/helloDev/*/home/linqiutian/workspace/qemu_shared/
- 准备QEMU启动命令:
qemu-system-x86_64
-kernel /path/to/vmlinuz-5.10
-initrd /path/to/initrd.img
-append “root=/dev/sda1 console=ttyS0”
-hda /path/to/qemu-image.qcow2
-fsdev local,id=share_dev,path=/home/linqiutian/workspace/qemu_shared,security_model=none
-device virtio-9p-pci,fsdev=share_dev,mount_tag=hostshare
-nographic
注意:请替换/path/to/为实际的路径。
QEMU虚拟机内部操作
登录QEMU后创建挂载点:
mkdir -p /mnt/hostshare
2. 挂载共享文件夹:
mount -t 9p -o trans=virtio,version=9p2000.L hostshare /mnt/hostshare
3. 验证挂载:
ls /mnt/hostshare
3. 编译内核模块
- 进入共享目录:
cd /mnt/hostshare
2. 清理之前的编译(如有需要):
make clean
3. 编译模块:
make
4. 使用说明
主机端修改文件会自动同步到QEMU中
编译生成的.ko文件也会出现在主机的共享目录中
卸载共享文件夹(退出QEMU前):
umount /mnt/hostshare3
/mnt/hostshare # mknod /dev/hello_dev c 511 0
/mnt/hostshare # chmod 666 /dev/hello_dev
/mnt/hostshare # echo “Test message” > /dev/hello_dev
[ 624.427209] Hello device opened
sh: write error: Invalid argument
[ 624.437116] Hello device closed
/mnt/hostshare # dmesg | tail
[ 0.969666] with arguments:
[ 0.969690] /sbin/init
[ 0.969712] with environment:
[ 0.969730] HOME=/
[ 0.969740] TERM=linux
[ 485.529205] random: fast init done
[ 489.339214] hello_dev: loading out-of-tree module taints kernel.
[ 489.346637] Hello device registered with major number 511
[ 624.427209] Hello device opened
[ 624.437116] Hello device closed
从测试结果来看,内核模块基本工作正常,但存在一个问题:
- 成功部分:
设备节点创建成功 (/dev/hello_dev)
模块正确响应了open/close操作
主设备号511正确注册
2. 问题部分:
写入时出现Invalid argument错误
这表明驱动程序的write操作没有正确处理输入
3. 原因分析:
可能是驱动中没有实现write操作
或者write操作返回了错误值
也可能是缓冲区处理有问题
4. 解决方案:
需要检查驱动代码中的write函数实现
确保正确处理用户空间数据
需要使qemu有root权限,所以在启动时需要 使⽤sudo启动 arm64 root启动
sudo qemu-system-aarch64
-M virt
-cpu cortex-a53
-kernel /home/linqiutian/workspace/linux/arch/arm64/boot/Image.gz
-initrd /home/linqiutian/workspace/initramfs_arm64.img
-nographic
-serial mon:stdio
-append “console=ttyAMA0”
-fsdev local,security_model=passthrough,id=fsdev0,path=/home/linqiutian/workspace/qemu_shared
-device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare
2.0
sudo qemu-system-aarch64
-M virt
-cpu cortex-a53
-kernel /home/wangbeiy/workspace/linux/arch/arm64/boot/Image.gz
-initrd /home/wangbeiy/workspace/initramfs_arm64.img
-nographic
-serial mon:stdio
-append “console=ttyAMA0”
-fsdev local,security_model=passthrough,id=fsdev0,path=/home/wangbeiy/workspace/qemu_shared
-device virtio-9p-pci,id=fs0,fsdev=fsdev0,mount_tag=hostshare
guest启动后需要⼿动mount该共享⽬录
创建专用挂载点目录:
mkdir /hostshare
2. 挂载宿主机共享目录:
mount -t 9p -o trans=virtio,version=9p2000.L hostshare /hostshare
3. 验证挂载是否成功:
ls /hostshare
要解决内核配置问题,请按照以下步骤操作:
- 首先进入内核源代码目录:
cd /home/linqiutian/workspace/linux
2. 生成内核配置文件(使用当前运行内核的配置):
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- oldconfig
3. 准备内核编译环境:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- prepare
4. 现在可以返回模块目录重新编译:
cd /path/to/module
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -C /home/linqiutian/workspace/linux M=$PWD modules
- 如果仍然遇到配置问题,可能需要:
从运行中的内核获取配置:
zcat /proc/config.gz > /home/linqiutian/workspace/linux/.config
或使用默认配置:
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- defconfig
注意:这些操作需要在内核源代码目录有写权限。
insmod helloDev.ko
[ 1108.216925] helloDev: loading out-of-tree module taints kernel.
[ 1108.225087] Hello: Module loaded successfully! Major number: 511
[ 1108.225324] Hello: Create device file with: mknod /dev/hello_dev c 511 0
. 模块已成功加载,显示”Module loaded successfully”和主设备号511
内核日志提示需要创建设备文件
测试步骤需要:
创建设备节点
测试设备访问
验证模块功能
4. 解决方案:
提供完整的设备测试流程
包括读写测试方法
恭喜模块加载成功!以下是完整的测试步骤:
- 首先创建设备节点:
sudo mknod /dev/hello_dev c 511 0
sudo chmod 666 /dev/hello_dev
- 基本设备文件测试:
ls -l /dev/hello_dev # 应显示crw-rw-rw-权限
file /dev/hello_dev # 应显示字符设备文件
- 测试设备读写(根据您的驱动实现):
写入测试
echo “test message” > /dev/hello_dev
读取测试
cat /dev/hello_dev
4. 检查内核日志:
dmesg | tail -n 10
应该能看到驱动处理读写操作的日志
- 压力测试(可选):
连续写入测试
for i in {1..10}; do echo “test $i” > /dev/hello_dev; done
连续读取测试
for i in {1..10}; do cat /dev/hello_dev; done
6. 测试完成后清理:
sudo rm /dev/hello_dev
sudo rmmod helloDev
交叉编译
当前已知信息:
目标:编译并加载helloDev.ko内核模块
系统架构:ARM64 (aarch64)
内核版本:5.10.0
模块源代码位置:~/workspace/helloDev/
4. 需要采取的步骤:
清理之前的编译尝试
从基础步骤开始指导
确保每一步都清晰可执行
5. 解决方案:
提供从头开始的完整指导
分步骤验证每个环节当前已知信息:
目标:编译并加载helloDev.ko内核模块
系统架构:ARM64 (aarch64)
内核版本:5.10.0
模块源代码位置:~/workspace/helloDev/
4. 需要采取的步骤:
清理之前的编译尝试
从基础步骤开始指导
确保每一步都清晰可执行
5. 解决方案:
提供从头开始的完整指导
分步骤验证每个环节
- 准备工作:
安装交叉编译工具链
sudo apt-get install gcc-aarch64-linux-gnu
进入模块目录
cd ~/workspace/helloDev
清理之前的编译结果
make clean
3. 设置环境变量:
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
4. 编译模块:
make -C /home/linqiutian/workspace/linux M=$(pwd) modules
5. 验证结果:
检查生成的模块
file helloDev.ko
应该显示”ARM aarch64”架构
加载模块
sudo insmod helloDev.ko
检查是否加载成功
lsmod | grep helloDev
dmesg | tail
首先确保安装了ARM64交叉编译工具链:
1 | sudo apt-get install gcc-aarch64-linux-gnu |
关键注意事项:
必须使用与运行内核(5.10.0)完全相同的源代码版本
确保内核配置(.config)匹配
编译环境变量设置:
1 | export ARCH=arm64 |
使用正确的架构参数重新编译模块:
1 | make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -C /home/linqiutian/workspace/linux M=$PWD modules |
在qemu中测试字符驱动
1.加载模块到内核:
1 | insmod helloDev.ko |
- 检查模块加载状态:
1 | lsmod | grep helloDev |
- 查看模块初始化输出:
1 | dmesg | tail -n 10 |
- 卸载模块:
1 | sudo rmmod helloDev |
检查模块退出输出:
1 | dmesg | tail -n 10 |
首先创建设备节点:
1 | mknod /dev/hello_dev c 511 0 |
基本设备文件测试:
1 | ls -l /dev/hello_dev # 应显示crw-rw-rw-权限 |
测试设备读写(根据您的驱动实现):
1 | # 写入测试 |
检查内核日志:
1 | dmesg | tail -n 10 |
测试完成后清理:
1 | rm /dev/hello_dev |
运行测试程序
首先在主机上交叉编译test.c
1 | aarch64-linux-gnu-gcc -static -o test test.c |
将编译好的程序传输到QEMU中:
1 | sudo cp test /qemu_shared/ |
1 | ./test |
测试程序test已成功运行,并与内核模块helloDev交互
- 从内核日志可见完整的设备操作流程:
设备打开
用户空间写入数据
驱动接收并回传数据
设备关闭
3. 测试结果显示:
写入和读取操作都成功完成
数据验证通过,表明驱动功能正常
4. 结论:
驱动模块helloDev.ko工作正常
测试程序test验证了驱动的完整功能
测试结果分析:
✅ 驱动模块功能验证成功:
- 设备操作流程完整:
打开设备 (open)
写入数据 (write)
读取数据 (read)
关闭设备 (close)
2. 数据流验证:
用户空间写入: “Hello from user space!”
驱动正确接收: 22字符
驱动正确回传相同数据
用户空间成功读取并验证数据
- 内核日志显示:
[ 627.996160] Hello: Device opened
[ 627.996437] Hello: Received 22 chars
[ 628.001305] Hello: Sent 22 chars
[ 628.002348] Hello: Device closed
4. 用户空间输出:
Wrote to device: Hello from user space!
Read from device: Hello from user space!
Data verification successful
在Ubuntu20.04虚拟机中加载(insmod)字符设备驱动,并⽤运⾏⽤⼾测试程序进⾏测试
先执行清理 重新编译
1 | make clean && make all |
加载模块:sudo insmod helloDev.ko
1 | sudo insmod helloDev.ko |
创建设备节点:sudo mknod /dev/hello_dev c [major] 0 (major号会在加载时打印)
从dmesg输出可以看到内核模块已成功加载,主设备号为237
模块期望用户手动创建设备节点:mknod /dev/hello_dev c 237 0
1 | sudo mknod /dev/hello_dev c 237 0 |
设置适当的权限
1 | sudo chmod 666 /dev/hello_dev |
使用test和write程序测试设备
1 | sudo ./test |
- sudo ./read
open file error
: No such file or directory
linqiutian@ubuntu:~/workspace/hello$ sudo ./write
open file error - No such file or directory
1 | sudo mknod /dev/hello c 237 0 && sudo chmod 666 /dev/hello |
helloDev - Linux字符设备驱动模块
项目概述
这是一个简单的Linux字符设备驱动模块,实现了基本的设备操作接口(open, read, write, close)。主要用于学习和演示Linux设备驱动开发。
主要文件
helloDev.c
: 主驱动代码,实现设备操作Makefile
: 构建脚本test.c
: 综合测试程序read.c
: 读取设备示例write.c
: 写入设备示例
构建和安装
- 确保已安装Linux内核头文件
- 执行构建命令:
1
make
- 加载内核模块:
1
sudo insmod helloDev.ko
- 创建设备节点:(注意: 主设备号250可能需要根据系统调整)
1
2sudo mknod /dev/hello c 250 0
sudo chmod 666 /dev/hello
使用示例
写入数据
1 | gcc write.c -o write |
读取数据
1 | gcc read.c -o read |
综合测试
1 | gcc test.c -o test |
卸载模块
1 | sudo rmmod helloDev |
注意事项
- 需要root权限加载/卸载模块
- 确保主设备号不与系统其他设备冲突
- 测试程序可能需要根据实际系统调整