news 2026/9/12 14:09:36

Linux 内核 OpenRISC 架构移植指南:从工具链搭建、内核编译到 FPGA 与 QEMU 运行

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Linux 内核 OpenRISC 架构移植指南:从工具链搭建、内核编译到 FPGA 与 QEMU 运行

Linux 内核 OpenRISC 架构移植指南:从工具链搭建、内核编译到 FPGA 与 QEMU 运行

【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux

导读

本指南围绕 Linux 内核仓库中的 OpenRISC 架构移植(Port)展开,系统讲解这一将 Linux 移植到 OpenRISC 类微处理器(以 32 位 OpenRISC 1000 家族、即 or1k 为初始目标)的架构移植工作的全貌。文章以 Documentation/arch/openrisc/openrisc_port.rst 为骨架,结合 arch/openrisc 下的源码、Kconfig 配置与各平台 defconfig,完整覆盖工具链准备、内核交叉编译、initramfs 嵌入、FPGA 板级运行(FuseSoC + OpenOCD)以及 QEMU 模拟运行等实战流程。读完本文,你将掌握从零构建并运行 OpenRISC Linux 内核的完整操作链路,并理解 or1k 移植在配置、指令集与设备树层面的工程细节。


一、OpenRISC 移植概览

OpenRISC 是一个开源的精简指令集(RISC)处理器架构,而 Linux 内核对其的支持是一个完整的架构移植(port)。该移植的初始目标是32 位的 OpenRISC 1000 家族(or1k),其核心实现集中在仓库的 arch/openrisc 目录下,涵盖:

  • 内核启动与异常/陷阱处理:head.Sentry.Straps.c
  • 进程与信号管理:process.csignal.cptrace.c
  • 内存管理(MMU、TLB、ioremap):mm/子目录
  • 中断控制器(OR1K PIC)与定时器:irq.csync-timer.c
  • 设备树(Device Tree)启动与平台初始化:prom.csetup.c
  • 对称多处理(SMP)支持:smp.c

从 arch/openrisc/Kconfig 可以看到,该移植是一套相当完整的架构配置:定义了OPENRISC架构入口,并选中了OF(Device Tree)、IRQ_DOMAINGENERIC_IRQ_CHIPHAVE_ARCH_JUMP_LABELHAVE_PCIMMUSMP(可配)以及PCI_MSI if PCI等一系列基础设施,说明该移植已深度接入主线内核的通用框架。

术语表:openrisc / or1k / or1200

原文档明确指出,在代码中以下三个前缀用于限定符号的作用范围,避免混淆不同层级的处理器实现:

代码中的称谓含义
openriscOpenRISC 类处理器(架构大类)
or1kOpenRISC 1000 家族处理器
or1200OpenRISC 1200 处理器(具体实现)

这一约定在源码中随处可见:例如 arch/openrisc/Kconfig 中的子架构选项OR1K_1200(对应 OR1200 通用架构),以及设备树节点中出现的compatible = "opencores,or1200-rtlsvn481"。理解这三个层次的差异,是阅读 OpenRISC 相关代码的前提。


二、第一步:搭建 OpenRISC 工具链

要编译 Linux 内核,首先需要一个针对 OpenRISC 目标的交叉编译工具链。原文档给出的途径包括:

  1. 直接获取预编译二进制工具链:可从 openrisc.io 软件页面或社区维护者的工具链构建发布页获取现成的or1k-linux-系列工具链二进制。
  2. 自行构建工具链:社区维护者(Stafford)提供了工具链构建与发布脚本(or1k-toolchain-build),按其中说明即可从源码构建完整工具链。

无论采用哪种方式,最终目的是获得前缀为or1k-linux-的交叉编译工具(gcc、binutils、glibc 等)。内核编译时通过CROSS_COMPILE="or1k-linux-"指定该前缀。

提示:原文档中的链接均为社区外部资源,此处仅说明获取途径。对内核侧而言,只要or1k-linux-gcc等工具位于PATH中即可正常编译。


三、编译 OpenRISC Linux 内核

3.1 最小构建命令

原文档给出的标准构建流程非常简洁,只需两条命令:

make ARCH=openrisc CROSS_COMPILE="or1k-linux-" defconfig make ARCH=openrisc CROSS_COMPILE="or1k-linux-"

