FEATURED · 精选文章

Linux 内核 Nios II 架构移植详解:在 Altera FPGA 上运行 Linux 的配置、编译与源码实现

发布时间 / 2026/9/12 12:40:56
来源 / 创域科博编辑部
栏目 / 资讯中心
Linux 内核 Nios II 架构移植详解:在 Altera FPGA 上运行 Linux 的配置、编译与源码实现 Linux 内核 Nios II 架构移植详解在 Altera FPGA 上运行 Linux 的配置、编译与源码实现【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux导读本文以 Documentation/arch/nios2/index.rst 及其核心文档 Documentation/arch/nios2/nios2.rst 为主体系统讲解 Linux 内核如何移植到 Altera现 Intel FPGA的 Nios II 32 位嵌入式处理器上。你将掌握 Nios II 处理器为支持 Linux 所需的硬件前提MMU 与硬件乘法器、内核 Kconfig 中与 Nios II 相关的全部配置项及其含义、官方 defconfig 与设备树Device Tree的组织方式以及从编译标志到启动镜像的完整构建流程并深入理解 arch/nios2 目录下的源码实现细节。一、Nios II 架构与 Linux 移植概述Nios II 是 Altera 公司为自家 FPGA 产品线专门设计的 32 位嵌入式处理器架构。它属于软核处理器soft-core processor即处理器本身以可综合的硬件描述语言形式存在开发者可以在 FPGA 中按需配置其功能再通过 Quartus / QSYS 工具链生成对应硬件系统。Linux 对 Nios II 的支持正是这样一个“将通用操作系统移植到可配置软核”的经典案例。根据 Documentation/arch/nios2/nios2.rst 的说明这是一个专门针对 Nios IIarch 名nios2处理器的 Linux 移植port要编译该移植版本的内核需要一份支持通用系统调用 ABIgeneric system call ABI的 GCC 交叉编译器文档同时给出了编译与启动 Nios II 平台软件的官方参考指引以及 Altera 官方 Nios II 处理器资料Nios II Processor Reference Handbook。运行 Linux 的硬件前提MMU 与硬件乘法器原文档明确指出为了支持 LinuxNios II 处理器必须配置为启用 MMU 和硬件乘法器hardware multiplier。这一点在源码中得到了严格印证arch/nios2/Kconfig 中config MMU被硬编码为def_bool y即 Nios II 移植强制启用 MMU不可关闭arch/nios2/platform/Kconfig.platform 中的NIOS2_HW_MUL_SUPPORT等选项用于告知内核硬件是否实现了 MUL/DIV 等指令arch/nios2/kernel/cpuinfo.c 在启动早期会对设备树中的硬件能力与内核编译配置做一致性校验若内核启用了CONFIG_NIOS2_HW_MUL_SUPPORT而设备树中altr,has-mul属性缺失会直接打印ERROR: Nios II MUL different for kernel and DTS警告对应源码中的err_cpu()宏。此外Nios II 移植还具备以下架构级特征来源于 arch/nios2/Kconfig 的select语句可视为移植的“能力清单”特性说明ARCH_NO_SWAP不支持交换分区swapFPU默认def_bool n无硬件浮点单元HAVE_PAGE_SIZE_4KB仅支持 4KB 页大小NR_CPUS默认 1Nios II 为单核MODULES_USE_ELF_RELA内核模块使用 RELA 重定位格式OF/OF_EARLY_FLATTREE强制依赖扁平设备树DTB描述硬件GENERIC_CSUM/GENERIC_HWEIGHT使用内核通用校验和与位计数实现NO_IOPORT_MAP无传统 I/O 端口地址空间TIMER_OF/COMMON_CLK/IRQ_DOMAIN/SPARSE_IRQ基于设备树的时钟、定时器与中断基础设施二、Nios II ABI 与工具链要求原文档的 Nios II ABI 一节明确指出应用二进制接口Application Binary Interface的完整规范请参考Nios II Processor Reference Handbook中的 Application Binary Interface 章节。从内核源码可以补充以下几点实现层面的 ABI 事实内核的KBUILD_CFLAGS会根据架构修订版本与指令集扩展生成对应的编译标志详见 arch/nios2/Makefile-marchr$(CONFIG_NIOS2_ARCH_REVISION)指定 Nios II R1 或 R2 架构-mhw-mul/-mno-hw-mul、-mhw-mulx/-mno-hw-mulx、-mhw-div/-mno-hw-div对应硬件乘/乘扩展/除指令-mbmx/-mno-bmx、-mcdx/-mno-cdxNios II R2 的位操作扩展指令-mcustom-fpu-cfg60-1当启用NIOS2_FPU_SUPPORT时使用 Altera 自定义浮点指令配置另有-fno-builtin、-G 0禁用小数据段聚合等嵌入式优化标志。系统调用表位于 arch/nios2/kernel/syscall_table.c对应的用户态头文件为 arch/nios2/include/uapi/asm/unistd.h这正对应原文档所说的“generic system call ABI”——Nios II 使用 Linux 内核的通用系统调用编号方案因此需要支持该 ABI 的 GCC 工具链。注意Nios II 的 R1 与 R2 两个架构修订版本是二进制不兼容的Kconfig 帮助文本原文为 The architectures are binary incompatible编译内核时必须通过CONFIG_NIOS2_ARCH_REVISION取值范围 1~2默认 1明确指定目标架构。三、Nios II 内核配置详解Kconfig3.1 基础配置arch/nios2/Kconfig打开 arch/nios2/Kconfig 可以看到 Nios II 移植的核心配置菜单包括MMUdef_bool y强制启用NR_CPUS固定为 1NIOS2_ALIGNMENT_TRAPCatch alignment trap默认 yNios II CPU 无法执行总线非对齐访问2/4 字节取数必须落在 2/4 字节对齐地址上。开启该选项后非对齐的 load/store 指令会被陷入并在软件中模拟执行代价是性能下降Boot options引导参数CMDLINE_BOOL/CMDLINE在引导加载程序无法传递内核参数的平台上编译期内置默认内核命令行CMDLINE_FORCE强制内置命令行覆盖引导加载程序传入的参数NIOS2_CMDLINE_IGNORE_DTB默认 y忽略设备树chosen节点中的bootargsNIOS2_PASS_CMDLINE使用 U-Boot 环境变量bootargs作为内核命令行会覆盖“默认内核命令字符串”NIOS2_BOOT_LINK_OFFSET默认0x00500000设置 zImage 的链接地址偏移对内存较小的板卡可用。Advanced setup高级内存区域设置NIOS2_KERNEL_MMU_REGION_BASE默认0x80000000内核 MMU 区域的虚拟基址NIOS2_KERNEL_REGION_BASE默认0xc0000000内核区域虚拟基址即 MMU 开启后内核线性映射的起始地址cpuinfo与设备树相关代码均依赖该地址约定NIOS2_IO_REGION_BASE默认0xe0000000I/O 区域虚拟基址。3.2 平台配置arch/nios2/platform/Kconfig.platformarch/nios2/platform/Kconfig.platform 定义了与具体 FPGA 硬件系统强相关的选项可归纳为四类内存设置NIOS2_MEM_BASE默认0x00000000内核运行的物理内存基址直接用于内核链接与初始内存管理该地址是裸物理地址若经过桥接bridge连接需要手工做地址转换。设备树加载方式NIOS2_DTB_AT_PHYS_ADDRNIOS2_DTB_PHYS_ADDR默认0xc0000000从固定物理地址加载 DTB可在没有引导加载程序的情况下直接使用设备树例如把 DTB 存入 NOR Flash 或片上 ROM使用 MMU 时地址需加上0xC0000000偏移BUILTIN_DTBBUILTIN_DTB_NAME将指定 DTS 编译并链接进内核镜像实现“内置设备树”。Nios II 指令集配置决定编译标志与运行时一致性校验配置项对应编译器标志说明NIOS2_ARCH_REVISION-marchrNNios II R1 或 R2二者二进制不兼容默认 R1NIOS2_HW_MUL_SUPPORT-mhw-mul硬件乘法指令 MULNIOS2_HW_MULX_SUPPORT-mhw-mulx硬件乘扩展指令 MULXNIOS2_HW_DIV_SUPPORT-mhw-div硬件除法指令 DIVNIOS2_BMX_SUPPORT-mbmxR2 位操作扩展仅 R2NIOS2_CDX_SUPPORT-mcdxR2 压缩指令扩展仅 R2NIOS2_FPU_SUPPORT-mcustom-fpu-cfg60-1Altera 自定义浮点指令NIOS2_CI_SWAB_SUPPORT—QSYS 中配置的字节交换endian converter自定义指令加速内核ntohs等字节序转换缓存设置CUSTOM_CACHE_SETTINGS默认关闭仅当需要在设备树信息可用前的早期启动阶段调整缓存参数时开启。Kconfig 帮助文本明确建议“除非你清楚自己在做什么否则选 N”并说明即使 Nios II 配置了更小的缓存Linux 也能正常工作NIOS2_DCACHE_SIZE范围0x200~0x10000默认0x800、NIOS2_DCACHE_LINE_SIZE范围0x10~0x20默认0x20、NIOS2_ICACHE_SIZE范围0x200~0x10000默认0x1000。3.3 官方 defconfig两款参考板卡仓库在 arch/nios2/configs 下提供了两款官方参考板卡的默认配置且 arch/nios2/Makefile 将KBUILD_DEFCONFIG : 3c120_defconfig设为默认10m50_defconfig对应 MAX 10 FPGA 开发板设备树见 10m50_devboard.dts关键差异项为CONFIG_NIOS2_MEM_BASE0x80000003c120_defconfig对应 Cyclone III 3C120 开发板差异项为CONFIG_NIOS2_MEM_BASE0x10000000、CONFIG_NIOS2_PASS_CMDLINEy、CONFIG_NIOS2_BOOT_LINK_OFFSET0x00800000。两者共同的基础配置包括CONFIG_NIOS2_HW_MUL_SUPPORTy CONFIG_NIOS2_HW_DIV_SUPPORTy CONFIG_CUSTOM_CACHE_SETTINGSy CONFIG_NIOS2_DCACHE_SIZE0x8000 CONFIG_NIOS2_ICACHE_SIZE0x8000 # CONFIG_NIOS2_CMDLINE_IGNORE_DTB is not set CONFIG_MODULESy CONFIG_MODULE_UNLOADy CONFIG_SERIAL_8250y CONFIG_SERIAL_8250_CONSOLEy CONFIG_SERIAL_OF_PLATFORMy CONFIG_SERIAL_ALTERA_JTAGUARTy CONFIG_MTDy CONFIG_JFFS2_FSy CONFIG_NFS_FSy CONFIG_ROOT_NFSy从中可以看到 Nios II 板级 Linux 的典型形态通过 8250 兼容 UART 或 Altera JTAG UART 作为控制台MTD JFFS2 承载根文件系统NFS 作为网络启动root on NFS选项网络驱动使用ALTERA_TSETriple-Speed Ethernet Marvell PHY。3.4 内核内存区域的虚拟地址布局结合 Kconfig 默认值与 arch/nios2/kernel/cpuinfo.c 等实现Nios II 移植的虚拟地址空间可归纳为区域虚拟地址用途内核 MMU 区域0x80000000起内核页表管理的 MMU 区域NIOS2_KERNEL_MMU_REGION_BASE内核区域0xc0000000起内核线性映射NIOS2_KERNEL_REGION_BASE设备树地址换算中“加 0xC0000000”即指此I/O 区域0xe0000000起外设 I/O 映射NIOS2_IO_REGION_BASE四、设备树硬件能力的唯一真相来源Nios II 移植完全基于扁平设备树FDT描述硬件这一点由 Kconfig 中强制select OF与OF_EARLY_FLATTREE保证。以 10m50_devboard.dts 为例CPU 节点完整描述了处理器能力cpu: cpu0 { device_type cpu; compatible altr,nios2-1.1; reg 0x00000000; interrupt-controller; #interrupt-cells 1; altr,exception-addr 0xc8000120; altr,fast-tlb-miss-addr 0xc0000100; altr,has-div 1; altr,has-initda 1; altr,has-mmu 1; altr,has-mul 1; altr,implementation fast; altr,pid-num-bits 8; altr,reset-addr 0xd4000000; altr,tlb-num-entries 256; altr,tlb-num-ways 16; altr,tlb-ptr-sz 8; clock-frequency 75000000; dcache-line-size 32; dcache-size 32768; icache-line-size 32; icache-size 32768; };这些属性与 arch/nios2/kernel/cpuinfo.c 中的setup_cpuinfo()一一对应内核启动早期读取altr,has-*系列属性判断硬件指令能力读取 TLB 参数altr,tlb-num-ways、altr,tlb-num-entries、altr,pid-num-bits计算tlb_num_lines等值并将CONFIG_NIOS2_ICACHE_SIZE/CONFIG_NIOS2_DCACHE_SIZE/CONFIG_NIOS2_DCACHE_LINE_SIZE与设备树中的缓存参数比对不一致时打印Warning: icache/dcache ... configuration mismatch。该文件同时揭示了几个启动早期的重要检查若设备树中找不到 CPU 节点panic(%s: No CPU found in devicetree!)若 CPU 未实现initda指令altr,has-initda为假说明数据缓存行小于 4 字节直接panic要求更新硬件系统若altr,tlb-num-ways为 0同样panic提示检查硬件系统。设备树中的chosen节点还承担了命令行传递功能chosen { bootargs debug earlycon consolettyS0,115200; stdout-path a_16550_uart_0; };这与前文 Kconfig 中的NIOS2_CMDLINE_IGNORE_DTB/NIOS2_PASS_CMDLINE选项直接相关是否采用bootargs、是否由 U-Boot 覆盖均由这三者协同决定。五、编译与启动从源码到 vmImage5.1 构建目标根据 arch/nios2/MakefileNios II 的默认构建产物为vmImageall: vmImage同时支持zImage二者均依赖vmlinux生成nios2-boot : arch/$(ARCH)/boot BOOT_TARGETS vmImage zImage KBUILD_IMAGE : $(nios2-boot)/vmImage all: vmImage $(BOOT_TARGETS): vmlinux $(Q)$(MAKE) $(build)$(nios2-boot) $(nios2-boot)/$vmImage面向 U-Boot 的内核镜像Kernel-only image for U-BootzImage压缩内核镜像其链接偏移由CONFIG_NIOS2_BOOT_LINK_OFFSET控制install调用 arch/nios2/boot/install.sh 安装内核默认安装路径为INSTALL_PATH ? /tftpboot典型 TFTP 网络启动场景脚本会将旧镜像备份为vmlinuz.old、写入vmlinuz并拷贝System.map。5.2 典型构建命令# 使用默认 defconfig3c120_defconfig生成 .config make ARCHnios2 CROSS_COMPILEnios2-linux-gnu- defconfig # 或显式选用 MAX 10 板卡配置 make ARCHnios2 CROSS_COMPILEnios2-linux-gnu- 10m50_defconfig # 调整配置 make ARCHnios2 CROSS_COMPILEnios2-linux-gnu- menuconfig # 构建 vmImage默认目标 make ARCHnios2 CROSS_COMPILEnios2-linux-gnu- # 构建 zImage / 安装到 /tftpboot make ARCHnios2 CROSS_COMPILEnios2-linux-gnu- zImage make ARCHnios2 CROSS_COMPILEnios2-linux-gnu- install前置条件是交叉编译器支持generic system call ABI原文档特别强调且宿主机具备 GNU 工具链的-marchr1/r2、-mhw-mul等 Nios II 特有标志能力。启动阶段由引导程序典型为 U-Boot加载 vmImage/zImage 与 DTB内核依据前文所述三种方式引导程序传递 / 固定物理地址 / 内置 DTB获得设备树后完成初始化。5.3 启动早期日志可观测性在内核配置设备树后可通过/proc/cpuinfo观察运行时能力由 arch/nios2/kernel/cpuinfo.c 的show_cpuinfo()生成输出格式包括CPU: Nios II/fast REV: 1 MMU: present FPU: none Clocking: 75.00 MHz BogoMips: ... MUL: yes / MULX: no / DIV: yes / BMX: no / CDX: no Icache: 32kB, line length: 32 Dcache: 32kB, line length: 32 TLB: 16 ways, 256 entries, 8 PID bits这与设备树中的 CPU 属性严格对应可作为硬件配置是否正确的快速验证手段。六、源码结构导航Nios II 移植的完整源码位于 arch/nios2 目录结构清晰、职责分明便于读者按需深入子目录/文件内容arch/nios2/kernel启动入口head.S、entry.S、中断irq.c、异常/陷阱traps.c、信号signal.c、进程管理process.c、系统调用表、CPU 信息cpuinfo.c、KGDB 调试支持、非对齐访问模拟misaligned.c、指令集模拟insnemu.S等arch/nios2/mm页表pgtable.c、TLBtlb.c、缺页处理fault.c、缓存刷新cacheflush.c、DMA 映射、ioremap、uaccessarch/nios2/include/asm架构相关头文件寄存器定义registers.h、MMUmmu.h、页表位pgtable-bits.h、系统调用等arch/nios2/boot压缩启动compressed/、设备树源dts/、安装脚本install.sharch/nios2/configs官方板卡 defconfigarch/nios2/platform平台相关配置与platform.carch/nios2/lib架构优化的memcpy、memmove、memset、delayarch/nios2/Kconfig 与 arch/nios2/platform/Kconfig.platform全部架构级与平台级配置选项七、总结Linux 对 Nios II 的支持是一份典型的“面向可配置软核处理器”的架构移植硬件前提明确必须启用 MMU 与硬件乘法器内核侧强制CONFIG_MMUy并在启动早期通过设备树校验硬件能力与编译配置的一致性配置体系完整从指令集扩展MUL/MULX/DIV/BMX/CDX/FPU/自定义指令、内存区域布局0x80000000/0xc0000000/0xe0000000、缓存参数到引导命令行策略arch/nios2/Kconfig 与 arch/nios2/platform/Kconfig.platform 提供了细粒度的控制面设备树驱动一切CPU 能力、TLB 结构、时钟、串口、以太网、GPIO、定时器全部由 DTB 描述配合BUILTIN_DTB或固定地址 DTB 可在无引导程序场景下启动构建流程简单直接make ARCHnios2 ... defconfig后构建默认产出面向 U-Boot 的vmImage配合install目标可完成 TFTP 目录部署。对于希望在 Altera/Intel FPGA 上运行 Linux 的开发者而言理解 Documentation/arch/nios2/nios2.rst 中关于 MMU/硬件乘法器要求与通用系统调用 ABI 工具链的前提再结合本文梳理的 Kconfig、defconfig 与设备树细节即可快速完成从硬件配置到内核启动的完整链路搭建。【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