WSL 下面 Buildroot + QEMU 环境记录一下

下面是你在使用 Buildroot + QEMU 构建和运行嵌入式 Linux 系统时的 完整安装和使用流程(含命令) ,适用于在 WSL(Ubuntu)环境下进行开发。


一、Buildroot 安装与构建流程

1. 获取 Buildroot 源码

bash 复制代码
wget https://buildroot.org/downloads/buildroot-2025.05-rc1.tar.gz
tar -xzf buildroot-2025.05-rc1.tar.gz
mv buildroot-2025.05-rc1 buildroot-master
cd buildroot-master

2. 配置 Buildroot(可选)

你可以用默认配置开始:

bash 复制代码
make qemu_arm_versatile_defconfig

或者进入图形界面定制:

bash 复制代码
make menuconfig

推荐配置调整(在 menuconfig 中)

  • Target options → Architecture:ARM (little endian)
  • ToolchainBuild cross toolchainYes
  • System configurationRoot password:空
  • Target packages → 勾选常用工具(如 nano, htop, busybox, dropbear 等)
  • Filesystem images → Enable ext2/3/4 root filesystem

3. 编译 Buildroot 系统

bash 复制代码
make -j$(nproc)

这个过程特别慢会下载很多第三方库

出现 make clean 之后再make

构建完成后,输出文件在:

复制代码
output/images/
├── rootfs.ext2      # 根文件系统
├── zImage           # 内核镜像
├── vexpress-v2p-ca9.dtb  # (如果你配置的是 vexpress 板子)

二、QEMU 安装

1. 安装 QEMU for ARM(如果未安装):

bash 复制代码
sudo apt update
sudo apt install qemu-system-arm

三、使用 QEMU 启动模拟器

直接运行下面的start-qemu.sh 脚本就行

四、挂载/编辑 rootfs.ext2(可选)

你可以在宿主机编辑 rootfs.ext2 的内容,比如添加文件:

bash 复制代码
sudo mount -o loop output/images/rootfs.ext2 /mnt
sudo cp hello /mnt/root/
sudo umount /mnt

五、交叉编译你自己的程序

假设你有 hello.c

c 复制代码
#include <stdio.h>
int main() {
    printf("Hello from ARM!\n");
    return 0;
}

使用 Buildroot 提供的交叉编译器:

bash 复制代码
output/host/bin/arm-*-gcc hello.c -o hello

然后复制到 rootfs 中,如上所述。


常见问题排查

问题 解决方案
cannot use stdio by multiple character devices 改用 -serial mon:stdio 替代 -serial stdio
QEMU 启动后无输出 检查 console= 参数,是否和板子匹配 (ttyAMA0 for ARM)
rootfs 无法挂载 确保用 root=/dev/mmcblk0 rw rootwait(SD卡模拟)
无法编译 执行 make clean && make,确保 host 系统有完整工具链(如 build-essential, libncurses-dev 等)

如果你有特定的需求,比如:

  • 添加 SSH 支持
  • 使用 initramfs 而非 rootfs.ext2
  • 支持网络功能、NFS、USB、I2C 等

可以继续告诉我,我可以帮你扩展配置。

cpp 复制代码
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <unistd.h>

// PL061 GPIO 寄存器地址(基于 Versatile Express,vexpress-a9)
// 参考:ARM Versatile Express 技术参考手册
#define GPIO_BASE 0x10013000 // GPIO 控制器基地址
#define GPIO_DIR  0x400      // 方向寄存器偏移(0x400)
#define GPIO_SET  0x01C      // 数据寄存器偏移(设置高电平)
#define GPIO_CLEAR 0x028     // 数据寄存器偏移(清除低电平)
#define GPIO_PIN  (1 << 0)   // 使用 GPIO0(可根据需要修改)

int main() {
    int fd;
    void *gpio_base;
    volatile unsigned int *gpio_dir;
    volatile unsigned int *gpio_set;
    volatile unsigned int *gpio_clear;

    // 打开 /dev/mem 以访问物理内存
    fd = open("/dev/mem", O_RDWR | O_SYNC);
    if (fd < 0) {
        perror("无法打开 /dev/mem");
        return 1;
    }

    // 映射 GPIO 寄存器
    gpio_base = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_SHARED, fd, GPIO_BASE);
    if (gpio_base == MAP_FAILED) {
        perror("mmap 失败");
        close(fd);
        return 1;
    }

    // 设置寄存器指针
    gpio_dir = (unsigned int *)(gpio_base + GPIO_DIR);
    gpio_set = (unsigned int *)(gpio_base + GPIO_SET);
    gpio_clear = (unsigned int *)(gpio_base + GPIO_CLEAR);

    // 设置 GPIO0 为输出
    *gpio_dir |= GPIO_PIN;

    printf("LED 点灯程序开始运行...\n");
    fflush(stdout);
    // 循环点亮和熄灭 LED
    while (1) {
        // 点亮 LED(设置 GPIO0 高电平)
        *gpio_set = GPIO_PIN;
        printf("LED 点亮\n");
        fflush(stdout);
        sleep(1);

        // 熄灭 LED(设置 GPIO0 低电平)
        *gpio_clear = GPIO_PIN;
        printf("LED 熄灭\n");
        fflush(stdout);
        sleep(1);
    }

    // 清理(实际上不会到达这里)
    munmap(gpio_base, 4096);
    close(fd);
    return 0;
}


相关推荐
飞凌嵌入式7 分钟前
【RK3588新品】嵌入式人工智能实验箱EDU-AIoT ELF 2发布
人工智能·嵌入式·飞凌嵌入式
LitchiCheng1 小时前
RISC-V 开发板 MUSE Pi Pro USB 测试(3.0 U盘,2.0 UVC摄像头)
linux·运维·risc-v
咖啡进修指南1 小时前
LVS原理详解及LVS负载均衡工作模式
linux·负载均衡·lvs
s1ckrain2 小时前
ARM笔记-嵌入式系统基础
arm开发·嵌入式
西阳未落3 小时前
Linux(7)——进程(概念篇)
linux·运维·服务器
苒苒鸭3 小时前
nginx 基于IP和用户的访问
linux
硬核科技4 小时前
超时处理机制设计:从TICK到回调
单片机·嵌入式硬件·嵌入式·编程·嵌入式软件·软件
Hi202402174 小时前
RK3588 ArmNN CPU/GPU ResNet50 FP32/FP16/INT8 推理测试
嵌入式·rk3588·vulkan·ai推理·armnn
滴水之功4 小时前
C语言数据结构-链式栈
linux·c语言·数据结构
liulilittle4 小时前
Ubuntu 18.04 升级内核到 5.X(< 5.10)
linux·运维·服务器·ubuntu