日本人談qemu的內存訪問的文章

本文介绍了QEMU中两种内存访问处理方式:一种用于调试的较慢版本,另一种为正常快速版本。正常版本通过CPU状态获取物理地址并验证其有效性。若地址无效,则返回错误。此外,还详细解释了相关宏定义及函数调用流程。

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

http://ando-ruo.blogspot.hk/2012/11/qemu-cpumemoryrwdebug-normal-version.html




we have two version of memory access manipulation. latter is normal (fast) version which takes CPUState env to get physical address and check whether it is valided or not. if the address is not valid, cpu_get_phys_page_debug returns -1. 

exec.c
  4642 |        phys_addr = cpu_get_phys_page_debug(env, page);
  4643 |        /* if no physical page mapped, return an error */
  4644 |        if (phys_addr == -1)
  4645 |            return -1;

exec.c
  3853 |/* physical memory access (slow version, mainly for debug) */
  3854 |#if defined(CONFIG_USER_ONLY)
  3855 |int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
  3856 |                        uint8_t *buf, int len, int is_write)
  3857 |{
  
  4632 |/* virtual memory access for debug (includes writing to ROM) */
  4633 |int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
  4634 |                        uint8_t *buf, int len, int is_write)
  4635 |{
  4636 |    int l;
  4637 |    target_phys_addr_t phys_addr;
  4638 |    target_ulong page;
  4639 |
  4640 |    while (len > 0) {
  4641 |        page = addr & TARGET_PAGE_MASK;
  4642 |        phys_addr = cpu_get_phys_page_debug(env, page);
  4643 |        /* if no physical page mapped, return an error */
  4644 |        if (phys_addr == -1)
  4645 |            return -1;
  4646 |        l = (page + TARGET_PAGE_SIZE) - addr;
  4647 |        if (l > len)
  4648 |            l = len;
  4649 |        phys_addr += (addr & ~TARGET_PAGE_MASK);
  4650 |        if (is_write)
  4651 |            cpu_physical_memory_write_rom(phys_addr, buf, l);
  4652 |        else
  4653 |            cpu_physical_memory_rw(phys_addr, buf, l, is_write);
  4654 |        len -= l;
  4655 |        buf += l;
  4656 |        addr += l;
  4657 |    }
  4658 |    return 0;
  4659 |} 

TARGET_PAGE_MASK and TARGET_PAGE_SIZE is a macro which is used to obtain the length of buffer from taking argument of page. these two macros are generic to all CPUs, defined in cpu-all.h 

cpu-all.h
   286 |/* page related stuff */
   287 |
   288 |#define TARGET_PAGE_SIZE (1 << TARGET_PAGE_BITS)
   289 |#define TARGET_PAGE_MASK ~(TARGET_PAGE_SIZE - 1)
   290 |#define TARGET_PAGE_ALIGN(addr) (((addr) + TARGET_PAGE_SIZE - 1) & TARGET_PAGE_MASK)
   
TARGET_PAGE_BITS is hard-coded in i386 to 12. 

i386/cpu.h
   934 |/* used to debug */
   935 |#define X86_DUMP_FPU  0x0001 /* dump FPU state too */
   936 |#define X86_DUMP_CCOP 0x0002 /* dump qemu flag cache */
   937 |
   938 |#define TARGET_PAGE_BITS 12

eventually this routine invoked either cpu_physical_memory_write_rom or cpu_physical_memory_rw.
  4650 |        if (is_write)
  4651 |            cpu_physical_memory_write_rom(phys_addr, buf, l);
  4652 |        else
  4653 |            cpu_physical_memory_rw(phys_addr, buf, l, is_write);
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值