Gdb/Armulator 源代码分析
2020-09-17 23:52:19 点击:
上一篇:嵌入式Web服务器移植与测试电感生产的函数则模拟指令预取,指令译码,指令执行以及数据回写的功能.这三个文件时可以说时Armulator的核心! b. 中断 Armulator 的中断机制主要靠以下两个例程实现: 1.IntPending(): 用来检测state中的各个中断标志是否置位,从而判断是否又需要中断. 2.ARMul_Abort():当需要中断时,用来改变处理器模式,并将pc指向相应的中断向量. 在流水线函数ARMul_Emulate32()执行当中,有多处调用IntPending() 去检测中断.而Ispending() 也十分简单,它仅仅判断state中的四个变量: State->Exception : 中断使能标志. State->Nresethttp://www.ruishen.net/绕线电感生产加工Sig : reset 中断信号. State->NirqSig : irq 中断信号. State->NfiqSig : fiq 中断信号. 所以当你的虚拟外设产生中断时,你只要调用/sim/arm/armio.c/ update_int()即可: static void update_int(ARMul_State *state) { ARMword requests = state->io.intsr %26;amp; state->io.intmr; state->NfiqSig = (requests %26;amp; 0x000f) ? LOW : HIGH; state->NirqSig = (requests %26;amp; 0xfff0) ? LOW : HIGH; } b. 读写操作 无论是CPU指令还是Gdb调试时读写内存或IO空间,最后都将要落到/armvirt.c/getword(), /armvirt.c/putword()这两个函数身上. 在原始代码中这两个函数马上就进行内存数组的读写了.而补丁代码的流程如下: --%26;#224;getword()/putword() --%26;#224;mmu_read_data()/mmu_write_data() in armmmu.c /*进行mmu的地址转换和cache 查询*/ --%26;#224; real_read_data()/real_write_data() :读写ram,rom io_read_data()/io_write_data() :读写IO空间 _write_data()/fail_read_data()/fail_write_data() :非法读写,如地址错误,rom读操作等. 可以看出最后几个函数的选择是由读写地址在相应的mem_bank_t结构中的读写函数指针决定的. c. 设备同步 写这篇文章的初衷是让读者能很快进入Armulator的移植和IO扩展的实际工作中去.所以这里有必要讨论一下IO设备和CPU的同步问题.很显然我们模拟的设备不能太快,也不能太慢.快了CPU正常的指令流将被堵塞,慢了就无法反映操作系统的实时性.也就是说设备的速度和指令流要有个比例关系,即要有一定的同步. Armulator 中有个很好的接口: ARMul_ScheduleEvent (ARMul_State * state, unsigned long delay, unsigned (*what) ()) in armvirt.c 它的目的就是注册你的同步例程,并且每个时钟周期即ARMul_Emulate32()将调用ARMul_ScheduleEvent()查看是否需要同步你的设备. 也许你在ARMul_Emulate32()中还发现了/sim/arm/armio.c/io_do_cycle(),没错它是AT91的timer和 uart用来和指令流同步的函数,但我并不赞成你象这样把自己的同步例程直接放入指令执行过程中,破坏代码的结构性. a. [i]源文件描述[/i] The original files The modified codes File descriptions arminit.c arminit.c 初始代码 armemu.c armemu.c 指令流模拟 armvirt.c armvirt.c 内存读写 armsupp.c armsupp.c 辅助指令流模拟 armcopro.c armcopro.c 协处理器模拟(可忽略) armos.c armos.c 初始操作系统(可忽略) armmem.c 内存管理 armmmu.c Mmu模拟 armio.c IO设备模拟 wrapper.c wrapper.c 和Gdb通讯的例程。