unicorn
unicorn copied to clipboard
ARM and MMU
I have a issue with the MMU in ARM emulation. It is difficult to reproduce due to complexity. I have a kernel that uses armv7 styled mmu setup. When the kernel switches to logical addresses it seems that unicorn tries to access them as physical, which obvisually is a bad idea. The kernel is at 0xffCExxxx in logical mapping.
So is the MMU emulation supposed to work and in that case at which arm revision?
Here is the mmu activation: https://gitlab.riscosopen.org/RiscOS/Sources/Kernel/-/blob/master/s/HAL The section that leads up to MMU activation starts at line 382.
I have never seen this failure on real hardware. Earlier in startup it sets up the RAM region. I set that to the start and end defined with uc_mem_map. It is very unlikely that the kernel starts mapping/accessing pages outside of the specified RAM.
RISC OS doesn't need much hardware to start the kernel , something to write log to and the cpu/mmu. On real hardware the log is written to uart during debug phase, I don't have uart , but I redirect everything with a SWI handler. Needless to say , I also tried starting without that , but it still gives me the error below.
Output: PC is the logical mapping.
Failed on uc_emu_start() with error returned: Invalid memory fetch (UC_ERR_FETCH_UNMAPPED)
Emulation done. Below is the CPU context R0 = 0x0 R1 = 0x2533001 R8 = 0xfc02d32c PC = 0xfc02d32c LR = 0x30000
I don’t think we can help too much without a reproduction script…
A example, not exactly the same as in kernel (kernel is very complex context). Anyway It treats logical address as physical. I added printf to qemu cputlb: vaddr 0x100000 paddr 0x2ef00000 size 1048576 If it would do it the other way around , it would crash. PC is the same as vaddr. Same problem as in kernel but because , what I assume, is the logical address , actually fits in phys ram it doesn't crash.
I would be very happy if someone could do a testprogram that works with this code.
OK so here is a test c code to launch the mmu code: mmuhack_c.c.txt
When I tried to enable the MMU in the past, I couldn't get any part of that to work - it only used the simple MMU mappings assigned from Unicorn's memory assignment, and didn't use the TLBs. So I gave up. If this is working now it might be interesting to use for me too.
I have checked a bit more now. It seems like translation works up to returning the phys_pc. My testprogram (the asm file) didn't work as expected. I can see now that phys_pc is -1 (0xffffffff). With the kernel I get expected phys_pc addresses. So either it goes wrong after translation OR my memory config is wrong.
When I tried to enable the MMU in the past, I couldn't get any part of that to work - it only used the simple MMU mappings assigned from Unicorn's memory assignment, and didn't use the TLBs. So I gave up. If this is working now it might be interesting to use for me too.
I tried a bit to make ARM MMU work when I developed Unicorn2. You might have another try?
mmu.s.txt
The sample doesn't work since /home/micken/mmuhack,ffd
is missing. Note even it's not missing, I can't help too much if you can't narrow down the problem to a few instructions.
mmu.s.txt
The sample doesn't work since
/home/micken/mmuhack,ffd
is missing. Note even it's not missing, I can't help too much if you can't narrow down the problem to a few instructions.
That is just a example. You put your binary there, which you assembled from the asm code. I think the asm file is the minimum for turning mmu on. You just need to replace AREA with .text and END with .end to assemble with gnu assembler. It needs to be in pure binary for it to work. If you can't assemble the file I can see if a compiled version can be uploaded somewhere.
Also ... You don't need to dig into the assembly. You will see the problem immediately, it uses the virtual address directly to the mapped ram. If it used the physical (which is a high address) it would have crashed directly.
mmu.s.txt
The sample doesn't work since
/home/micken/mmuhack,ffd
is missing. Note even it's not missing, I can't help too much if you can't narrow down the problem to a few instructions.That is just a example. You put your binary there, which you assembled from the asm code. I think the asm file is the minimum for turning mmu on. You just need to replace AREA with .text and END with .end to assemble with gnu assembler. It needs to be in pure binary for it to work. If you can't assemble the file I can see if a compiled version can be uploaded somewhere.
Also ... You don't need to dig into the assembly. You will see the problem immediately, it uses the virtual address directly to the mapped ram. If it used the physical (which is a high address) it would have crashed directly.
So what's really relevant to reproduce? If the content of the files is irrelevant, why do you need it?
So what's really relevant to reproduce? If the content of the files is irrelevant, why do you need it?
You need something to trigger the problem. Otherwise it is just my words, which is fine with me.
So what's really relevant to reproduce? If the content of the files is irrelevant, why do you need it?
You need something to trigger the problem. Otherwise it is just my words, which is fine with me.
I can't understand what "trigger the problem" means. Again, without a proper reproduction, no one can understand what your problem is. Check #1608 to see what a reproduction looks like.
OK. Can't do much more. If you want to test MMU functionality you need code for it. I have checked #1608 , and it is a very different issue. Since you don't want to test MMU translation , I close this issue.
I'm not sure how this thread managed to get to the point where it's closed. It seems like there's a misunderstanding here between @mickenx and @wtdcode.
- @wtdcode wants a reproduction case.
- @mickenx produced source, but not something that's actually able to work as it stands.
- @wtdcode asked for the actual binary
- @mickenx said (paraphase) build it yourself.
- @wtdcode said (paraphrase) that it wasn't a reproduction case (because the code wasn't present).
- @mickenx said (paraphrase) that they couldn't do much more and claimed that wtdcode didn't want to test it.
The problem here is that a reproduction case is a complete set of minimal code that will reproduce the problem. That has not been supplied - as the assembler source is not assemblable and the C code refers to the file that is not supplied.
@mickenx said that they couldn't supply the built binary that was necessary. I don't understand why they couldn't supply it, but it should be buildable if you've got the right toolchain and know how (which presumably mickenx had but somehow couldn't use to build the binary nessary).
These are soluable problems.
I can create the necessary binaries and attach them here. The important missing binary file is (in my archive) mmu
- assuming it has assembled properly. If it has not, this certainly goes back to @mickenx to supply the binary that they are reporting as a problem.
My reproduction case...
- I had to modify the
.c
file to make it reference the built local file. - I had to modify the
.s
file to make it use a MOV instruction - previously there was an ADRL in there which didn't work properly. - My filename is slightly different - I've just called the binary under test
mmu
.
How to use:
Type make test
to build the code and run the test. This uses curl to invoke the build service to build the mmu file. @mickenx may be able to confirm whether that is correct or not. Then we build the C file with GCC and run the resulting code to test it.
When I run it I get this:
charles@phonewave ~/mmu-problems> make test
rm -f src.zip
zip src.zip .robuild.yml build,feb mmu_s
adding: .robuild.yml (deflated 42%)
adding: build,feb (deflated 37%)
adding: mmu_s (deflated 62%)
# Build the sources
curl -F [email protected] -o mmu http://json.build.riscos.online/build/binary
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
100 1603 100 120 100 1483 30 378 0:00:04 0:00:03 0:00:01 408
./mmuhack_c
Emulate ARM code
read: Undefined error: 0
make: *** [test] Segmentation fault: 11
- The
read: Undefined error: 0
appears to be a bug in the test code (it calls perror when nothing has been returned). - I'm pretty sure this is a different problem to what @mickenx was reporting, as they didn't say anything about the system crashing.
I've tested this with the dev branch at SHA 64050aafb197f6c6d95b33eeb8fa160069e50d7d
. I may have built unicorn wrongly, or I may have incorrectly built this repro case - at this point I hand back to @mickenx if they want to actually have the problem looked at.
I'm not sure how this thread managed to get to the point where it's closed. It seems like there's a misunderstanding here between @mickenx and @wtdcode.
- @wtdcode wants a reproduction case.
- @mickenx produced source, but not something that's actually able to work as it stands.
- @wtdcode asked for the actual binary
- @mickenx said (paraphase) build it yourself.
- @wtdcode said (paraphrase) that it wasn't a reproduction case (because the code wasn't present).
- @mickenx said (paraphrase) that they couldn't do much more and claimed that wtdcode didn't want to test it.
The problem here is that a reproduction case is a complete set of minimal code that will reproduce the problem. That has not been supplied - as the assembler source is not assemblable and the C code refers to the file that is not supplied.
@mickenx said that they couldn't supply the built binary that was necessary. I don't understand why they couldn't supply it, but it should be buildable if you've got the right toolchain and know how (which presumably mickenx had but somehow couldn't use to build the binary nessary).
These are soluable problems.
I can create the necessary binaries and attach them here. The important missing binary file is (in my archive)
mmu
- assuming it has assembled properly. If it has not, this certainly goes back to @mickenx to supply the binary that they are reporting as a problem.My reproduction case...
- I had to modify the
.c
file to make it reference the built local file.- I had to modify the
.s
file to make it use a MOV instruction - previously there was an ADRL in there which didn't work properly.- My filename is slightly different - I've just called the binary under test
mmu
.How to use:
Type
make test
to build the code and run the test. This uses curl to invoke the build service to build the mmu file. @mickenx may be able to confirm whether that is correct or not. Then we build the C file with GCC and run the resulting code to test it.When I run it I get this:
charles@phonewave ~/mmu-problems> make test rm -f src.zip zip src.zip .robuild.yml build,feb mmu_s adding: .robuild.yml (deflated 42%) adding: build,feb (deflated 37%) adding: mmu_s (deflated 62%) # Build the sources curl -F [email protected] -o mmu http://json.build.riscos.online/build/binary % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 1603 100 120 100 1483 30 378 0:00:04 0:00:03 0:00:01 408 ./mmuhack_c Emulate ARM code read: Undefined error: 0 make: *** [test] Segmentation fault: 11
- The
read: Undefined error: 0
appears to be a bug in the test code (it calls perror when nothing has been returned).- I'm pretty sure this is a different problem to what @mickenx was reporting, as they didn't say anything about the system crashing.
I've tested this with the dev branch at SHA
64050aafb197f6c6d95b33eeb8fa160069e50d7d
. I may have built unicorn wrongly, or I may have incorrectly built this repro case - at this point I hand back to @mickenx if they want to actually have the problem looked at.
I appreciate your patience in illustrating this. If you still have problems about MMU, you might send a reproduction here, or the issue will remain closed.
I did. See the export.zip in the last message.
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.
This issue is stale because it has been open 60 days with no activity. Remove stale label or comment or this will be closed in 15 days.
I think this can actually be closed due to new tlb ctl. I will confirm it.
I have just tried it again.. still same issue. However I think the mmu in itself isn't a problem , just mappings that isn't linear translated. I am very sorry that I haven't been able to give you something better to try. It would be nice to know if it should work. That was with "main" branch. Tried with "dev" and that behaved quite different. It crashed directly on hitting the first mapped word. I configured it to have a bit more ram allocated than the mmu translated address. With "main" it goes up to the limit, in "dev" it doesn't.
The fix is only in dev, so you need to test with dev.
I just have tested the PoC (export.zip) and got UC_ERR_INSN_INVALID. Looks like this is a problem of the PoC. I'll check this.
It crashed directly on hitting the first mapped word
What do you mean with crashed? Does uc_emu_start
return an error or something else?
So after a bit testing the invalid instruction is at 0x10060
the code there (produced by the test case) is 0x116a1e3
. I can't disassemble this. When I look at the disassembly of the produced binary this not always match with the code.
I couldn't find a good tool to build the binary at my machine so any hints there would help to debug this.
After a bit more testing with a realworld kernel. I can successfully access my mapped ram! Very happy! I think this finally be closed ( for real this time). Thanks a lot for the fix!
Thanks for confirmation! Closed.