首页 > 其他分享 >QEMU添加设备相关-中断控制器、串口、pflash支持

QEMU添加设备相关-中断控制器、串口、pflash支持

时间:2024-09-17 20:49:15浏览次数:12  
标签:flash dev prop qdev 串口 pflash QEMU

QEMU添加设备相关-中断控制器、串口、pflash支持

一、添加串口支持:

真实板卡的初期调试中,串口打印可谓神器,几乎所有的SOC都会带有串口这个外设,因此我们也需要添加串口到我们的定义中。

  • 首先添加几个串口的基地址,添加多个串口的目的是为了后面在读个权限空间内跑不同的系统因此需要不同的权限的串口打印输出。

    [SIFIVE_U_UART0] = { 0x10013000, 0x1000 },

    [SIFIVE_U_UART1] = { 0x10023000, 0x1000 },

  • 在初始化函数中调用serial_mm_init创建串口实例,这个串口仿真ns16550a的定义,在后续opensbi、u-boot、kernel中有这个串口的驱动,方面移植。在sifive_u模拟板中,我们使用的是sifive_uart_create函数来实现uart实例的实现,它的仿真驱动文件位于同级的sifive_uart.c中。

serial_mm_init(system_memory,
memmap[QUARD_STAR_UART0].base, 0, qdev_get_gpio_in(DEVICE(mmio_plic),
QUARD_STAR_UART0_IRQ), 399193, serial_hd(0),
DEVICE_LITTLE_ENDIAN); serial_mm_init(system_memory,
memmap[QUARD_STAR_UART1].base, 0, qdev_get_gpio_in(DEVICE(mmio_plic),
QUARD_STAR_UART1_IRQ), 399193, serial_hd(1),
DEVICE_LITTLE_ENDIAN);

其中,qdev_get_gpio_in函数用来配置串口中断信号,必须要添加中断控制器相关的函数才能正确使用串口。

二、添加中断控制器:

外设是需要中断器的,所以说中断控制器是必不可少的。

RISCV标准的中断控制器分为两部分内核中断CLINT(Core
Local Interrupt)和外设中断控制器Platform-Level Interrupt
Controller(PLIC),CLINT在每一个smp架构下每个core都各有自己私有的中断,PLIC则是所以core共用的外部中断控制器。

[SIFIVE_U_CLINT] =    {  0x2000000,    0x10000 },

[SIFIVE_U_PLIC] =     {  0xc000000,  0x4000000 },

在初始化函数内,分别使用下面的两个函数创建相关的ip,注意要根据内核中smp个数为每个core创建对应的资源。

sifive_clint_create

sifive_plic_create

添加上述ip后,就有了中断控制器和串口,就可以进行简单的串口功能测试,现在需要固件的载体使其工作,这里使用到qemu中对于flash的仿真设备,也就是pflash。

三、添加pflash支持

pflash是并行flash,目前真实的器件已经很少见了,市面上常见的是qspi的nor flash作为低阶固件的载体,而nor flash一般都支持XIP运行,那么基本上等同于pflash了,那么为了方便我们就使用qemu提供的plash作为早期固件的载体。

依然是增加pflash的基地址,这里不是寄存器,而是pflash的数据起始地址,大小是32M,完全足够我们存放固件了。

{

[SIFIVE_U_FLASH] = {

0x20000000, 0x2000000 },

}

创建pflash器件并映射到我们的系统总线对应地址上,最后将其关联到“-drive if=pflash,bus=0,unit=0,…………”的qemu参数上,这样启动仿真时就可以加载固件文件到这片flash上,以下这些代码都不难理解,这里不在赘述

static PFlashCFI01 *sfive_u_flash_create(RISCVVirtState *s,

                                   const

char *name,

                                   const

char *alias_prop_name)

{

DeviceState *dev =

qdev_new(TYPE_PFLASH_CFI01);

qdev_prop_set_uint64(dev,

“sector-length”, QUARD_STAR_FLASH_SECTOR_SIZE);

qdev_prop_set_uint8(dev, "width",

4);

qdev_prop_set_uint8(dev,

“device-width”, 2);

qdev_prop_set_bit(dev,

“big-endian”, false);

qdev_prop_set_uint16(dev, "id0",

0x89);

qdev_prop_set_uint16(dev, "id1",

0x18);

qdev_prop_set_uint16(dev, "id2",

0x00);

qdev_prop_set_uint16(dev, "id3",

0x00);

qdev_prop_set_string(dev, "name",

name);

object_property_add_child(OBJECT(s), name,

OBJECT(dev));

object_property_add_alias(OBJECT(s),

alias_prop_name,

                          OBJECT(dev),

“drive”);

return PFLASH_CFI01(dev);

}

static
void sfive_u_flash_map(PFlashCFI01 *flash,

                        hwaddr base, hwaddr

size,

                        MemoryRegion

*sysmem)

