Closed vznncv closed 1 year ago
Thanks a lot for the really detailed issue! I agree that it would be nice to have the device regions represented correctly in the memory map.
The canonical solution for this is to issue the command set mem inaccessible-by-default off
to gdb. This enables access to the full 4GB address space, so the memory map is only used to determine read/write-ability and set the gdb cache policy.
I've also thought about always adding in the standard Cortex-M Peripheral range. The problem with that is it adds a very large (256 MB) range that is normally very sparsely populated with peripherals. In addition, a number of devices have peripherals in different regions, and it wouldn't cover the PPB and Vendor PPB regions. Those could of course be added, but you end up with something like 1/3 the address space covered by a Device region. 😄
Probably the best option is to examine the SVD file and extract a region that covers all defined peripherals. Or several regions, with a heuristic for when to split based on how far apart nearly-contiguous regions are. The issue here is that parsing SVD files is currently quite slow, which would negatively affect pyOCD's startup performance with a very noticeably delay. We could compromise by making it a user-configurable option that is disabled by default.
One issue with all options is they don't distinguish between S and NS attributions in v8-M devices with TrustZone-M. Not sure how to address this without proper information in the CMSIS-Pack. (This isn't covered by the SVD data.)
Another possibility that's already supported is to add memory regions with a user script.
It would be possible to have a session option to add memory regions, but doing it via the user script is probably better anyway.
Thanks for advice about user script. This approach with adding extra memory regions inside user script suites me.
Glad the user script will work for now. I'm going to continue working towards a good solution based on SVD and other CMSIS-Pack data. Thanks for raising the problem.
@flit @vznncv Thanks for the info provided. I also meet this issue in when using arm gdb, so it is very useful for me.
Besides, I wanna ask whether it is possible (or there is an easy way) to read all of the I/O traffic inside the memory regions of peripheral registers when the MCU is running by leveraging pyOCD? What I understand from above is that we could “see” this peripheral memory region when debugging the firmware, which means we should stop the firmware/binary and run the gdb command e.g. x/10x [somewhere between 0x40000000 0x60000000]
. However, what I want to achieve first in my research project is to export all of the changes inside peripheral memory regions by sequence when the firmware is continuously running. You could regard this as you not only run continue
command inside GDB, but also output the peripheral region at the same time. Is it possible to have this sort of automation by using pyOCD (sorry I am a newbie for pyOCD😅..)?
Thanks a lot if you could provide any ideas/suggestions!
Hi @DarknessChen
If I understand correctly, it sounds like you want to record every read or write to the peripheral memory region. I'm afraid it isn't directly possible on any off the shelf system. It would require a system-level bus trace capability that would record every bus transaction (read or write) to the peripheral memory region (or whatever address range you want).
There are some options, however.
Hope that helps!
Yeah, what you understand is exactly what I want to do. These advice is really helpful for me.
To be more specific, currently I want to directly record every read or write to the peripheral memory region when the real-world IoT device is running (a lot of vendors may only provide the executable so we should assume we only have the binary file without the source code). I am exploring that whether I could get those I/O traffic on-the-fly via Jtag, but as you said it may be not possible directly.
What's more, I guess another way is to run the firmware in QEMU (an emulator) and forward the I/O operations to the real hardware, which may give me a chance to observe the read/write operation. Actually this is what avatar2 could achieve, but it is another business..
Anyway, I am very glad to hear the ideas from you, if you have any other suggestions please let me know.
Thank you so much @flit !
That's right, another emulator such as QEMU is a good option. And even if it doesn't already give you the observation ability you need, you have the source code so you can add it. 😄
Are you doing this for security research? I'd like to hear a little more about the purpose of your research if you don't mind. If you want to talk more privately, just send me an email (see my github profile for the address).
Yeah, you are right. Open source tool deserves our appreciation. And it is amazing that QEMU was firstly made by a single person..
Description of defect
gdbserver of pyocd doesn't return memory regions of peripheral registers with
$qXfer:memory-map:read
command. Only flash and SRAM regions are returned.It doesn't prevent debugging, but causes that gdb cannot read peripheral registers that are defined by SVD files.
Probably
pyocd
should return memory map that contains device register regions, as some software (gdb with QtCreator) uses this information to display peripheral registers.QtCreator example
debugging with PyOCD:
The
info mem
gdb command shows the following results:client command:
note: 0x48001000 address absents in the memory regions
debugging with OpenOCD:
The
info mem
gdb command shows the following results:client command:
note: the region addresses aren't correct (some addresses are invalid), but 0x48001000 address presents in the last region, so QtCreator is able to display peripheral registers
If I add device regions with monkey patching using the following script, it will also work:
The
info mem
gdb command shows the following results:client command:
note: the 0x48001000 address presents in a memory region, so QtCreator is able to read it
Toolchain(s) (name and version) and target
Possible solution
Add common "Peripheral" regions for all targets with corresponding cortex-m cores according cortex-m documentation:
https://developer.arm.com/documentation/ddi0439/b/Programmers-Model/System-address-map