当前位置: 首页 > news >正文

Qemu-NUC980(一):SOC框架代码添加

概述

从这篇博文开始,作者开始连载NUC980 arm的qemu仿真实现,实现Nuc980 CPU上的大部分控制器的实现,并同时使用FreeRTOS和linux系统来验证qemu nuc980的仿真结果。

添加步骤

1、在include/hw/arm/目录下创建nuc980.h,如下所示:

+号部分为新增加内容

diff --git a/include/hw/arm/nuc980.h b/include/hw/arm/nuc980.h
new file mode 100644
index 00000000..fe7f2270
--- /dev/null
+++ b/include/hw/arm/nuc980.h
@@ -0,0 +1,35 @@
+/*
+ * NUC980 SOC System emulation.
+ *
+ * Copyright (c) 2025- yanl1229@163.com.
+ * Written by yanl1229
+ *
+ * This code is licensed under the GPL.
+ */
+#ifndef NUC980_H
+#define NUC980_H
+
+#include "hw/arm/boot.h"
+#include "exec/memory.h"
+#include "target/arm/cpu.h"
+
+#define SDRAM_BASE      0x0000000
+#define SDRAM_SIZE      (64 *1024 * 1024)
+
+#define SDRAM_SIZE_32M  (0x5 << 0)
+
+#define TYPE_NUC980 "nuc980"
+#define NUC980(obj) OBJECT_CHECK(NUC980State, (obj), TYPE_NUC980)
+
+typedef struct NUC980State {
+    /*< private >*/
+    DeviceState parent_obj;
+
+    MemoryRegion   rom;
+    MemoryRegion   ram;
+    /*< public >*/
+    ARMCPU         cpu;
+
+} NUC980State;
+
+#endif
\ No newline at end of file

2、在hw/arm/下创建nuc980_soc.c,如下所示:

+号部分为新增加内容

diff --git a/hw/arm/nuc980_soc.c b/hw/arm/nuc980_soc.c
new file mode 100644
index 00000000..3de9d712
--- /dev/null
+++ b/hw/arm/nuc980_soc.c
@@ -0,0 +1,54 @@
+/*
+ * NUC980 SOC System emulation.
+ *
+ * Copyright (c) 2025- yanl1229@163.com.
+ * Written by yanl1229
+ *
+ * This code is licensed under the GPL.
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "hw/i2c/i2c.h"
+#include "hw/sysbus.h"
+#include "hw/arm/nuc980.h"
+#include "sysemu/sysemu.h"
+#include "exec/address-spaces.h"
+#include "hw/qdev-properties.h"
+#include "chardev/char.h"
+
+
+static void nuc980_init(Object *obj)
+{
+}
+
+static void nuc980_realize(DeviceState *dev, Error **errp)
+{
+}
+
+static void nuc980_class_init(ObjectClass *oc, void *data)
+{
+    DeviceClass *dc = DEVICE_CLASS(oc);
+
+    dc->realize = nuc980_realize;
+    dc->desc = "NUVOTON NUC980 SOC";
+    /*
+     * Reason: uses serial_hds in realize
+     */
+    dc->user_creatable = false;
+}
+
+static const TypeInfo nuc980_type_info = {
+    .name = TYPE_NUC980,
+    .parent = TYPE_SYS_BUS_DEVICE,
+    .instance_size = sizeof(NUC980State),
+    .instance_init = nuc980_init,
+    .class_init = nuc980_class_init,
+};
+
+static void nuc980_register_types(void)
+{
+    type_register_static(&nuc980_type_info);
+}
+
+type_init(nuc980_register_types)

3、在hw/arm/下创建nuc980_evb.c,如下所示:

+号部分为新增加内容

diff --git a/hw/arm/nuc980_evb.c b/hw/arm/nuc980_evb.c
new file mode 100644
index 00000000..f3aa6d32
--- /dev/null
+++ b/hw/arm/nuc980_evb.c
@@ -0,0 +1,63 @@
+/*
+ * NUC980 evb board System emulation.
+ *
+ * Copyright (c) 2025- yanl1229@163.com.
+ * Written by yanl1229
+ *
+ * This code is licensed under the GPL.
+ */
+#include "qemu/osdep.h"
+#include "qapi/error.h"
+#include "cpu.h"
+#include "hw/arm/nuc980.h"
+#include "hw/boards.h"
+#include "qemu/error-report.h"
+#include "exec/address-spaces.h"
+#include "sysemu/qtest.h"
+
+#define SRAM_BASE       0x3c000000
+#define SRAM_SIZE       0x4000
+
+typedef struct NUC980EVBBoard {
+    NUC980State soc;
+    MemoryRegion sdram;
+    MemoryRegion sram;
+} NUC980EVBBoard;
+
+static struct arm_boot_info nuc980_evb_binfo;
+
+static void nuc980_evb_init(MachineState *machine)
+{
+    NUC980EVBBoard *s = g_new0(NUC980EVBBoard, 1);
+
+    object_initialize_child(OBJECT(machine), "soc", &s->soc, sizeof(s->soc),
+                            TYPE_NUC980, &error_abort, NULL);
+
+    object_property_set_bool(OBJECT(&s->soc), true, "realized", &error_fatal);
+
+    machine->ram_size = SDRAM_SIZE;
+    memory_region_allocate_system_memory(&s->sdram, NULL, "nuc980_evb.sdram",
+                                         machine->ram_size);
+    memory_region_add_subregion(get_system_memory(), SDRAM_BASE, &s->sdram);
+
+
+    memory_region_allocate_system_memory(&s->sram, NULL, "nuc980_evb.sram",
+                                         SRAM_SIZE);
+    memory_region_add_subregion(get_system_memory(), SRAM_BASE, &s->sram);
+
+    nuc980_evb_binfo.ram_size = machine->ram_size;
+    nuc980_evb_binfo.loader_start = SDRAM_BASE;
+    nuc980_evb_binfo.board_id = 4577,
+    nuc980_evb_binfo.nb_cpus = 1;
+    arm_load_kernel(&s->soc.cpu, machine, &nuc980_evb_binfo);
+}
+
+static void nuc980_evb_machine_init(MachineClass *mc)
+{
+    mc->desc = "NUVOTON NUC980 EVB board (ARM926EJ-S)";
+    mc->init = nuc980_evb_init;
+    mc->block_default_type = IF_SD;
+    mc->ignore_memory_transaction_failures = true;
+}
+
+DEFINE_MACHINE("nuc980-evb", nuc980_evb_machine_init)
\ No newline at end of file

