☰
RISC-V上跑通Zephyr和Linux:从QEMU到开发板的完整指南
2026/10/5 11:22:42 网站建设 项目流程

如果你和我一样,手头放着一块还带着静电袋的RISC-V开发板,脑子里却同时在纠结两件事——先用Zephyr跑个实时任务,还是直接上Linux感受一下桌面级系统?那么这篇东西就是给你写的。我第一次在QEMU里把RISC-V上的Zephyr跑通,是在一个加班到深夜的晚上,串口蹦出Hello World的那一刻,疲惫感直接没了;后来花了一个周末,又把Linux在同一个QEMU里带起来,才真正理解了什么叫“同一套指令集,两种完全不同的软件栈”。这篇文章不聊虚的,就记录我在RISC-V上运行Zephyr和Linux的完整方法、原理和踩坑过程,全部精确到命令行,你可以照着一步步复现。

1. 为什么要在RISC-V上同时折腾Zephyr和Linux:两个系统的定位差异

很多人拿到RISC-V开发板后的第一个问题不是“怎么跑”,而是“跑什么”。Zephyr还是Linux?这个选择题困扰了我很久,后来想明白了,真正的问题不是二选一,而是你得知道这颗CPU上到底能同时承载什么。

RISC-V的本质是一个开放的指令集架构(ISA),它不规定具体硬件实现,只规定指令怎么编码、怎么执行。这就带来了一个嵌入式领域里很罕见的特性:同一颗处理器核心,既可以运行一个几KB的实时内核,也可以运行一个完整的多进程操作系统。在ARM世界里,虽然也有这种能力,但Cortex-M和Cortex-A分了家,工具链、调试器、软件生态都各玩各的。RISC-V从设计之初就预留了这种组合拳的可能。

Zephyr和Linux正是这条光谱上的两个典型代表。Zephyr是一个轻量级实时操作系统,面向MCU场景,内核可以压缩到几十KB,在只有几百KB内存的芯片上也能活蹦乱跳。Linux则是一个通用操作系统,它默认你有一颗带MMU的处理器,几十MB内存起步,跑文件系统、跑网络协议栈、跑容器都行。

我整理了一个表格,方便你直观感受两者的区别:

维度ZephyrLinux
定位实时操作系统(RTOS)通用操作系统
内核镜像几十KB到几百KB几MB起步
内存需求几十KB即可运行建议至少64MB以上
实时性硬实时,调度策略可配置软实时,更侧重吞吐量
MMU不需要,可选PMP/MPU必须,依赖MMU做进程隔离
文件系统可选,通常用Flash分区标配,且支持多种文件系统
驱动模型devicetree + 子系统devicetree + 驱动框架
典型场景MCU、传感器节点、PLC、电机控制单板电脑、网关、边缘计算

从这张表能看出,Zephyr和Linux不是替代关系,而是互补关系。实际项目中完全可以把一个双核RISC-V SoC分成两个世界:小核跑Zephyr处理实时中断,大核跑Linux做业务逻辑。这也是很多边缘计算SoC的常见玩法。不过,这种混合架构有个前提——你得先把两个系统在同一个平台上单独跑通,理解它们的启动边界和资源开销,然后再谈核间通信。

这篇文章的路线就是这样:先跑通Zephyr,再跑通Linux,最后一章讲清楚它们在RISC-V架构下的运行边界。对刚接触RISC-V的嵌入式工程师来说,这是最快建立全局观的方式。

2. 起步阶段的环境准备:工具链、QEMU与SDK的选择

2.1 为什么先选QEMU而不是直接买板子

我见过不少朋友的路径:拿到一块真实开发板,先被刷机流程劝退,再被串口驱动折磨,最后连个点灯程序都没跑起来,板子就吃灰了。所以我强烈建议你先在QEMU上跑,而不是一上来就买板子。

理由有三条。第一,成本为零,你在自己电脑上就能完成所有实验。第二,可复现性是模拟器的天然优势,环境坏了直接删除重来,别人向你请教问题的时候,你给他一串命令就够了。第三,QEMU是Zephyr和Linux社区持续验证的平台,它的virt机器和真实硬件相比已经很接近,官方文档里的测试用例绝大多数跑在QEMU上,这意味着你踩到的坑,答案大概率已经在网上出现了。

等你在QEMU上把Zephyr和Linux的软件栈玩明白了,再买一块社区长期维护的开发板,速度会快很多。

