星期三, 6月 21, 2006

ARMLINK : ~PRES8 and REQ8 Error

uLionel 買的是arm9的devkit。
用的是新版ADS - RealView。

先拿一個簡單的sample project:
init.S : 只有initialize stack,就跳到Main label.
main.c : initialize peripheral io,讓 pio pin hi/low --

make時出現
Error: L6238E: init..o(.text) contains invalid call from '~PRES8' function to 'REQ8' function Main.
看起來毫無頭緒的Error。init.S哪一個symbol有被Main reference到?

移除main.c,單獨make init.S -- OK (把 "b main"拿掉)。
移除init.S,單獨make Main.C -- semi OK - warnning = no entry point specified.

但是一起build就有問題。把main()剔除成空殼也一樣。
沒辦法,只好問google.. 真的有答案
http://mail.millennium.berkeley.edu/pipermail/tinyos-help/2004-October/006298.html

follow 這個thread的link 到 : http://www.arm.com/support/faqdev/1242.html

原來再ARM 5TE以後的architecture有LDRD,STRD這兩個一次load 8 bytes的指令,
RealView會用這兩個 instruction 來存取stack,所以要求 function的interface (B, BL)要保持stack align 8 byte。在linker上,這對應三個predefined symbols:
PRE8 : 這個object file預留8 byte aligned stack.
~PRE8 : 這個 object 的stack不是8 bytes aligned.
REQ8 : 這個object的stack 必須是8 bytes aligned
所以就可以看出前面的Error message"翻譯過後就是 init.o 包含一個需要不是8 byte align的call,到一個需要 8 bytes aligned的 object : main。

解決方法:

就強制stack對齊就好啦:
i) 所有STMFD command,注意要store 偶數個data。
ii)在assembly file 的head宣告: PRESERVE8。

如果很倒楣,沒有source code (例如是.a 的library 或是close source 的.o)。
那就... 用 "fromelf -C" disassemble .o 檔(...這是ARM website說的喔...),查stack operation的地方是不是都是8 bytes aligned.

如果是的話,用"--diag_suppress 6238"告訴 linker 不要作 stack aligh check 就可以消除這個Error。

也就是說,用手動取代自動。
WEB SITE還說舊版的ADS/SDT都沒有PREVS8 這個attribe,所以都會有Error。但是比較後面版本的ADS是以Align 8 的方式compile的,所以還是有機會。但是assembly code就沒有了。

所以說 opensource 還是很重要的事呀,否則你就要disassemble .o 出來check了......

沒有留言:

網誌存檔