4、在default-configs/arm-softmmu.mak文件中,加入nuc980平台的编译,如下所示:

+号部分为新增加内容

diff --git a/default-configs/arm-softmmu.mak b/default-configs/arm-softmmu.mak
index 1f2e0e7f..38b3ee26 100644
--- a/default-configs/arm-softmmu.mak
+++ b/default-configs/arm-softmmu.mak
@@ -40,3 +40,4 @@ CONFIG_FSL_IMX25=yCONFIG_FSL_IMX7=yCONFIG_FSL_IMX6UL=yCONFIG_SEMIHOSTING=y
+CONFIG_NUC980_EVB=y

5、在hw/arm/Kconfig中添加nuc980的配置选项

+号部分为新增加内容

diff --git a/hw/arm/Kconfig b/hw/arm/Kconfig
index c6e77825..2a604c83 100644
--- a/hw/arm/Kconfig
+++ b/hw/arm/Kconfig
@@ -113,6 +113,13 @@ config NSERIESselect TWL92230 # energy-managementselect TUSB6010+config NUC980
+    bool
+
+config NUC980_EVB
+    bool
+    select NUC980
+

6、在hw/arm/Makefile.objs中,加入nuc980的编译,如下所示:

+号部分为新增加内容

diff --git a/hw/arm/Makefile.objs b/hw/arm/Makefile.objs
index fe749f65..8ba9d64d 100644
--- a/hw/arm/Makefile.objs
+++ b/hw/arm/Makefile.objs
@@ -10,6 +10,8 @@ obj-$(CONFIG_INTEGRATOR) += integratorcp.oobj-$(CONFIG_MAINSTONE) += mainstone.oobj-$(CONFIG_MICROBIT) += microbit.oobj-$(CONFIG_MUSICPAL) += musicpal.o
+obj-$(CONFIG_NUC980) += nuc980_soc.o
+obj-$(CONFIG_NUC980_EVB) += nuc980_evb.oobj-$(CONFIG_NETDUINO2) += netduino2.oobj-$(CONFIG_NSERIES) += nseries.oobj-$(CONFIG_SX1) += omap_sx1.o

7、编译运行

添加完后,再qemu源码路径下,执行:

./configure --target-list=arm-softmmu

make && sudo make install

8、执行 qemu-system-arm -M ? 就可以看到新增加的980平台

总结

本文主要描述了nuc980的qemu soc框架代码的添加,感兴趣的同学可以在ubuntu 20.04系统上进行下载和编译验证。

工程链接

https://gitee.com/yanl1229/qemu.git

http://www.lryc.cn/news/594312.html

相关文章:

  • LeetCode 3202.找出有效子序列的最大长度 II:取模性质(动态规划)
  • 智能制造——48页毕马威:汽车营销与研发数字化研究【附全文阅读】
  • 【图像处理基石】什么是畸变校正?
  • 2025牛客暑期多校训练营2(部分补题)
  • 【LeetCode 热题 100】124. 二叉树中的最大路径和——DFS
  • 网络安全隔离技术解析:从网闸到光闸的进化之路
  • 【机器学习深度学习】魔塔社区模型后缀全解析:Base、Chat、Instruct、Bit、Distill背后的技术密码
  • leetcode丑数II计算第n个丑数
  • Java行为型模式---解释器模式
  • 大语言模型:人像摄影的“达芬奇转世”?——从算法解析到光影重塑的智能摄影革命
  • 核电子数字多道分析(DMCA)系统中,脉冲展宽的核心目的
  • 力扣:动态规划java
  • 基于单片机的火灾报警系统设计
  • 每日算法刷题Day50:7.20:leetcode 栈8道题,用时2h30min
  • 处理Electron Builder 创建新进程错误 spawn ENOMEM
  • C++ primer知识点总结
  • D. Traffic Lights 【Codeforces Round 1038, Div. 1 + Div. 2】
  • docker制作前端镜像
  • securecrt连接服务器报错 Key exchange failed 怎么办
  • Direct3D 11学习(一)
  • 股票账户数据及其数据获取
  • Python dataclass 高阶用法与技巧
  • ADC和DMA简述
  • Java中List<int[]>()和List<int[]>[]的区别
  • k8s:离线添加集群节点
  • MySQL—表设计和聚合函数以及正则表达式
  • 【性能测试】性能压测3个阶段+高频面试题回答(详细)
  • 第三章自定义检视面板_创建自定义编辑器类_编辑器操作的撤销与恢复(本章进度3/9)
  • Android 项目中如何在执行 assemble 或 Run 前自动执行 clean 操作?
  • Milvus Dify 学习笔记