{

DeviceState *dev = DEVICE(flash);

assert(QEMU_IS_ALIGNED(size,

QUARD_STAR_FLASH_SECTOR_SIZE));

assert(size / QUARD_STAR_FLASH_SECTOR_SIZE

<= UINT32_MAX);

qdev_prop_set_uint32(dev,

“num-blocks”, size / QUARD_STAR_FLASH_SECTOR_SIZE);

sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);

memory_region_add_subregion(sysmem, base,

                            sysbus_mmio_get_region(SYS_BUS_DEVICE(dev),

                                                   0));

}

s->flash = sfive_u_flash_create(s, “sifive_u.flash0”, “pflash0”);

pflash_cfi01_legacy_drive(s->flash,
drive_get(IF_PFLASH, 0, 0));

sifiv_u_flash_map(s->flash, virt_memmap[SIFIVE_U_FLASH].base,

                    virt_memmap[SIFIVE_U_FLASH].size, system_memory);

标签:flash,dev,prop,qdev,串口,pflash,QEMU
From: https://blog.csdn.net/swh547/article/details/140315919

相关文章

  • C#实现扫码枪串口通信
     usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.IO.Ports;usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;namespaceWind......
  • 蓝桥杯-STM32G431RBT6(串口)
    前言一、配置二、使用步骤1.串口发送代码逻辑效果展示2.串口接收单个字符代码逻辑中断回调函数3.串口接受字符串代码逻辑字符串函数中断回调函数声明代码开源前言一、配置二、使用步骤1.串口发送代码逻辑sprintf(tx_buf,"jinke\r\n"):这行代码使用......
  • QEMU on Linux hosts(By frp)
    Invocation—QEMUdocumentationHosts/Linux-QEMU关键字:QEMU、Tips:由于是使用反向代理frp 内网穿透在无图形界面的Ubuntu24.04LTS主机,通过ssh安装QEMU,频繁出现掉线问题,所以使用Screenapt-getinstallscreenroot@atc:~#screen-vScreenversion4.09.01(GNU)20-Au......
  • printk 串口打印级别
    打印级别格式:printk(KERN_EMERG"1111111KERN_EMERG\n");printk("<0>1111111KERN_EMERG\n");*******************************************************************************1.基本解决方法(如果这种方法不行,结尾处说明另一种小众原因)用到的命令1>cat/proc/sy......
  • Verilog - 串口命令封装(多个命令封装为1个命令)代码
    串口命令封装,代码实现思想:1.对接收的串口数据(8bit)进行移位2.识别封装命令,输出配置使能信号3.计数(计数器cnt),使计数时间大于一个命令的配置时间,当达到计数值cnt_x时,输出有效信号并对计数器清零4.输出flag信号:开始配置时,将flag信号拉高,配置完成后拉低5.计数(计数器cnt_ca......
  • Ubuntu 18.04搭建RISCV和QEMU环境
    Ubuntu18.04搭建RISCV和QEMU环境  原文:https://blog.csdn.net/Eng_ingLi/article/details/135285200 前言因为公司项目代码需要在RISCV环境下测试,因为没有硬件实体,所以在Ubuntu18.04上搭建了riscv-gnu-toolchain+QEMU模拟器环境。安装riscv-gnu-toolchainriscv......
  • 使用 csharp获取串口 的 全称
    使用的命名控件usingSystem.Management;代码点击查看代码///<summary>///获取串口的全称///</summary>///<returns></returns>publicstaticList<string>GetCompleteNameOfSerialPort(){List<string>serial_port_result=newList&......
  • 串口通信-stm32
    【实验目的】深入理解串口协议和串口程序编制方法;【实验要求】1.学会编写串口通信程序2.能够使用按键控制通信消息的发送2.学会在两块开发板之间通信的方式【实验内容】1.将开发板和PC机串口连接,并通过串口线和另一块开发板连接;2.在发送开发板上按下发送键,则向目标开发......
  • Xen on qemu for arm64: 由qemu-system-aarch64导致的kernel-panic
    背景描述:    我在A平台利用qemu实现了xen中dom0的运行,将其移植到B平台运行,dom0的复现遭遇了kernel-panic,在虚拟设备的添加时异常。一、将运行dom0所需要的可执行文件拷贝到同一个目录        可执行文件的来源参考XenOnQemuforarm64_qemuxen-CSDN博客......
  • lesson05-设计主函数实现串口的初始化和运行
    根据boot.S里的内容,最后会跳转到kernel_main里,在这里会进行设置gpio引脚配置串口的初始化,然后循环运行,不断打印接受到的内容。//主函数voidkernel_main(){//串口初始化uart_init();//串口发送helloworlduart_send_string("Helloword!\n")//循环发......