2.2 两条工具链,千万别混着用

RISC-V的工具链和ARM不太一样,一上来就有两条路:

  • riscv64-unknown-elf-gcc:裸机工具链,针对bare-metal环境,C库用的是newlib,适合编译固件、RTOS、裸机程序。Zephyr SDK自带的就是这种。
  • riscv64-linux-gnu-gcc:面向Linux用户态,C库使用glibc,适合编译Linux内核、BusyBox、各种Linux应用程序。

很多人第一次在RISC-V上折腾,会把这两者搞混。比如用riscv64-unknown-elf工具链去编译BusyBox,链接阶段会报一堆找不到libc的错。当然,编译Linux内核本身不用libc,裸机工具链也能编内核,但如果你要制作initramfs,里面的用户态程序就必须要Linux工具链了。

我的建议很简单:Zephyr的源码和工程统一交给Zephyr SDK处理,Linux相关的内核、BusyBox、根文件系统统一用riscv64-linux-gnu-gcc,两边各管各的,省心。

2.3 一次性装齐基础环境

我的实验环境是Ubuntu 22.04,其他发行版大同小异。先更新系统并安装编译依赖:

sudo apt update && sudo apt upgrade -y sudo apt install -y --no-install-recommends \ git cmake ninja-build gperf ccache dfu-util \ device-tree-compiler wget python3-dev python3-pip \ python3-setuptools python3-tk python3-wheel xz-utils \ file make gcc gcc-multilib g++-multilib \ libsdl2-dev libmagic1 qemu-system-misc

qemu-system-misc这个包在Ubuntu里包含了qemu-system-riscv32和qemu-system-riscv64。装完之后确认一下版本:

qemu-system-riscv64 --version

建议版本不低于7.0,新版本对RISC-V虚拟机的支持更完善,特别是virt机器上的PCIe和中断控制器仿真更接近真实硬件。

另外,还需要用pip安装west,这是Zephyr官方推荐的工程管理工具:

pip3 install --user west export PATH=$HOME/.local/bin:$PATH west --version

2.4 顺手验证工具链是否可用

如果你按上面的命令装完,已经有了一部分环境。现在还需要安装Linux交叉编译工具链,趁早验证一下,避免后面Linux编译到一半才发现缺东西:

sudo apt install -y gcc-riscv64-linux-gnu riscv64-linux-gnu-gcc -v

看到gcc version信息输出就说明OK。这里再提醒一次,Zephyr的工具链和Linux的工具链是分开的,Zephyr SDK我们下一节再装,因为它的安装方式和路径会影响west build的调用方式。

3. 跑通Zephyr:从工程管理到QEMU板卡启动

3.1 west:Zephyr的工程管理入口

Zephyr不是一个单一仓库,它由zephyr主仓库、hal板级支持包、第三方库等一大堆子仓库组成。直接用git clone一个仓库是拉不完整的,west就是用来管理这个多仓库结构的工具。

初始化一个Zephyr工程的完整命令如下:

mkdir -p ~/zephyrproject cd ~/zephyrproject west init -m https://github.com/zephyrproject-rtos/zephyr --mr v3.7.0 west update

west init会根据manifest文件把顶层仓库拉下来,west update则会把manifest里声明的所有子仓库全部同步到本地。这一步会耗一些时间,取决于你的网络情况,不过是一次性的。

初始化完成之后,还要把ZEPHYR_BASE环境变量指过去,这样CMake才能通过find_package找到Zephyr构建系统:

export ZEPHYR_BASE=$HOME/zephyrproject/zephyr

建议把这一行写到你的~/.bashrc里,后面所有Zephyr工程构建都依赖它。

3.2 安装Zephyr SDK

Zephyr SDK是Zephyr官方发布的交叉编译工具链合集,里面包含了多个架构的gcc、gdb、OpenOCD等工具。对于RISC-V而言,我们需要riscv64-zephyr-elf系列。

去Zephyr官方的GitHub Release页面下载对应版本,我用的是0.16.8:

cd ~ wget https://github.com/zephyrproject-rtos/sdk-ng/releases/download/v0.16.8/zephyr-sdk-0.16.8_linux-x86_64.tar.xz tar -xf zephyr-sdk-0.16.8_linux-x86_64.tar.xz cd zephyr-sdk-0.16.8 ./setup.sh -t riscv64-zephyr-elf -c

setup.sh会把工具链安装到默认位置,并创建必要的CMake配置文件。如果你不确定这里做了什么,可以后面把环境变量也加上:

export ZEPHYR_TOOLCHAIN_VARIANT=zephyr export ZEPHYR_SDK_INSTALL_DIR=$HOME/zephyr-sdk-0.16.8

这样west build的时候就会自动选择Zephyr SDK里的riscv64工具链,而不是系统自带的gcc。

3.3 编译并启动hello_world

Zephyr官方示例很多,hello_world是最简单的一个。在QEMU上跑qemu_riscv32板卡:

cd ~/zephyrproject/zephyr west build -b qemu_riscv32 samples/hello_world west build -t run

如果一切正常,编译完成后终端会直接进入QEMU,并弹出类似下面的输出:

*** Booting Zephyr OS build v3.7.0-rc1 *** Hello World! qemu_riscv32

这一步跑通,说明你的Zephyr工具链、构建系统、QEMU模拟环境全部已经正常工作了。想换成64位体验,把-b参数改成qemu_riscv64即可:

west build -b qemu_riscv64 samples/hello_world west build -t run

3.4 从hello_world到可交互的shell

如果你觉得hello_world只是打印一句话,没看出Zephyr的系统能力,那我建议你编译一个带shell的示例。Zephyr里有个经典的shell示例:

west build -b qemu_riscv32 samples/shell/shell_module west build -t run

启动后你会进入一个交互式shell,可以输入命令查看系统状态。比如输入:

kernel version

可以看内核版本号,输入:

devices

能看到当前已经初始化的设备驱动列表。通过这个shell,你能比较直观地感受到Zephyr虽然小,但它有完整的设备模型、Kconfig配置体系和子系统框架,并不是一个玩具级别的调度循环。

3.5 写一个自己的应用并在QEMU上验证

跑通了官方示例,接下来就得试试自己写应用了。创建一个工程目录:

mkdir -p ~/hello_app/src cd ~/hello_app

CMakeLists.txt内容如下:

cmake_minimum_required(VERSION 3.20.0) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) project(hello_app) target_sources(app PRIVATE src/main.c)

src/main.c:

#include <zephyr/kernel.h> void main(void) { printk("Hello from my own RISC-V app!\n"); printk("Running on %s, %d MHz\n", CONFIG_BOARD, CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / 1000000); }

然后编译并运行:

cd ~/zephyrproject/zephyr west build -b qemu_riscv32 ~/hello_app west build -t run

你会看到自己的工程在QEMU上跑起来。这一步很重要,标志着你已经脱离了“只会看示例”的阶段,开始能自己组织Zephyr工程了。Zephyr的构建系统由CMake、Kconfig和devicetree三部分协同,后面你每加一个驱动或模块,基本都要和这三者打交道。

4. 跑通Linux:内核编译、根文件系统与QEMU启动

Zephyr跑通后,Linux这条线的难度会上一个台阶,但思路更清晰:编译内核、制作根文件系统、启动QEMU。这里我建议不要用任何发行版镜像,直接手工从源码构建,这样你对整个系统从零到一的流程才有真正的掌控感。

4.1 准备RISC-V Linux交叉工具链

前面已经装过riscv64-linux-gnu-gcc,这里再确认一次:

riscv64-linux-gnu-gcc -v

这套工具链默认使用glibc,生成的程序依赖Linux syscall接口,可以编译内核、BusyBox和用户态应用。

4.2 编译Linux内核:defconfig与Image

我用的是6.12 LTS版本内核,LTS的好处是长期维护,后面遇到问题社区资料多。

cd ~ wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.12.tar.xz tar -Jxf linux-6.12.tar.xz cd linux-6.12

配置内核时,RISC-V架构只需要指定ARCH和CROSS_COMPILE,然后选一个默认配置:

make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j$(nproc)

这个过程会编一会儿。结束后内核镜像在arch/riscv/boot/Image:

ls -l arch/riscv/boot/Image

这里有个RISC-V特有的细节:新的RISC-V内核一般没有像ARM那样使用zImage,而是直接用Image这个平铺镜像,QEMU或者U-Boot加载它非常方便。我第一次编译完还在到处找zImage,浪费了不少时间,特此提一句。

4.3 用BusyBox制作最小initramfs

Linux内核本身只是一个“空壳”,启动后需要挂载根文件系统,找到init进程。最方便的方案是做initramfs,也就是把根文件系统打包成一个cpio归档,由内核在启动时解压到内存里。这样做不需要磁盘驱动,也不需要文件系统驱动,最适合学习和验证。

