暫存器和ioremap的使用

2021-10-12 13:02:05 字數 3559 閱讀 3325

1.暫存器概述

暫存器的功能是儲存二進位制**,它是由具有儲存功能的觸發器組合起來構成的。乙個觸發器可以儲存1位二進位制**,故存放n位二進位制**的暫存器,需用n個觸發器來構成。

按照功能的不同,可將暫存器分為基本暫存器和移位暫存器兩大類。基本暫存器只能並行送入資料,也只能並行輸出。移位暫存器中的資料可以在移位脈衝作用下依次逐位右移或左移,資料既可以並行輸入、並行輸出,也可以序列輸入、序列輸出,還可以並行輸入、序列輸出,或序列輸入、並行輸出,十分靈活,用途也很廣。

2.暫存器的大小:

8位的微控制器,乙個暫存器佔8bit,乙個位元組。16位的微控制器,1個暫存器,佔16bit,2個位元組。高階一點的,arm的晶元,乙個暫存器佔32bit,即是4個位元組。

原型:

void

*ioremap

(unsigned

long phys_addr,

unsigned

long size)

void

*__ioremap

(unsigned

long phys_addr,

unsigned

long size,

unsigned

long flags)

size: 要對映的空間的大小(多少個位元組);

ioremap 依靠 __ioremap實現,它只是在__ioremap中以第三個引數為0呼叫來實現.

flags:要對映的io空間的和許可權有關的標誌;

size:是要對映的長度,

功能:將乙個io位址空間對映到核心的虛擬位址空間上去,便於訪問;函式專門用來為i/o記憶體區域分配虛擬位址。經過ioremap之後,裝置驅動即可訪問任意的i/o記憶體位址。有了ioremap (和iounmap),裝置就可以訪問任何i/o記憶體空間,不論它是否直接對映到虛擬位址空間。但是,這些位址永遠不能直接使用(指實體地址),而要用readb這種函式。

ioremap是核心提供的用來對映外設暫存器到主存的函式,我們要對映的位址**於cpu的使用者開發手冊。硬體的跳線或者是物理連線方式決定了硬體上的記憶體對映到的cpu實體地址。對映完了有什麼效果呢,舉個例子,比如某個網絡卡有100個暫存器,他們都是連在一塊的,位置是固定的,加入每個暫存器佔4個位元組,那麼一共400個位元組的空間被對映到記憶體成功後,ioaddr就是這段位址的開頭(ioaddr = ioremap (mmio_start, mmio_len);注意ioaddr是虛擬位址,而mmio_start是實體地址,它是開發手冊中提供的,肯定是實體地址,而保護模式下cpu不認實體地址,只認虛擬位址),ioaddr+0就是第乙個暫存器的位址,ioaddr+4就是第二個暫存器位址(每個暫存器佔4個位元組),以此類推,我們就能夠在記憶體中訪問到所有的暫存器進而操控他們了。

訪問i/o記憶體的正確方式是通過一系列專用於此目的的函式(在中定義的):

i/o記憶體讀函式

unsigned

intioread8

(void

*addr)

;unsigned

intioread16

(void

*addr)

;unsigned

intioread32

(void

*addr)

;

addr是從ioremap獲得的位址(可能包含乙個整型偏移量),返回值是從給定i/o記憶體讀取的值

對應的i/o記憶體寫函式

void

iowrite8

(u8value,

void

*addr)

;void

iowrite16

(u16value,

void

*addr)

;void

iowrite32

(u32value,

void

*addr)

;

讀和寫一系列值到乙個給定的i/o記憶體位址,從給定的buf讀或寫count個值到給定的addr

void

ioread8_rep

(void

*addr,

void

*buf,

unsigned

long count)

;void

ioread16_rep

(void

*addr,

void

*buf,

unsigned

long count)

;void

ioread32_rep

(void

*addr,

void

*buf,

unsigned

long count)

;void

iowrite8_rep

(void

*addr,

const

void

*buf,

unsigned

long count)

;void

iowrite16_rep

(void

*addr,

const

void

*buf,

unsigned

long count)

;void

iowrite32_rep

(void

*addr,

const

void

*buf,

unsigned

long count)

;

需要操作一塊i/o位址,使用一下函式

void

memset_io

(void

*addr, u8 value,

unsigned

int count)

;void

memcpy_fromio

(void

*dest,

void

*source,

unsigned

int count)

;void

memcpy_toio

(void

*dest,

void

*source,

unsigned

int count)

舊函式介面,仍可工作,但不推薦。

unsigned

readb

(address)

;unsigned

readw

(address)

;unsigned

readl

(address)

;void

writeb

(unsigned value,address)

;void

writew

(unsigned value,address)

;void

writel

(unsigned value,address)

;

CS 暫存器 和 IP 暫存器

下面將要介紹的是一組非常非常重要的暫存器,即 cs ip cs ip 兩個暫存器指示了 cpu 當前將要讀取的指令的位址,其中cs 為 段暫存器,而ip 為指令指標暫存器。什麼叫做指示了 cpu 當前將要讀取的指令呢?在 8086 cpu 中,為什麼 cpu 會自動的執行指令呢?這些指令肯定是存放在...

除錯暫存器和測試暫存器

1 除錯暫存器 80386為除錯提供了硬體支撐。在80386晶元內有8個32位的除錯暫存器dr0 dr7,如圖2.6所示。這些暫存器可以使系統程式設計人員定義4個斷點,用它們可以規定指令執行和資料讀寫的任何組合。dr0 dr3是線性斷點位址暫存器,其中儲存著4個斷點位址。dr5 dr6是兩個備用的除...

暫存器(通用暫存器)

因為學習使用的是王爽的 組合語言 第3版 因此也只能提到8086cpo的暫存器。對於其他而言,原理都是相通的。對於8086暫存器,有14個暫存器,主要是 ax bx cx dx si di sp bp ip cs ss ds es psw。一 通用暫存器 8086的通用暫存器有ax bx cx dx...