GDB Remote Serial Protocol —— RSP协议解析
簡(jiǎn)介
GDB Remote Serial Protocol——GDB的標(biāo)準(zhǔn)遠(yuǎn)程通信協(xié)議。
當(dāng)你已經(jīng)熟悉你的處理器是如何處理斷點(diǎn)和其他異常時(shí),再了解一點(diǎn)基本的遠(yuǎn)程穿行通信協(xié)議的知識(shí),你就可以在你的嵌入式平臺(tái)上實(shí)現(xiàn)與主機(jī)GDB的通信。(即遠(yuǎn)程調(diào)試)
協(xié)議定義
GDB RemoteSerial Protocol(RSP)是一種簡(jiǎn)單的,通過(guò)串口線、網(wǎng)絡(luò)等至少支持半雙工通信的媒介進(jìn)行ASCII消息傳輸?shù)膮f(xié)議。
RSP包以$符號(hào)作為數(shù)據(jù)包的開(kāi)始,后跟一個(gè)或多個(gè)用于組成要發(fā)送的消息的ASCII字節(jié),并以#作為數(shù)據(jù)包的結(jié)束。再#后,還有兩個(gè)16進(jìn)制的ASCII字符作為要發(fā)送的消息的校驗(yàn)和。一個(gè)完整的RSP協(xié)議數(shù)據(jù)包如下:
$m4015bc,2#5a
消息的接收方會(huì)立即返回‘+’表示正確接收數(shù)據(jù),或‘-’表示沒(méi)有正確接收數(shù)據(jù)。當(dāng)返回‘-’時(shí),GDB會(huì)將錯(cuò)誤碼返回給用戶,并無(wú)條件掛起GDB進(jìn)程。
目標(biāo)機(jī)按接收到的指令次序,依次將信息輸出在GDB的console中。除非GDB進(jìn)程中有其他的命令正在執(zhí)行,否則來(lái)自目標(biāo)機(jī)的信息將會(huì)在任意時(shí)刻輸出在console中。
RSP必須實(shí)現(xiàn)的命令
根據(jù)功能劃分,可將GDB發(fā)送來(lái)的信息,分成三種命令:寄存器相關(guān)(register-)、內(nèi)存相關(guān)(memory-based)和程序控制命令。
寄存器相關(guān)
主要是對(duì)寄存器進(jìn)行讀、寫(xiě)操作。
讀寄存器組:(“g”)
eg:$g#67
當(dāng)GDB想獲取當(dāng)前目標(biāo)機(jī)的寄存器信息時(shí),就會(huì)像目標(biāo)機(jī)發(fā)送(“g”)命令,目標(biāo)機(jī)會(huì)返回如下信息:
+$123456789abcdef0…#xx
(Register 0 的值為0x12345678,1 的值為0xabcdef0….等等)
目標(biāo)機(jī)根據(jù)平臺(tái)的大小端返回相應(yīng)的字節(jié)流,關(guān)于大小端的定義,可以在目標(biāo)平臺(tái)的gdb宏文件中找到,eg:gdb/config/<arch>tm-<arch>.h (不同版本可能不一樣,我就沒(méi)找到)
寫(xiě)寄存器組:(“G”)
eg:$G123456789abcdef0…#xx
(設(shè)置register0 的值為0x12345678,1 為 0xabcdef0…等等)
使用這個(gè)命令,GDB會(huì)在程序恢復(fù)運(yùn)行前,按照平臺(tái)的字節(jié)序?qū)?shù)據(jù)存儲(chǔ)在相應(yīng)的寄存器中。同時(shí)目標(biāo)平臺(tái)也會(huì)回應(yīng)給GDB反饋信息,如成功返回+$OK#9a。
寫(xiě)寄存器:(“P”)
eg:$p10=0040149c#b3
(設(shè)置16號(hào)寄存器的值為0x40149c)
當(dāng)GDB僅僅想設(shè)置一個(gè)或二個(gè)寄存器時(shí),GDB會(huì)發(fā)送這條指令(代替(“G”)命令)給目標(biāo)機(jī)。寄存器的號(hào)與讀寫(xiě)寄存器組的號(hào)是一樣的。同時(shí),若成功,目標(biāo)機(jī)會(huì)返回+$OK#9a。
內(nèi)存相關(guān)
讀內(nèi)存:(“m”)
eg: $4015bc,2#5a
(從0x4015bc這個(gè)地址開(kāi)始讀2個(gè)字節(jié)的數(shù)據(jù))
GDB發(fā)送的讀命令會(huì)確定局部變量和全局變量的值,并用斷點(diǎn)指令替代opcode,及其他用戶需要的信息。GDB是知道目標(biāo)平臺(tái)的大小端的,因此目標(biāo)機(jī)只需返回字符流即可,GDB會(huì)適當(dāng)?shù)膶?duì)它們進(jìn)行重組。
目標(biāo)機(jī)的調(diào)試樁根據(jù)目標(biāo)機(jī)的數(shù)據(jù)寬度對(duì)讀寫(xiě)內(nèi)存指令進(jìn)行了優(yōu)化,例如日立SH-2處理器的外設(shè)配置寄存器只能通過(guò)16位/32位進(jìn)行讀寫(xiě)。因此,在任何時(shí)刻,調(diào)試樁都只用16位/32位進(jìn)行訪問(wèn)。目標(biāo)機(jī)會(huì)返回如下信息:
+$2f86#-06
寫(xiě)內(nèi)存:(“M”)
eg:M4015cc,2:c320#6d
(向地址0x4015cc寫(xiě)入數(shù)據(jù)0xc320)
如果正確,目標(biāo)機(jī)返回+$OK#9a。
程序控制命令
程序控制命令是GDB用來(lái)控制被調(diào)試程序行為的命令。相對(duì)寄存器相關(guān)命令和內(nèi)存相關(guān)命令,控制命令的實(shí)現(xiàn)難度大些。
獲取最后的信號(hào)(“?”)
eg:$?#3f
這個(gè)命令用來(lái)確定目標(biāo)是如何達(dá)到當(dāng)前的狀態(tài)的。接收到的響應(yīng)同最后的信號(hào)(“l(fā)ast signal”),后面會(huì)介紹。
單步命令(“s”)
eg:$s#73
當(dāng)GDB想讓目標(biāo)精確的執(zhí)行一條匯編指令時(shí),GDB會(huì)向目標(biāo)機(jī)發(fā)送這條命令。(用戶在GDB的console中輸入step和stepi),接收到的響應(yīng)見(jiàn)continue。
繼續(xù)命令(“c”)
eg:$C#63
當(dāng)用戶在console下執(zhí)行continue命令時(shí),GDB回向目標(biāo)機(jī)發(fā)送此命令。目標(biāo)機(jī)成功解析此命令后,GDB會(huì)釋放控制權(quán),使被調(diào)試目標(biāo)機(jī)全速運(yùn)行。
調(diào)試樁除了返回“+”消息包,表示正確收到信息外,不會(huì)立即響應(yīng)step和continue命令。相反,只有當(dāng)下一個(gè)斷點(diǎn)到達(dá)時(shí),被請(qǐng)求的指令已經(jīng)執(zhí)行完(ste,p時(shí)的情況),一個(gè)異常發(fā)生,或者程序退出時(shí),樁才進(jìn)行響應(yīng)。
有兩種方式響應(yīng)這些命令:一種是簡(jiǎn)單的(“l(fā)ast signal”),另一種是多用途的(“expedited response”)。
Last Signal 響應(yīng)(“S”)
eg:+$050#b8
這是最簡(jiǎn)單的響應(yīng)lastsignal(“?”)step和continue命令。“05”可以用作使用POSIX標(biāo)準(zhǔn)的signal函數(shù)的任意信號(hào)值的響應(yīng)。“5”是斷點(diǎn)異常,“10”是總線錯(cuò)誤,等等。
快速響應(yīng)(Expeditedresponse (“T”))
eg:$T0510:1238;F:FFE0…#xx
這條信息將最后的信號(hào)響應(yīng)(例子是“05”)和一些GDB可能立刻會(huì)讀取的寄存器進(jìn)行結(jié)合。為了在代碼單步執(zhí)行時(shí),提高GDB調(diào)試性能,這條信息使GDB直接獲取該寄存器的值(通常是PC和狀態(tài)寄存器),避免發(fā)出讀寄存器的命令。
寄存器號(hào)的格式與讀寫(xiě)寄存器命令相同。在這個(gè)例子中,寄存器16(hex 10)的值是0x1238,寄存器15(F hex)的值為0xffe0。
其他命令:
Console 輸出(“O“)——可自定義的
eg:$0x48656c6cf2c20776f726c64210a#55
(在GDB console中輸出“Hello, world!\n“)
這個(gè)命令允許調(diào)試樁向GDBconsole發(fā)送文本信息。文本會(huì)被按照16進(jìn)制顯示在console中,并且GDB會(huì)一直輸出信息,直到它遇到(‘\n’, 0xa)字符。
這個(gè)信息通常是由目標(biāo)機(jī)發(fā)起,GDB絕不會(huì)發(fā)送一個(gè)console output信息給目標(biāo)機(jī)。
空響應(yīng)(““)
當(dāng)目標(biāo)機(jī)調(diào)試樁遇見(jiàn)一個(gè)它不支持或不理解的命令時(shí),它將返回空響應(yīng)。這允許GDB選擇一個(gè)替代命令如果另一個(gè)命令是有效的。
eg:<an unrecognized command>
目標(biāo)機(jī)響應(yīng):+$#00
錯(cuò)誤響應(yīng)(“E“)
當(dāng)目標(biāo)機(jī)調(diào)試樁在執(zhí)行命令時(shí)遇到一個(gè)錯(cuò)誤時(shí),它將會(huì)給GDB返回錯(cuò)誤信息。例如總線錯(cuò)誤或進(jìn)行非法地址訪問(wèn)時(shí),會(huì)生成這樣的錯(cuò)誤。
eg:<a command that produces an error>
目標(biāo)機(jī)響應(yīng):+$E01##
在GDB中沒(méi)有任何預(yù)定義的錯(cuò)誤碼,因此當(dāng)GDB接收到錯(cuò)誤信息時(shí),會(huì)將錯(cuò)誤信息輸出在console中,并且掛起當(dāng)前進(jìn)程。
總結(jié)
以上是生活随笔為你收集整理的GDB Remote Serial Protocol —— RSP协议解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 浅谈cpu.idle和cpu.load
- 下一篇: javascript中如何求数组的平均值