先下载BusyBox:

cd ~ wget https://busybox.net/downloads/busybox-1.36.1.tar.bz2 tar -jxf busybox-1.36.1.tar.bz2 cd busybox-1.36.1

配置并编译:

make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- defconfig make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- menuconfig

注意,在menuconfig里一定要进入BusyBox Settings -> Build Options,勾选Build static binary (no shared libs)。这一步原因很直接:如果BusyBox动态链接glibc,initramfs里还得额外带上完整的libc库,否则启动后一堆命令报错找不到共享库。静态链接可以把所有依赖打进去,一个busybox二进制就是整根系统。

然后编译安装到指定目录:

make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- -j$(nproc) make ARCH=riscv CROSS_COMPILE=riscv64-linux-gnu- CONFIG_PREFIX=$HOME/rootfs install

接下来,补上proc、sys、dev目录和init脚本:

cd ~/rootfs mkdir -p proc sys dev etc sudo mknod -m 622 dev/console c 5 1

init脚本内容如下:

#!/bin/sh mount -t proc proc /proc mount -t sysfs sysfs /sys echo "Hello from RISC-V Linux init!" echo "Running with PID $$" exec /bin/sh

最后把整个rootfs目录打包成initramfs:

cd ~/rootfs find . -print0 | cpio --null -ov --format=newc | gzip -9 > ~/rootfs.cpio.gz

这个打包方式的原理比较简单:用cpio把目录结构变成归档,再用gzip压缩。内核收到cpio格式的initramfs后,会自动在内存中解压,把它作为临时根文件系统。

4.4 QEMU启动参数的拆解

现在内核和根文件系统都齐了,用一条命令把RISC-V Linux跑起来:

qemu-system-riscv64 \ -M virt \ -m 1G \ -smp 2 \ -kernel ~/linux-6.12/arch/riscv/boot/Image \ -initrd ~/rootfs.cpio.gz \ -nographic \ -append "console=ttyS0 rdinit=/init"

如果你启动后什么都看不到,先在内核命令行加earlycon看看早期日志:

-append "console=ttyS0 rdinit=/init earlycon=sbi"

把参数拆开解释一下:

  • -M virt:选择QEMU的virt虚拟机平台,这是QEMU为RISC-V设计的通用虚拟平台,包含了UART、PLIC中断控制器、CLINT定时器、PCIe控制器等外设。
  • -m 1G:给虚拟机分配1GB内存。Linux在RISC-V上对内存大小比较敏感,太小了会频繁swap,1G足够学习。
  • -smp 2:给虚拟机两个CPU核心。
  • -kernel:指定编译好的内核镜像。
  • -initrd:指定initramfs归档。
  • -nographic:把虚拟机的串口输出重定向到当前终端,方便调试。
  • -append:向内核传递命令行参数。console=ttyS0告诉内核把日志输出到串口0,rdinit=/init告诉内核initramfs解压后执行/init脚本。

QEMU virt机器默认会自动生成设备树(DTB)并传给内核,所以大部分情况下你不需要手动指定-dtb。如果你遇到外设初始化异常,或者想看看DTB里的节点结构,可以手动导出:

qemu-system-riscv64 -machine virt,dumpdtb=riscv64-virt.dtb

然后在启动命令里加上-dtb riscv64-virt.dtb,这样内核使用的设备树就完全由你掌控了。

4.5 启动后能观察到什么

启动成功后,你应该会看到OpenSBI的banner、内核早期的初始化日志,然后进入init脚本,最后停在BusyBox的sh提示符下。此时可以执行:

uname -a cat /proc/cpuinfo

uname会显示内核版本和CPU架构,cat /proc/cpuinfo能看到当前核的ISA扩展信息。这就意味着你已经有了一套可以在QEMU里“折腾”的RISC-V Linux环境。接下来无论是写内核模块、调试设备驱动,还是研究系统调用,都有了落脚点。

5. 两套系统在RISC-V上的运行边界:从启动流程到内存管理

跑通只是第一步,真正让你和别人拉开差距的,是理解这两个系统在RISC-V上各自的运行模式。

5.1 M模式、S模式与OpenSBI:RISC-V特有的固件层

RISC-V定义了三种特权模式:机器模式(M-mode)、监管者模式(S-mode)和用户模式(U-mode)。类比ARM世界的话,M-mode相当于EL3或Secure Monitor,S-mode相当于EL1内核态,U-mode相当于EL0用户态。