第一条命令生成默认配置。这里的defconfig会读取 arch/openrisc/Makefile 中声明的默认配置目标:

KBUILD_DEFCONFIG := or1ksim_defconfig

即默认采用 arch/openrisc/configs/or1ksim_defconfig(面向 OpenRISC 模拟器平台)。第二条命令执行完整的内核编译。

值得注意的是,arch/openrisc/Makefile 还定义了两个与其它架构不同的行为:

  • KBUILD_CFLAGS += -pipe -ffixed-r10 -D__linux__以及-msfimm -mshftimm,对编译选项做了架构定制;
  • all: vmlinux.bin—— 默认目标除了生成vmlinuxELF 外,还会通过 arch/openrisc/boot/Makefile 用 objcopy 生成纯二进制镜像vmlinux.bin-O binary),便于直接烧写进 FPGA 或加载到模拟器。

3.2 可选:嵌入 initramfs

如果希望在编译阶段就把根文件系统直接嵌入内核镜像,需要额外传递CONFIG_INITRAMFS_SOURCE,例如:

make ARCH=openrisc CROSS_COMPILE="or1k-linux-" \ CONFIG_INITRAMFS_SOURCE="path/to/rootfs path/to/devnodes"

该选项的值是一个或多个路径(目录、cpio 归档等),内核构建系统会将其打包为 initramfs 嵌入镜像。更多细节可参考仓库中的 Documentation/filesystems/ramfs-rootfs-initramfs.rst。

从 defconfig 可以看出,无论是 or1ksim_defconfig 还是 de0_nano_defconfig 都开启了CONFIG_BLK_DEV_INITRD=y,说明 initramfs 是 OpenRISC 平台常见的根文件系统方案。

3.3 针对不同平台的配置目标

除了模拟器平台,仓库还提供了面向其它硬件平台的 defconfig(全部位于 arch/openrisc/configs):

配置文件目标平台
or1ksim_defconfigOpenRISC 模拟器(默认)
de0_nano_defconfigTerasic De0 Nano FPGA 开发板(单核)
de0_nano_multicore_defconfigDe0 Nano 多核(SMP)配置
or1klitex_defconfigOR1K LiteX 平台
simple_smp_defconfig通用 SMP 平台
virt_defconfig虚拟化平台

使用方式与标准流程一致,例如:

make ARCH=openrisc CROSS_COMPILE="or1k-linux-" de0_nano_defconfig make ARCH=openrisc CROSS_COMPILE="or1k-linux-"

以 or1ksim_defconfig 为例,可以看到针对模拟器环境的精简配置:启用CONFIG_NO_HZCONFIG_HZ_100CONFIG_JUMP_LABELCONFIG_MODULESCONFIG_DEVTMPFS(自动挂载)、以太网驱动CONFIG_ETHOC(OpenCores 以太网控制器)、CONFIG_SERIAL_8250及其控制台支持,并指定CONFIG_BUILTIN_DTB_NAME="or1ksim"将设备树编入内核。而 de0_nano_defconfig 则额外开启了CONFIG_GPIO_SYSFSCONFIG_NEW_LEDS与一系列 LED 触发器(heartbeat、cpu、netdev 等),以匹配 De0 Nano 板上的 GPIO/LED 外设。


四、内核配置要点:从 Kconfig 看 or1k 移植细节

arch/openrisc/Kconfig 是理解该移植能力边界的最佳入口,原文档虽未展开,但其背后的配置选项直接决定内核能否在目标处理器上正确运行。

4.1 子架构与缓存

  • OR1K_1200:当前唯一的子架构选择,即 OR1200 通用架构(默认选中)。
  • DCACHE_WRITETHROUGH:如果你的实现采用写透(write-through)数据缓存,应开启此项;关闭时内核会在必要时强制冲刷数据缓存。大多数 OpenRISC 实现支持写透缓存,拿不准时选 N。

4.2 Class II 指令集开关

OpenRISC 1000 定义了可选的 Class II 指令。Kconfig 提供一组开关,让内核针对具体处理器实现启用(或不启用)这些指令。启用后 GCC 可生成对应指令,通常会提升性能并减小二进制体积:

配置项对应指令默认值
OPENRISC_HAVE_INST_FF1l.ff1(前导一计数)y
OPENRISC_HAVE_INST_FL1l.fl1y
OPENRISC_HAVE_INST_MULl.mul(硬件乘法)y
OPENRISC_HAVE_INST_DIVl.div(硬件除法)y
OPENRISC_HAVE_INST_CMOVl.cmov(条件移动)n
OPENRISC_HAVE_INST_RORl.ror(循环右移)n
OPENRISC_HAVE_INST_RORIl.rori(立即数循环右移)n
OPENRISC_HAVE_INST_SEXTl.ext*(符号/零扩展系列)n

这些开关会直接反映到内核编译选项上:arch/openrisc/Makefile 中根据对应配置追加-mhard-mul/-msoft-mul-mhard-div/-msoft-div-mcmov-mror-mrori-msext等 GCC 选项,实现硬件指令与软件模拟的自动切换。

4.3 多核、FPU 与异常行为

  • SMPNR_CPUS(范围 2–32):启用对称多处理,NR_CPUS默认 2。SMP 场景下必须依赖影子寄存器组(见下)。
  • FPU(默认 y):关闭可剔除内核中所有浮点相关处理过程以减小体积。
  • OPENRISC_NO_SPR_SR_DSX(默认 y,仅 OR1K_1200):SPR_SR_DSX是状态寄存器中指示“上一次异常是否发生在延迟槽(delay slot)”的位。OpenRISC 架构允许硬件不实现该位,而 OR1200 恰好没有实现,因此内核默认用软件方式模拟该语义;只有确认你的处理器实现了该位才可关闭。
  • OPENRISC_HAVE_SHADOW_GPRS:处理器是否具备影子寄存器组(shadow register file)。启用后,异常入口可将通用寄存器暂存到影子寄存器中,避免额外的保存开销;在 SMP 系统上该特性是必需的。
  • CMDLINE:对没有 bootloader 传递参数的平台,可在编译期内置默认内核命令行。

4.4 调试选项

  • JUMP_UPON_UNHANDLED_EXCEPTION(默认 y):首次 oops 后让内核进入死循环,便于定位问题。
  • OPENRISC_ESR_EXCEPTION_BUG_CHECK(默认 n):开启一些可能暴露内核潜在问题的检查。

五、在 FPGA 上运行(可选)

OpenRISC 社区通常借助FuseSoC来管理 SoC 的构建与烧写流程:FuseSoC 在构建时从 IP 核仓库下载 FPGA RTL 代码,再调用 FPGA 厂商工具完成综合与布局布线,最后通过OpenOCD将二进制加载到开发板。

原文档以 Terasic De0 Nano 开发板为例给出完整流程:

# 1) 安装 FuseSoC(Python 包,以可编辑模式安装) git clone <fusesoc-repo> cd fusesoc sudo pip install -e . # 2) 初始化并构建/烧写 De0 Nano 的 OpenRISC SoC fusesoc init fusesoc build de0_nano fusesoc pgm de0_nano # 3) 启动 OpenOCD,连接板载 Altera USB-Blaster 调试器与 or1k 目标 openocd -f interface/altera-usb-blaster.cfg \ -f board/or1k_generic.cfg # 4) 通过 telnet 进入 OpenOCD 命令界面,加载内核镜像并复位运行 telnet localhost 4444 > init > halt; load_image vmlinux ; reset

上述de0_nano目标与内核侧 arch/openrisc/configs/de0_nano_defconfig 一一对应,其板级设备树描述位于 arch/openrisc/boot/dts/de0-nano.dts(与de0-nano-common.dtsi配合)。内核编译产物vmlinux(ELF)正是 OpenOCDload_image直接加载的镜像;若烧写裸二进制,则使用默认目标生成的vmlinux.bin


六、在 QEMU 上运行(可选)

对于没有硬件或 FPGA 开发板的开发者,QEMU是官方推荐的 OpenRISC 平台模拟器。原文档建议两种方式:

  1. 自行编译 QEMU,启用 OpenRISC 目标支持;
  2. 使用发行版提供的二进制包——多数主流 Linux 发行版都带有支持 OpenRISC 的 QEMU 包,这是最快的方式。

