Intel TE28F320C3BA100 Flash讀寫函數FAQ

Q1 #define barrier() __asm__ __volatile__("": : :"memory")宏的作用?

A:這個宏定義於blob-2.0.5-pre2/include/blob/util.h中,在blob-2.0.5-pre2/src/blob/intel16.c中多次用到。經過Oldlinux.org論壇中的高人指點,我在ULK2的5.3.2節中找到了對這個宏的解釋:The macro, however, forbids the complier to reshuffle the instructions.即該宏禁止了編譯器對(彙編語言)指令的重新排列。當使用帶優化功能的編譯器時,你不能指望指令會嚴格按照它們在源程序中出現的順序來執行。例如,編譯器可能會爲了優化CPU中寄存器的使用而重新排列(reorder)彙編語言指令,這將大大提高程序的運行速度。

然而當面對同步問題時,則需要避免指令的重新排序。此時需要使用存儲器屏障原語(memory barrier premitive)來保證位於該原語之前的指令在位於該原語之後的指令開始執行之前執行完畢。

而對28F320C3 Flash存儲器的正確訪問是依賴於發送到CUI的命令代碼序列的先後次序(時序)正確,因此需要使用存儲器屏障原語,而barrier()宏正是存儲器屏障原語的具體實現。

彙編語言指令真的會被有優化功能的編譯器重新排序嗎?不妨來測試一下。

以flash.c文件中的讀取28F320C3 Flash的Device Identification Code的函數read_device_id爲例

u16 read_device_id(u32 *blockstart)
{
 u16 *p = (u16 *)blockstart;
 u16 result;
 
 *p = READ_CONFIG;
 barrier();
 result = *(p + 1);
 barrier();

 *blockstart = READ_ARRAY;
 barrier();

 return result;
}

測試平臺爲Red Hat Linux 9,編譯器選用arm-elf-gcc,編譯時使用命令:

arm-elf-gcc -O2 -c -o flash.o flash.c

然後反彙編生成的目標文件flash.o,使用命令:

arm-elf-objdump -d flash.o > barrier.txt

接下來註釋掉read_device_id中的所有barrier()宏調用,重新編譯flash.c:

arm-elf-gcc -O2 -c -o flash.o flash.c

然後反彙編生成的目標文件flash.o,使用命令:

arm-elf-objdump -d flash.o > nobarrier.txt

最後使用diff命令來比較兩次反彙編輸出的結果:

diff -bB nobarrier.txt barrier.txt > diff.txt

這樣diff.txt文件中得到了不使用barrier()宏時和使用時,編譯器所產生的彙編語言指令的不同:

9,16c9,16
<    8: e3a03090  mov r3, #144 ; 0x90
<    c: e1c030b0  strh r3, [r0]
<   10: e24cb004  sub r11, r12, #4 ; 0x4
<   14: e1d030f2  ldrsh r3, [r0, #2]
<   18: e3a020ff  mov r2, #255 ; 0xff
<   1c: e5802000  str r2, [r0]
<   20: e1a03803  mov r3, r3, lsl #16
<   24: e1a00823  mov r0, r3, lsr #16

---
>    8: e24cb004  sub r11, r12, #4 ; 0x4
>    c: e3a03090  mov r3, #144 ; 0x90
>   10: e1c030b0  strh r3, [r0]
>   14: e1d020f2  ldrsh r2, [r0, #2]
>   18: e3a030ff  mov r3, #255 ; 0xff
>   1c: e5803000  str r3, [r0]
>   20: e1a02802  mov r2, r2, lsl #16
>   24: e1a00822  mov r0, r2, lsr #16

紅色的彙編指令是不使用barrier()宏時由arm-elf-gcc所產生的彙編語言指令,對比之下可以發現編譯器確實有重新排序彙編語言指令的現象。

參考資料:

Intel Advanced+ Boot Block Flash Memory(C3) datasheet

blob-2.0.5-pre2/src/blob/intel16.c source code

Understanding the Linux Kernel 2rd Edition

ARM System Developer's Guide:Designing and Optimizing System Software

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章