新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 深入分析S3C2440啟動代碼中大小端問題

        深入分析S3C2440啟動代碼中大小端問題

        作者: 時間:2016-11-22 來源:網絡 收藏

        一、ADS1.2中關于大小端的設置以及對編譯后的代碼的影響

        下面是一段代碼在線段模式下編譯,生成的二進制文件的內容
        大端模式下編譯,生成二進制文件的內容
        根據上面的內容可以看出:它們的字節序是相反的,也就是說,ADS1.2中對大小端的設置會影響最終生成的二進制文件的字節序。

        二、S3C2440啟動代碼中與大小管相關的代碼

        Option.inc中相關代碼

        本文引用地址:http://www.104case.com/article/201611/319967.htm
        [plain]view plaincopy
        print?
        1. GBLLENDIAN_CHANGE
        2. NDIAN_CHANGESETL{FALSE}
        3. GBLAENTRY_BUS_WIDTH
        4. NTRY_BUS_WIDTHSETA16


        2440init.s中相關代碼
        [plain]view plaincopy
        print?
        1. AREAInit,CODE,READONLY
        2. ENTRY
        3. EXPORT__ENTRY
        4. __ENTRY
        5. ResetEntry
        6. ;1)Thecode,whichconvertstoBig-endian,shouldbeinlittleendiancode.
        7. ;2)ThefollowinglittleendiancodewillbecompiledinBig-Endianmode.
        8. ;Thecodebyteordershouldbechangedasthememorybuswidth.
        9. ;3)Thepseudoinstruction,DCDcannotbeusedherebecausethelinkergenerateserror.
        10. ASSERT:DEF:ENDIAN_CHANGE
        11. [ENDIAN_CHANGE
        12. ASSERT:DEF:ENTRY_BUS_WIDTH
        13. [ENTRY_BUS_WIDTH=32
        14. bChangeBigEndian;DCD0xea000007
        15. ]
        16. [ENTRY_BUS_WIDTH=16
        17. andeqr14,r7,r0,lsl#20;DCD0x0007ea00
        18. ]
        19. [ENTRY_BUS_WIDTH=8
        20. streqr0,[r0,-r10,ror#1];DCD0x070000ea
        21. ]
        22. |
        23. bResetHandler
        24. ]
        25. bHandlerUndef;handlerforUndefinedmode
        26. bHandlerSWI;handlerforSWIinterrupt
        27. bHandlerPabort;handlerforPAbort
        28. bHandlerDabort;handlerforDAbort
        29. b.;reserved
        30. bHandlerIRQ;handlerforIRQinterrupt
        31. bHandlerFIQ;handlerforFIQinterrupt
        32. ;@0x20
        33. bEnterPWDN;Mustbe@0x20.
        34. ChangeBigEndian
        35. ;@0x24
        36. [ENTRY_BUS_WIDTH=32
        37. DCD0xee110f10;0xee110f10=>mrcp15,0,r0,c1,c0,0
        38. DCD0xe3800080;0xe3800080=>orrr0,r0,#0x80;//Big-endian
        39. DCD0xee010f10;0xee010f10=>mcrp15,0,r0,c1,c0,0
        40. ]
        41. [ENTRY_BUS_WIDTH=16
        42. DCD0x0f10ee11
        43. DCD0x0080e380
        44. DCD0x0f10ee01
        45. ]
        46. [ENTRY_BUS_WIDTH=8
        47. DCD0x100f11ee
        48. DCD0x800080e3
        49. DCD0x100f01ee
        50. ]
        51. DCD0xffffffff;swinv0xffffffissimilarwithNOPandrunwellinbothendianmode.
        52. DCD0xffffffff
        53. DCD0xffffffff
        54. DCD0xffffffff
        55. DCD0xffffffff
        56. bResetHandler
        我們可以看到,在Option.inc將ENDIAN_CHANGE設置FALSE,程序將直接運行b ResetHandler,S3C2440默認是處于小端模式,ADS1.2中的設置默認也是小段模式,一切風平浪靜。
        現在,我們在ADS1.2中設為打斷模式,并把ENDIAN_CHANGE設置FALSE設為TURE,現在問題就來了,請看下面的分析。
        在編譯程序時,根據ENTRY_BUS_WIDTH宏會將下面三條指令的之一放在0地址處
        b ChangeBigEndian ;DCD 0xea000007
        andeq r14,r7,r0,lsl #20 ;DCD 0x0007ea00
        streq r0,[r0,-r10,ror #1] ;DCD 0x070000ea
        其實這三條指令的功能都是一樣,只是根據數據帶寬調整了字節序,都是跳轉到0x24處的ChangeBigEndian執行,ChangeBigEndian的作用就是通過協處理CP15中的寄存器C1來改變S3C2440的大小端模式。
        先來看一下這三條指令。因為我們已經在ADS中設置為大端模式,所以這些指令是以大端模式進行編譯的,而S3C2440此時還是小端模式,S3C2440怎么能執行大端模式下的指令呢,比如b ChangeBigEndian ;DCD 0xea000007???
        原因如下:
        如果一個基于 ARM 芯片將存儲器系統配置為其中一種存儲器格式(如小端) ,而實際連接的存儲器系統配置為相反的格式(如大端) ,那么只有以字為單位的指令取指、數據裝載和數據保存能夠可靠實現。其它的存儲器訪問將出現不可預期的結果。也就就是說在32位模式下,大小端模式對指令取指、數據裝載和數據保存沒有影響。(注意:如果實際的存儲器格式與芯片的存儲器格式不符時,只有以字為單位的數據存取才正確,否則將出現不可預期的結果。)
        b ChangeBigEndian在大端模式下機器碼是0xea000007,這是32位模式下,其四個字節從低到高分別是:07 00 00 ea。那沒b ChangeBigEndian這條指令在8位模式下,要被小端模式的S3C2440執行,就要人為的修改為0x070000ea。在存儲器中存儲的順序:從低地址到高地址分別是 07 00 00 ea,S3C2440按小端模式取指令時,取得是0xea000007。
        b ChangeBigEndian這條指令在16位模式下,要被小端模式的S3C2440執行,就要人為的修改為0x0007ea00。在存儲器中存儲的順序:從低地址到高地址分別是 0007 ea00,S3C2440按小端模式取指令時,取得是0xea000007。
        后面修改協處理CP15中的寄存器C1的代碼時類似的。


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 星子县| 榆社县| 西平县| 津南区| 富宁县| 屏山县| 开原市| 沽源县| 海南省| 家居| 依兰县| 庐江县| 惠来县| 南溪县| 会东县| 驻马店市| 九龙坡区| 荥阳市| 鹿邑县| 巴林左旗| 明光市| 克什克腾旗| 新泰市| 武威市| 阳山县| 大化| 莲花县| 张北县| 崇义县| 育儿| 汝阳县| 习水县| 裕民县| 天长市| 纳雍县| 富宁县| 三穗县| 榕江县| 洛浦县| 沧源| 达拉特旗|