Zephyr在RISC-V上默认跑在M-mode,它可以直接访问所有硬件资源,不需要任何固件支持,上电之后代码直接执行,这是它启动极快的根本原因。Linux则必须跑在S-mode,因为Linux要利用MMU做进程隔离,而MMU的配置和异常处理需要OS在S-mode完成。

那么S-mode下的内核想操作硬件怎么办?RISC-V规定了一条标准通道:ecall指令。S-mode调用ecall,陷入M-mode,由M-mode固件代为完成硬件访问。这个M-mode固件,最主流的就是OpenSBI。你在QEMU启动日志里看到的OpenSBI信息,就是这段固件的功劳。

所以RISC-V跑Linux的完整启动链路是:OpenSBI(M-mode)先接管硬件,然后跳转到Linux内核(S-mode)。如果没有OpenSBI,Linux起不来。

5.2 Zephyr的启动链路:从reset向量到main

Zephyr在RISC-V上的启动流程很直接。处理器复位后,从开始地址执行arch/riscv/core/start.S里的代码,做的事情包括:

  • 初始化栈指针sp;
  • 清零bss段;
  • 设置gp全局指针,准备C运行环境;
  • 跳转到C语言入口z_cstart。

z_cstart会完成内核对象初始化、调度器初始化、设备驱动初始化,最后调用main函数。整个过程是线性的,没有虚拟地址转换,没有页表,所有指针都是物理地址。在嵌入式实时场景里,这种直接、确定性的启动方式是巨大优势。

5.3 Linux的启动链路:从OpenSBI到init

Linux在RISC-V上的启动链路要复杂得多。OpenSBI把CPU带到S-mode后,跳转到内核入口_ start_kernel,在汇编阶段完成早期页表建立和CPU特性检测,然后进入start_kernel,完成大批子系统初始化,最终通过kernel_init线程创建第一个用户态进程。

这个过程中有一个关键动作:Linux需要先解析设备树,确认内存大小、中断控制器、串口等外设信息,然后建立完整的页表映射,打开MMU。之后,所有内核代码和数据结构都运行在虚拟地址上。这也是为什么RISC-V Linux对内存大小有硬性要求的原因之一——页表本身、vmemmap、各种内核数据结构都需要物理内存支撑。

5.4 有没有MMU,决定了这两种系统的天花板

有没有MMU,是Zephyr和Linux之间最本质的分水岭。

Zephyr面向的是“直接操作硬件”的场景,不需要虚拟内存带来的隔离和保护,因此上下文切换的开销极小,只是保存和恢复寄存器。实时任务的确定性很强。

Linux面向的是“多进程共享CPU和内存”的场景,每个进程有自己的独立地址空间,一个进程崩溃不会拖垮整个系统。这种隔离靠的是MMU的页表映射。但代价是上下文切换时要切换页表,TLB也要失效,性能开销远高于RTOS。

用一个生活化的类比:Zephyr像一个小作坊,所有材料和工具都摆在桌面上,师傅拿起来就能干活,速度快但大家共享同一张桌子;Linux像一个大企业,每个部门有独立办公室,文件和权限分得很细,工作安全、互不干扰,但进出办公室都得刷卡,自然慢一些。

理解了这点,你在选择技术路线时就有了理论依据:如果项目需要硬实时、低功耗、秒级启动,Zephyr合适;如果需要复杂应用、网络协议栈、文件系统,Linux更合适。

6. 换到真实开发板之前,先排掉这些雷

QEMU跑得很顺,不代表真实板子上也能一键成功。从模拟器到真实硬件,有几个坑我几乎是必踩的。

6.1 板卡选型:官方支持列表比任何宣传都靠谱

买板子前,先查两件事。一是Zephyr的boards/riscv目录下有没有这块板子,二是Linux内核arch/riscv/boot/dts下有没有对应设备树。官方支持列表就是最权威的兼容性清单。

我见过几个典型例子:

  • SiFive HiFive1 Rev B:FE310芯片,RV32IMAC,没有MMU,只能跑Zephyr或裸机程序。
  • SiFive HiFive Unmatched:U740,多核RV64,可以跑完整的Linux,开箱支持很好。
  • StarFive VisionFive V2:JH7110,四核RV64,Linux支持较完善,Zephyr也有社区移植。