在 QEMU 中运行 Linux 的具体步骤以 QEMU 官方 OpenRISC 平台文档为准。仓库侧与之配套的默认配置正是 or1ksim_defconfig 与设备树 arch/openrisc/boot/dts/or1ksim.dts。

从 or1ksim.dts 可以看出模拟器平台的外设布局:compatible = "opencores,or1ksim",内存起始于 0x0 且大小为 32 MiB(reg = <0x00000000 0x02000000>),CPU 为opencores,or1200(20 MHz 时钟),串口为兼容ns16550a的 OpenCores UART(serial@90000000),以太网为 OpenCoresethocenet0@92000000),中断控制器为 CPU 内置的opencores,or1k-pic(通过特殊功能寄存器访问,无地址空间)。chosen节点中bootargs = "earlycon"stdout-path = "uart0:115200"指定了早期控制台输出。编译该平台时,CONFIG_BUILTIN_DTB_NAME="or1ksim"会把这棵设备树直接内嵌进内核镜像,免去外部传递 DTB 的步骤。


七、移植现状与 TODO

Documentation/arch/openrisc/todo.rst 对该移植的现状做了补充说明:OpenRISC Linux 移植已完全可用,并且自 Linux 2.6.35 起持续跟随主线演进。剩余的工作项包括:

  • 补齐 DMA API 的其余部分(如dma_map_sg等);
  • 完成命名清理:代码中仍残留or32引用——这是该架构的旧名,现已统一为or1k,改名工作正在逐步推进;目前or32or1k等价。

此外,Documentation/arch/openrisc/index.rst 将openrisc_porttodofeatures三份文档组织为 OpenRISC 架构文档集;其中 features.rst 通过kernel-feat指令自动从内核特性列表生成,可作为查询该架构功能支持矩阵的入口。


八、历史沿革

原文档保留了该移植的完整历史记录,反映了 Linux/OpenRISC 移植从早期原型到上游化的演进脉络:

日期作者里程碑
2003-11-18Matjaz Breskvar将 Linux 初始移植到 OpenRISC/or32 架构,核心功能可用
2003-12-08Matjaz Breskvar完全重写 TLB miss 处理与异常处理;默认 initrd 中可运行完整的 sash-3.6 shell
2004-04-10Matjaz Breskvar大量缺陷修复;加入以太网支持,可运行 HTTP 与 telnet 服务器,可跑众多标准 Linux 应用
2004-06-26Matjaz Breskvar移植到 2.6.x 内核
2004-11-30Matjaz Breskvar大量缺陷修复与增强;加入 OpenCores framebuffer 驱动
2010-10-09Jonas Bonn大规模重写,使其与上游 Linux 2.6.36 保持一致

这段历史解释了代码中or32/or1k名称并存的由来,也与 todo.rst 中“or32 是 or1k 的旧名”的说明相互印证。


总结

围绕 openrisc_port.rst 这篇官方移植文档,本文完整还原了 OpenRISC Linux 的构建与运行链路:从获取or1k-linux-交叉工具链,到make ARCH=openrisc完成内核与vmlinux.bin的构建,再到通过CONFIG_INITRAMFS_SOURCE嵌入根文件系统;随后分别给出了 FPGA(FuseSoC + OpenOCD)与 QEMU 两条运行路径,并结合 arch/openrisc/Kconfig 与各平台 defconfig 深入剖析了 Class II 指令开关、缓存策略、SMP/FPU 及异常行为等配置要点。对于希望深入该移植的开发者,arch/openrisc 目录下的启动代码(head.Sentry.S)、内存管理(mm/)与平台初始化(prom.csetup.c)是继续阅读的首选入口。

【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/12 14:07:11

Python实战:NASA API数据获取与可视化全攻略

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 14:06:33

32KB MCU实现边缘AI:ML-KWS-for-MCU静态架构解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 14:03:33

ToF相机深度解析:光机电算协同系统设计与实战调优

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/12 13:57:26

SpringBoot家庭理财系统设计与实现

1. 项目概述&#xff1a;SpringBoot家庭理财系统设计背景这个基于SpringBoot的家庭理财管理系统&#xff0c;本质上是一个面向个人和家庭的轻量级财务数字化解决方案。在移动支付普及和消费多元化的今天&#xff0c;传统的手工记账方式已经难以满足现代家庭对财务管理的实时性、…

作者头像 李华