Avatar——内存配置

本文介绍如何使用Avatar²定义内存布局及配置内存范围,实现内存访问转发及外设仿真,支持QEMU和自定义外设实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

创建Avatar²需要的第二片信息是内存布局的规范。 Avatar持续对所有内存范围的跟踪并将生成的包含所有范围的内存映射送给独立的目标。

内存范围定义


增加一个内存范围很简单。假定存在一个叫’avatar’的Avatar²对象,使用下面这一行来创建0x40000000处大小为0x1000的基础内存区域就足够了:

dummy_range = avatar.add_memory_range(0x40000000, 0x1000)

内存范围是非常灵活的,在创建时允许多种多样的附加关键字,其中的一些可能仅仅被特定种类的目标使用。下面是所有独立目标创建内存范围时可能使用的关键字参数的列表。

KeywordDescription
name内存范围的可选名
permissions文本形式表示的权限。默认: ‘rwx’
file包括内存初始内容的文件路径
forwarded是否可访问要转发给特定目标所需的那个内存范围
forwarded_to如果启用了转发,则引用将处理内存访问的目标。
emulate对所给内存范围的avatar外设进行仿真

内存转发


Avatar²的一个核心特征就是执行与内存访问的分离。这允许在不同目标之间转发内存的访问。例如,一个固件镜像可以在一个模拟器中执行,而所有的内存访问可以被转发到真实物理设备。
转发规则自身在配置内存范围时就通过forwarded与forwarded_to参数设置好了。假设我们在QEMU中分析一个包含内存映射外设的物理设备。一个典型的内存范围配置如下:

mmio = avatar.add_memory_range(0x4000000, 0x10000, name='mmio',
                               permissions='rw-'
                               forwarded=True, forwarded_to=phys_device)
ram  = avatar.add_memory_range(0x2000000, 0x1000000, name='ram',
                               permissions='rw-')
rom  = avatar.add_memory_range(0x0800000, 0x1000000, name='rom',
                               file='./firmware.bin',
                               permissions='r-x')

Qemu-Target Peripheral Emulation Ranges


由于Qemu是一个完整的系统模拟器,他也可以模拟大量外设。逻辑上来说,Avatar²可以通过指定memmory range里的目标的特定关键词 ‘qemui_name’与’qemu_properties’参数来受益于此特性。
例如,一个非常普通的串口设备,可以在Qemu中仿真而不用转发I/O访问给物理设备,正如下面这个例子:

# Properties as required by qemu
serial_qproperties = {'type' : 'serial', 'value': 0, 'name':'chardev'}

serial = avatar.add_memory_range(0x40004c00, 0x100, name='usart',
                                 qemu_name='stm32l1xx-usart',
                                 qemu_properties=serial_qproperties, 
                                 permissions='rw-')

# Provide serial I/O via tcp
qemu.additional_args = ["-serial", "tcp::1234,server,nowait"]

Avatar² Peripheral Emulation Ranges


不幸的是,Qemu不支持所有现存的外设,也不支持每个使用Qemu目标的Avatar²设置。 因此,Avatar²允许用AvatarPeripheral类来指定用户定义的外设实现。
为此,需要两步:
从 AvatarPeripheral创建一个子类,它在__init__ 函数中定义定制读写处理程序。
将该类的引用传递给内存范围的模拟关键字。下面这个例子提供了一个HelloWorld外设的实现,它每次读取时返回了的字符串’Hello World’的另一部分。

from avatar2 import *

class HelloWorldPeripheral(AvatarPeripheral):

    def hw_read(self, size):         
        ret = self.hello_world[:size]
        self.hello_world = self.hello_world[size:] + self.hello_world[:size]
        return ret

    def nop_write(self, size, value):
        return True    

    def __init__(self, name, address, size, **kwargs):
        AvatarPeripheral.__init__(self, name, address, size)

        self.hello_world='Hello World'

        self.read_handler[0:size] = self.hw_read 
        self.write_handler[0:size] = self.nop_write

[...]        

hw = avatar.add_memory_range(0x40004c00, 0x100, name='hello_world',
                             emulate=HelloWorldPeripheral, permissions='rw-')        
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值