http://dy.163.com/v2/article/detail/F6UCU4DP0511CJ6O.htmlhtml
飛利浦TriMedia CPU
git
TriMedia微處理器最初由飛利浦製造,目前名爲NXP(Nexperia)半導體(高通公司於2016年宣佈收購NXP)。它是VLIW(超長指令字)處理器家族,這意味着它們可使用哈佛架構同時並行執行給定數量的指令,其主要用途是用於DSP(數字)信號處理)。程序員
一開始,TriMedia處理器的名稱是「PNX」,後來改成「TM」。github
TriMedia微處理器運行一個實時操做系統,稱爲pSOS。此外,也有人嘗試將2.6 Linux內核分支移植到TriMediacpu上運行。web
爲了編寫TriMedia微處理器的代碼,須要用官方的SDK,它包含了你須要的全部東西(庫、編譯器、調試器、模擬器等),可是除了那些銷售使用TriMedia處理器的大公司(例如D-Link和2Wire)以外,它是不可用的。可是,有一些兼容TriMedia的SDK,如Streaming Networks提供的IADK(集成應用程序開發工具包),專門爲PNX1300系列設計。編程
另外,若是你想使用該處理器,還有一些配備TriMedia CPU的開發板,例如Streaming Networks提供的TriREF開發板。可是,這種包括IADK的板並不便宜。實際上,我聯繫了Streaming Network並向他們要了TriREF板,大約爲5000美圓,太貴了,我買不起。架構
在撰寫本文時(2019年1月),我又有了其它選擇,但其中不包括SDK。ssh
在本文中,我將主要使用TriMedia PNX1300EH微處理器。wordpress
逆向TriMedia CPU的信息源
工具
對TriMedia處理器進行逆向工程並非一件容易的事,主要是因爲缺乏相關文檔和工具。互聯網上關於TriMedia體系結構的文檔不多,指令集文檔不多,而且現有工具私有且昂貴。不管如何,咱們可使用一些舊的信息資源來開始咱們的逆向工做。
開始研究的第一條信息來源是數據表,本文檔包含有關處理器全部體系結構的信息。咱們能夠了解芯片中不一樣組件的主要思想,它們之間的相互做用方式,控制器使用的特定指令集等。若是你要從右邊的引腳入手,則必須閱讀數據表。
儘管專門針對JTAG研究,但另外一個很好的信息來源是http://hackingbtbusinesshub.wordpress.com。即便該博客再也不可用,仍然有一些副本存儲在web.archive.org中。這個傢伙在反轉基於TriMedia CPU的2Wire路由器方面作得很是出色,並建立了一些出色的工具,例如2wiglet(基於urjtag,它是用於2Wire路由器和tm32dis的JTAG wiggler工具),這是TM32系列的TriMedia反彙編程序。
如今咱們談論JTAG,在上一節中,我提到了Monumental Data System提供的用於TriMedia CPU的JTAG PCI調試器。飛利浦還提供了一個官方的JTAG調試器,可是它比較特殊。TriMedia JTAG工具僅設計用於專有的JTAG電纜。「電纜」其實是一種複雜的編程設備。它是一個經過NetChip NET-2282外圍控制器鏈接到PC的USB設備。編程器從其本身的EEPROM啓動,並由帶有NOR閃存和DRAM內存的Philips PNX1502 CPU驅動。
顯然, IDA工具必不可少。IDA從4.x版本(特別是4.21版本)開始就支持TriMedia CPU。
New features in version 4.21 (19/04/2002)
Processors
Trimedia (upon special request only)
[..]
如上所述,處理器模塊僅在有特殊要求時纔可用。我從HexRays請求了處理器模塊,但他們再也不提供。
最後,在這項研究期間,我收集了有關TriMedia(文檔、工具)的各類信息,並將其存儲在github中。
接下來,我將討論TriMedia架構自己。
TriMedia PNX1300EH CPU
在本文中,我將不對CPU上的每一個組件進行很是詳細的描述,由於這沒有任何意義。該處理器的最高速度爲143MHz,可在2.5V電壓下工做。它的內核稱爲DSPCPU,是通用的32位CPU,它還實現了某些媒體標準,例如MPEG-1和MPEG-2。如下是PNX1300的全部組件的框圖:
咱們已經看到DSPCPU使用了VLIW指令集,這使得每一個時鐘週期能夠同時執行5個操做。DSPCPU具備不一樣的「issue插槽」,總共五個,每一個「issue插槽」具備不一樣數量的「功能單元」,總共27個,每一個指令中包含的每一個操做均可以將其做爲目標。因爲每一個VLIW指令編碼5個獨立的操做,相對於其餘指令,理解每一個指令有點困難,跟蹤控制流並不容易。
關於PNX1300的寄存器模型,它有128個32位通用寄存器,從r0到r127。在這128個寄存器中,有兩個具備固定值。它們是分別包含整數值0和1的r0和r1,且主要用做布爾值TRUE或FALSE,不容許程序員寫入r0或r1。
還有一個用於程序計數器(PC)的寄存器和四個特殊寄存器:PCSW(程序控制和狀態字),DPC(目標程序計數器),SPC(源程序計數器)和CCCOUNT(自復位以來的時鐘週期計數)。PCSW一般用做包含標誌的寄存器,例如32位和64位Intel平臺中的EFLAGS和RFLAGS。重要的是要說明PNX1300 CPU具備可切換的bytesex(單位)。經過將BSX標誌(位大小)寫入PCSW寄存器,由軟件完成bytesex切換。這意味着能夠在同一執行中找到小端字節排序和大端字節排序。例如,加載和存儲操做會觀察PCSW寄存器中的BSX標誌,以瞭解該操做應按小端仍是大端順序進行。若是BSX標誌等於1,則使用小端字節排序。若是BSX標誌爲0,則使用大端字節排序。
DPC和SPC是用於異常處理的寄存器, CCOUNT寄存器是PNX1300中惟一的64位寄存器,用於循環計數,它計算自上次重置事件以來的時鐘週期。
關於內存和MMIO,如數據表中所述,PNX1300在32位地址空間中定義了四個孔:內存孔,DRAM,MMIO和PCI孔。DRAM從DRAM_BASE中指定的地址映射到DRAM_LIMIT寄存器中的地址。最大大小爲64 MB。MMIO位於MMIO_BASE處,固定大小爲2 MB。DRAM和MMIO的值是在BIOS引導時設置的。內存孔從地址0映射到0xFF,所以爲256個字節。最後,全部未標記爲DRAM,MMIO或內存孔的空間都應考慮在PCI孔中。如下是PNX1300中的內存映射圖:
如今,讓咱們進入困難的部分。由於,我將嘗試向你解釋TriMedia ASM
TriMedia ASM及其指令集
我不瞭解其餘VLIW處理器,由於這是我處理過的第一個處理器。Trimedia處理器是具備多個功能單元的VLIW處理器,你能夠在一個指令字中最多進行5個操做。我能夠證實,TriMedia ASM的功能很是的優秀。舉個例子,下面是來自TM32處理器的一些程序集:
(* instruction 0 : 224 bits (28 bytes) long *)
(* offset : 0x00000000 *)
(* bytes : 00 18 4c 0c c0 80 c0 81 c3 80 c0 b5 c0 81 02 00 12 00 8c 00 20 90 40 40 40 20 a0 d0 *)
(* format bytes : 0x0018 & 0xff03 = 0x0000, format in little endian bit order: 00 00 00 00 00 *)
IF r1 uimm(0x61a618) -> r0, (* 42 bits: 0 02 30 c0 0c 4c *)
IF r7 ijmpi(0x90030001), (* 42 bits: 2 40 81 81 c0 80 *)
IF r2 fadd r67 r1 -> r32, (* 42 bits: 1 01 02 c0 80 c3 *)
IF r10 bitand r64 r3 -> r16, (* 42 bits: 0 81 02 02 81 c0 *)
IF r1 uimm(0xd0060024) -> r0; (* 42 bits: 3 42 83 00 12 00 *)
與其餘體系結構中的許多其餘彙編語言同樣,TriMedia ASM包含有關數學運算(整數和浮點),邏輯,加載和存儲數據,分支等的指令;特殊之處在於,全部操做最多能夠並行執行五個。每一個操做都有其本身的功能單元,該功能單元基本上是CPU中用於分配某些操做組的預約義插槽。
數學整數操做進入「alu」單元,控制流操做進入「branch」單元,直接操做進入「const」單元,依此類推;根據數據表,PNX1300最多具備27個功能單元。
使TriMedia ASM難以理解的是其編碼方案,指令被壓縮在一個可變大小的流中,解壓單元負責在指令被髮送到CPU以前展開它們。
讓咱們以第一條指令爲例:
IF r1 uimm(0x61a618) -> r0
你能夠看到一個「IF」語句,位於真正的助記符以前,後面是「r1」寄存器字符串。全部這些意味着這是一個「受保護的」指令。TriMedia CPU中的全部操做均可以受到保護(可選),受保護的操做有條件地執行,具體取決於「保護」寄存器的值。在此特定示例中,這意味着「 r1」(保護寄存器)寄存器控制uimm操做的執行(uimm操做將無符號的32位操做碼修飾符n寫入rdest)。若是r1寄存器爲「真」,則將值0x61a618移入r0寄存器。可是,在這種狀況下,反彙編程序的輸出會出現不一致的狀況。根據官方文檔,iimm和uimm指令不受保護,所以,在這種狀況下,咱們能夠假定不管r1寄存器的值是多少,值0x61a618都將存儲到r0寄存器中。
另外一個要強調的重要事項是尋址模式,下表中總結了這些尋址模式:
在這些尋址模式中,R[i]表示一個通用寄存器。所應用的比例因子(1/2/4)等於加載或存儲的項目的大小,即,對於字節操做爲1,對於16位操做爲2,對於32位操做爲4。有效的「 i」, 「 j」和「 k」值的範圍在體系結構的實現之間可能有所不一樣。「 i」和「k「參數的值能夠介於0到127之間。「 j」參數的值能夠介於-64和63之間。例如, ‘ld32d(–8) r3’從地址 (r3 – 8))加載一個32位值。
如今,如何對全部這些操做進行編碼?
TriMedia ASM壓縮方案
爲了理解TriMedia指令是如何編碼的,我查看了我能找到的惟一文檔,即「用於產生VLIW指令壓縮的美國專利5787302軟件」文檔。另外,我使用了前面提到的TM32反彙編程序工具,以某種方式驗證了我在文檔中所讀的內容。更好的解決方案是得到SDK或開發板,以編譯一些代碼並使用官方工具反彙編/調試它。
注意事項
咱們須要學習的第一件事是區分「指令」和「操做」,TriMedia CPU中的每一個指令最多能夠有5種不一樣的操做。這些操做中的每個均可以屬於27個不一樣的功能單元中的任何一個,並被分配到相應的issue插槽中。TriMedia 32位CPU具備5個issue插槽。每一個issue插槽表明CPU中處理每一個操做的位置,並附加了適當功能單元類型的實例。
值得注意的是TriMedia CPU並非惟一實現VLIW體系結構的CPU。還有其餘諸如SHARC或C6000處理器之類的(或少於)5個issue插槽。
每一個指令的長度將根據每一個操做的大小而變化,TriMedia操做大小能夠爲2六、34或42位。正如咱們已經看到的,這些操做能夠是保護的,也能夠是不保護的,能夠是零值的,一元的,也能夠是二進制的(0,1或2個操做數),能夠是無結果的,還能夠包含直接參數(7位或32位)。唯一未壓縮的操做是分支。每一個操做都伴隨着一些稱爲「格式位」的位,這些位包含有關操做的附加信息。指令的格式位位於先前指令中。因爲TriMedia CPU每條指令有5個操做,這意味着咱們總共有10個格式位(5個操做中的每個有2個),所以,一個字節加上2個字節被使用。
格式位對於理解指令的編碼很是重要,咱們已經說過,在Trimedia CPU中,咱們有5個issue插槽,這給了咱們10個格式位。格式位將以矩陣表示法稱爲Format [j],其中j是位數。位Format [2i]和Format [2i + 1]給出有關issue插槽i的格式信息,其中0 <= i <= N。下表(表1)中解釋了格式位的含義:
能夠看出,操做對應於從左到右排列的issue插槽。
例如,若是Format = {1,1,1,1,1,0,1,0,1,0},則該指令包含三個34位操做({1,0},{1,0},{ 1,0})。
如上所述,操做能夠具備2六、34和42位。26位操做被分解爲2位部分,並與格式位和24位部分一塊兒存儲。34位操做分爲2位部分,24位部分和1個字節擴展名。42位操做分爲2位部分,24位部分和兩個字節擴展名。這意味着使用五個42位操做加上10個格式位,咱們能夠擁有的最大指令大小爲28個字節(224位)。若是進行數學運算,你將看到42位* 5個操做= 210位-> + 10個格式位= 220位= 27.5個字節,可是因爲指令是按字節對齊的,所以咱們必須添加四個填充位才能總共有28個字節。
此外,在指令的末尾有一個字節對齊的可選8位或16位操做擴展組,每一個擴展都是字節對齊的。若是須要的話,這些擴展位用於將操做的大小從基本的26位擴展到34位或42位。
以上咱們介紹了TriMedia架構,下文咱們會接着介紹有關反彙編TriMedia代碼的一些問題。
本文參考自:https://blog.quarkslab.com/reverse-engineering-a-philips-trimedia-cpu-based-ip-camera-part-2.html#id8