裸机 mod (%) 在带有 libgcc 的 ARMv6 上挂起
当我尝试在 ARM 裸机程序中的 C 代码中使用 % 时,它需要 libgcc 的包装器。没问题,我可以链接它。当我这样做时,链接器停止抱怨,但是程序在 mod 使用时挂起(如果我观察寄存器,它们实际上开始以莫名其妙的方式循环)。用 % 注释掉该行会使程序不会以这种方式挂起,所以这肯定是问题所在。
我在 https://gist.github.com/1724746 构建了一个简单的问题示例,
我运行测试使用:
qemu-system-arm -M versatilepb -cpu arm1176 -nographic -kernel kernel.elf | xxd
然后 ^ax 退出它,并注释掉 % 行,我得到了我期望的输出字节,但是使用那里的行我没有得到任何这样的输出。
知道这是怎么回事吗?
编辑:我使用的交叉编译器是 Ubuntu 上的默认设置: https://launchpad.net/gcc-linaro
When I try to use % in C code in my ARM bare-metal program, it needs a wrapper from libgcc. No problem, I can link that in. When I do, the linker stops complaining, but then the program hangs (if I watch the registers they actually start cycling in inexplicable ways) at the mod use. Commenting out the line with the % makes the program not hang in this way, so that's definitely the problem.
I have constructed a trivial example of the problem at https://gist.github.com/1724746
I run the test using:
qemu-system-arm -M versatilepb -cpu arm1176 -nographic -kernel kernel.elf | xxd
Then ^a-x to quit it, and with the % line commented out I get the bytes I expect of output, but with the line in there I do not get any such output.
Any idea what's going on here?
Edit: the cross compiler I'm using is the default on on Ubuntu: https://launchpad.net/gcc-linaro
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
所以它用 2 加载 r0 和 r1 (好吧,它在当前任务+1上做了加一的事情
我猜他们使用 _veneer 从手臂切换到拇指,它是一个切换模式的蹦床:
这将你带到这里,实际的模数操作,这是拇指代码,拇指模式
所以它看起来做一个正常的除法,然后乘以结果并减去例如
我想知道问题是否是拇指模式,真正的拇指模式,我。 qemu 可以做拇指。
你可以尝试一个实验来找出 assemble 和 link:
其他所有内容链接起来
或任何你的工具链前缀(如果有),并将 .o 文件与 C 代码中的
,以及你传递的任何内容 。你应该得到这个值加一...尝试这个而不是取模。
另一件事是直接除法,看看除法是否有效但不能取模,也许问题是乘法指令?
嗯,我 知道。我想我看到了问题:
你不能使用 ldr 切换模式它必须是 bx 或 blx,当它尝试在 Arm 模式下执行拇指代码时,它可能会转到未定义的处理程序。
我有一些关于切换模式如何工作的示例,特别是为 qemu 编写的。现在这是一个低级示例,例如没有 printf,我确实有 uart 输出,可以通过一种方式查看 uart 上的内容。如果这是问题所在(切换到拇指模式),那么您需要检查如何编译和链接程序。如果您不使用以前的代码源(现在由导师图形使用)工具链,您可能需要指定交互工作,或者可能需要了解工具链的构建方式。假设您正在使用基于 gnu/gcc 的东西。
如果你有办法在其中放置一个未定义的处理程序,或者如果你能够观察跟踪并看到 pc 下降到地址 0x0000000 附近的某个位置,那么这可能就是正在发生的情况。如果你用我的小拇指测试东西构建,并且它使用 ldr 而不是 bx 来到达那里,那么它也不应该工作,它仍然应该崩溃......
So it loads r0 and r1 with a 2 (well it does the plus one thing on current task+1
I guess they used _veneer to switch from arm to thumb, it is a trampoline to switch modes:
That takes you here, the actual modulo operation, this is thumb code, thumb mode
So it looks to do a normal divide, then multiplies the result and subtracts for example
I wonder if the problem is thumb mode. The arm1176 definitely has thumb mode, the real one, and I qemu can do thumb.
You could try an experiment though to find out assemble and link:
or whatever your toolchain prefix is if any, and link the .o file in with everything else.
in the C code declare it as
and whatever you pass it you should get that value plus one back...try this instead of the modulo.
Another thing to try is just a straight divide, see if divide works but not modulo, maybe the problem is the multiply instruction? Who knows.
Hmmmm, I think I see the problem:
You cant switch modes with an ldr it has to be a bx or blx, it is probably going to the undefined handler when it tries to execute thumb code in arm mode.
I have some examples of how switching modes needs to work, in particular written for qemu. Now this is a low level example, no printf for example, I do have uart output with a way to see stuff on the uart. If this is the problem (switching to thumb mode) then you need to examine how you are compiling and linking your program. You might need to specify interwork or might need to understand how your toolchain was built if you are not using the formerly code sourcery (now consumed by mentor graphics) toolchain. that is assuming you are using something gnu/gcc based.
If you have a way to put an undefined handler in there or if you are able to watch the trace and see the pc drop to something near address 0x0000000 that is probably what is happening. If you build with my little thumb_test thing and it uses an ldr instead of bx to get there then that should not work either it should still crash...