日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Kernel中如何操作CPU及外设寄存器

發(fā)布時間:2023/12/20 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Kernel中如何操作CPU及外设寄存器 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

01

ARM Coretex-A9寄存器

對于ARM Coretex-A9處理器而言其寄存器主要包括兩大部分,分別是通用寄存器以及系統(tǒng)控制寄存器。

上圖所示的通用寄存器,主要是在代碼運行過程中使用到,CPU通過該部分寄存器執(zhí)行代碼并完成相關(guān)的運算操作。對于調(diào)試過程中比較關(guān)心的是SP、LR、PC以及R0~R3幾個寄存器。而其他寄存器在特定場景下也有應(yīng)用,例如U-Boot在代碼重定向的過程中使用到了R9寄存器來暫存gd_t的地址。調(diào)試過程中,當代碼崩潰的時候我們第一步是看PC是多少,以此通過追蹤反匯編文件來定位到具體的指令處。

對于系統(tǒng)控制寄存器而言,其實現(xiàn)了CPU的一些控制以及狀態(tài)指示等功能,例如通過ACTLR寄存器完成多核的配置,通過CPSR寄存器實現(xiàn)CPU的邏輯運算狀態(tài)指示等。CP15寄存器一共是16組寄存器,通過MRC/MCR指令并結(jié)合不同的指令碼實現(xiàn)寄存器的訪問。

MRC和MCR指令如下圖所示:

CPU的取指、運算過程如下圖所示,除了要操作內(nèi)存之外,內(nèi)部的寄存器組也會同步進行更新。


02

調(diào)試工具操作CPU寄存器

在芯片開發(fā)驗證的過程中,不可避免的會遇到CPU內(nèi)部邏輯實現(xiàn)異常而導(dǎo)致代碼無法正常得到執(zhí)行,此時需要定位故障的原因,一般可以通過JLINK、DSTREAM工具獲取、操作CPU的寄存器。對于程序已經(jīng)執(zhí)行出錯的場景而JTAG仍然可以連接上的場景,使用JLINK工具可以獲取到故障現(xiàn)場信息。JLINK連接上之后輸入Regs命令,可以dump出CPU的寄存器值:

當希望改寫CPU通用寄存器的時候,可以通過wreg來實現(xiàn):

同樣,CP15寄存器也可以操作:


03

C代碼中內(nèi)嵌匯編

當通過故障現(xiàn)場不能得知故障原因的時候,需要追蹤CPU執(zhí)行過程中寄存器的變化狀態(tài),例如Kerne的用戶空間程序申請頁表的過程中,我們可以通過CP15的ttbr0寄存器獲取頁表地址。

1#define?_ARM_MRC(coproc,?opcode1,?Rt,?CRn,?CRm,?opcode2)????????\2????asm?volatile?("mrc?p"?#coproc?",?"?#opcode1?",?%[output],?c"?#CRn?",?c"?#CRm?",?"?#opcode2?"\n"?:?[output]?"=r"?(Rt))3#define?_ARM_MCR(coproc,?opcode1,?Rt,?CRn,?CRm,?opcode2)????????\4????asm?volatile?("mcr?p"?#coproc?",?"?#opcode1?",?%[input],?c"?#CRn?",?c"?#CRm?",?"?#opcode2?"\n"?::?[input]?"r"?(Rt))56void?func1(void)7{8????????u32?ttbr0,ttbr1;9????????_ARM_MRC(15,?0,?ttbr0,?2,?0,?0); 10????????_ARM_MRC(15,?0,?ttbr1,?2,?0,?1); 11????????printk("ttbr0?0x%08x?ttbr1?0x%08x\n",?ttbr0,?ttbr1); 12}

對于其他寄存器的操作,U-Boot中\(zhòng)arch\arm\include\asm\system.h的代碼可以借鑒,通過移植該部分代碼可以實現(xiàn)我們的需求:

1static?inline?unsigned?int?get_cr(void)2{3????unsigned?int?val;45????if?(is_hyp())6????????asm?volatile("mrc?p15,?4,?%0,?c1,?c0,?0?@?get?CR"?:?"=r"?(val)7??????????????????????????????????:8??????????????????????????????????:?"cc");9????else 10????????asm?volatile("mrc?p15,?0,?%0,?c1,?c0,?0?@?get?CR"?:?"=r"?(val) 11??????????????????????????????????: 12??????????????????????????????????:?"cc"); 13????return?val; 14} 15 16static?inline?void?set_cr(unsigned?int?val) 17{ 18????if?(is_hyp()) 19????????asm?volatile("mcr?p15,?4,?%0,?c1,?c0,?0?@?set?CR"?: 20??????????????????????????????????:?"r"?(val) 21??????????????????????????????????:?"cc"); 22????else 23????????asm?volatile("mcr?p15,?0,?%0,?c1,?c0,?0?@?set?CR"?: 24??????????????????????????????????:?"r"?(val) 25??????????????????????????????????:?"cc"); 26????isb(); 27}

04

devmem

對于kernel已經(jīng)掛在文件系統(tǒng)之后,操作外設(shè)寄存器的方法有很多,但是比較傾向于使用devmem這個命令,該命令可以直接操作物理內(nèi)存空間,不必考慮虛擬地址和物理地址之間的映射。該命令由busybox提供,通過配置busybox可以在生成的文件系統(tǒng)中包含它。

通過devmem操作寄存器的過程如下


END


推薦閱讀:

專輯|Linux文章匯總

專輯|程序人生

專輯|C語言

我的知識小密圈

總結(jié)

以上是生活随笔為你收集整理的Kernel中如何操作CPU及外设寄存器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。