如果你看到某块板子芯片很新、性能很强,但Linux和Zephyr都没有官方支持,那就要做好自己移植驱动的心理准备,这种工作量对一个新手来说非常劝退。

6.2 Zephyr的devicetree和Linux的DTB不能互拷

Zephyr和Linux都用设备树来描述硬件,但这是两套不完全兼容的“语言”。Zephyr的设备树绑定有很多Zephyr特有属性,比如console设备标记、flash分区定义、GPIO中断标志的Zephyr扩展;而Linux的DTB遵循Linux内核的binding规范。

有次我把Linux里一块板子的dts文件直接拷贝到Zephyr工程下,编译虽然通过,但串口驱动怎么都起不来,日志里提示console设备找不到。排查到最后才发现,Zephyr的UART节点里需要status="okay"和相应的clocks属性,而Linux的dts里这些字段可能是空着的,或者由bootloader在运行时修补。

正确做法是:在Zephyr工程中,以Zephyr提供的SoC级dtsi为基准,只覆盖自己板卡相关的差异;在Linux侧,则以上游内核的dts为基准修改。两边不要互相搬运。

6.3 串口和时钟频率:最常见的板级翻车现场

QEMU里面UART时钟频率是理想值,你随便设置波特率都能输出。真实板卡可没这么宽容,UART外设的时钟源可能来自SoC内部的PLL,频率不匹配最典型的表现就是串口输出乱码。

排查乱码问题的思路很固定:

  • 查看板卡的原理图,确认调试串口的电平标准和引脚复用。
  • 查SoC手册,确认UART模块的输入时钟频率。
  • 在Zephyr的dts中检查clocks字段,在Linux的dts中检查clock-frequency字段,两边必须和硬件实际值一致。
  • 如果乱码还是存在,用逻辑分析仪抓TX引脚的波形,数一下位宽,能估算出实际波特率。

这套排查链路我走了一遍之后,基本不会再被串口问题卡住。

6.4 用QEMU调试内核早期崩溃的小技巧

真实板卡上调试Linux早期崩溃比较麻烦,但QEMU里有一个非常方便的调试手段。启动QEMU时加上-s -S参数:

qemu-system-riscv64 \ -M virt -m 1G -smp 2 \ -kernel ~/linux-6.12/arch/riscv/boot/Image \ -initrd ~/rootfs.cpio.gz \ -nographic \ -append "console=ttyS0 rdinit=/init" \ -s -S

-s表示在TCP 1234端口打开GDB调试服务,-S表示QEMU启动后先暂停,等待调试器连接。然后在另一个终端:

gdb ~/linux-6.12/vmlinux (gdb) target remote :1234 (gdb) hbreak start_kernel (gdb) continue

这样你就可以在内核入口处断下来,逐步跟踪早期启动过程。很多内核早期崩溃,比如页表配置错误、设备树解析失败,都可以用这种方式快速定位。

7. 一点实操后的个人体会

这套流程完整走下来之后,我对RISC-V、Zephyr和Linux的理解比过去几年看文档都深。在这里分享一些个人体会。

先学哪个?我建议先Zephyr后Linux。Zephyr的构建系统虽然初看很绕(west、CMake、Kconfig、devicetree),但它规模小,你能在一天内看到完整的“从源码到运行”闭环。有了这个基础再去碰Linux,你会更容易理解内核在干什么,而不是被编译日志淹没。

学的时候尽量别一股脑上高性能开发板。QEMU的好处是你敢随便改配置,改坏了重来就是一行命令的事。真实板子刷坏了可能得用JTAG救砖,心态完全不一样。我自己的经验是,QEMU上的Zephyr和Linux各跑通一遍之后,再拿真实板子来验证,整个过程会顺畅很多。

再分享一个小技巧:遇到问题时,先去看上游代码和官方文档,而不是零散搜博客。Zephyr的Documentation目录、Linux的Documentation/riscv目录都是很好的起点。网络上很多教程是别人基于老版本写的,RISC-V生态迭代太快,版本不匹配会让你莫名其妙的踩坑。

最后想说的是,RISC-V学习的最大价值,不在于你用哪个OS,而在于你能同时看到RTOS和通用OS在同一个ISA上是怎么协作、怎么分工的。这份全局视角,在传统ARM生态里需要花不少钱和时间才能摸到边,在RISC-V上你只要一个免费模拟器。把这份折腾精神保持住,你的嵌入式功底一定会比同龄人厚实不少。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询