『壹』 linux如何讀取某個寄存器的值如何讀
處理概要: 通過制定類型(int,char等)的指針變數,把rw的地址給這個指針。 通過指針操作,取得含有07位的數值,然後通過移位運算即可取得07位的值。 僅供參考。
『貳』 linux下編寫一個內核模塊程序,獲取系統核心寄存器的值。
這個沒你想的那麼復雜,相當簡單,
Linux下面就是把AT&T語法的匯編程序編譯成.o
文件,這個匯編程序只包含一個函數即可,這個函數就是把你想要寄存器的值存在通用寄存器里作為返回值。另外你再寫一個C語言程序文件,C里調用這個匯編函數後,把返回值printk出來即可。這個是最簡單的分兩個文件混合C,assem
。
另外,用GCC還可以在單個文件混合匯編。可以參考一下。
『叄』 關於linux驅動中的寄存器地址
寄存器名字就成了「指針」,是一個地址
沒有的就要自己加了
『肆』 linux上有沒有工具能看到內存和寄存器的值
用途說明 tail命令可以輸出文件的尾部內容,默認情況下它顯示文件的最後十行。它常用來動態監視文件的尾部內容的增長情況,比如用來監視日誌文件的變化。與tail命令對應的是head命令,用來顯示文件頭部內容。
『伍』 linux中 eip寄存器 程序計數器裡面放的內容到底是什麼呢
去看微機原理....
ip或者EIP(32位機) 又叫指令指針寄存器。
存放當前指令的下一條指令的地址。CPU該執行哪條指令就是通過IP來指示的。
EIP是32位機的指令寄存器。
『陸』 LINUX中,如何查看CPU有哪些寄存器,其長度為多少
這很難說,
CPU的16位、32位以及64位技術,指的是CPU一次性能處理的最大數據位。具體的,比較直觀的,主要體現在CPU的主要寄存器的長度上。也就是從8086/8088那時候開始的AX,BX,CX,DX等等。
CPU的寄存器的長度,可以說,它代表了CPU一次性能處理的最大數值的能力。如果你了解二進制,這個就比較好理解:
兩個64位的二進制數如果用32位的CPU做加法,是一件比較麻煩的事情,需要多條指令才能完成。
而對於64位的CPU來說,它計算64位的加法,只要一條指令。
所以,理論上說,64位的CPU的處理能力要強於32位的CPU。
但是,硬體的使用,需要相應的軟體配合。如果64位的CPU上運行的是32位的代碼,那麼,該CPU的優勢並不能發揮出來。
就如同一個高中生和一個初中生都計算1+1等於幾的問題。
答案都可以算出來,速度都很快。但高中生的強項你是看不到的。
我們目前的操作系統,除了LINUX/UNIX外,主要還是32位。
不是說沒有64位的WINDOWS系統。像WINDOWS XP和WINDOWS VISTA都有64位的,但個人感覺用的人比較少。主要是因為64位的操作系統,還需要64位的應用軟體才能發揮出64位的優勢。
而64位的軟體的產生,目前來說,主要取決編譯系統是否能生成64位代碼。想想看,現在的大學,普遍都還在研究98年的VC6.0等編譯系統,所以,64位的應用,現在只能說是起步。
以上說的是CPU的常規寄存器。事實上,CPU的其它某些專用寄存器,都有128位的了。
總的來說,64位CPU是目前的主流,32位在以後的10多年中會逐步淘汰---就如同當年的386出生後,16位的逐步淘汰。
『柒』 imx6q linux bsp中怎麼讀取一個寄存器的值
這一問題來自項目中一個實際的需求:
我需要在Linux啟動之後,確認我指定的晶元寄存器是否與我在uboot的配置一致。
舉個例子:
寄存器地址:0x20000010負責對DDR2的時序配置,該寄存器是在uboot中設置,現在我想在Linux運行後,讀出改寄存器的值,再來檢查該寄存器是否與uboot的配置一致。
Linux應用程序運行的是虛擬空間,有沒有什麼機制可以是完成我提到的這一需求。若行,還請附些測試代碼。
謝謝!
這個需要用mmap()函數將寄存器物理地址映射為用戶空間的虛擬地址,即將寄存器的那段內存映射到用戶空間,函數介紹如下:
void*
mmap(void
*
addr,
size_t
len,
int
prot,
int
flags,
int
fd,
off_t
offset);
該函數映射文件描述符
fd
指定文件的
[offset,
offset
+
len]
物理內存區至調用進程的
[addr,
addr
+
len]
的用戶空間虛擬內存區,通常用於內存共享或者用戶空間程序控制硬體設備,函數的返回值為最後文件映射到用戶空間的地址,進程可直接操作該地址。下面是測試代碼(僅供參考):
#define
DDR2_REG_BASE
(0x20000000)
#define
MAP_SIZE
4096UL
#define
MAP_MASK
(MAP_SIZE
-
1)
static
unsigned
int
pTestRegBase;
static
int
dev_fd;
dev_fd
=
open("/dev/mem",
O_RDWR
|
O_NDELAY);
if
(dev_fd
<</SPAN>
0)
{
LOGE("open(/dev/mem)
failed.");
return;
}
pTestRegBase
=
(void
*)mmap(NULL,
MAP_SIZE,
PROT_READ
|
PROT_WRITE,
MAP_SHARED,
dev_fd,DDR2_REG_BASE
&
~MAP_MASK);
if
(MAP_FAILED
==
pTestRegBase)
{
printf("mmap
failed.
fd(%d),
addr(0x%x),
size(%d)\n",
dev_fd,
DDR2_REG_BASE,
MAP_SIZE);
}
else
{
unsigned
int
reg_value
=
*((volatile
unsigned
int
*)(pTestRegBase
+
10));
printf("reg_value
=
0xx\n",
reg_value);
munmap((void*)pTestRegBase,
MAP_SIZE);
}
pTestRegBase
=
0;
if(dev_fd)
close(dev_fd);
這里將DDR2_REG_BASE開始大小為1個page的物理地址映射到了用戶空間,然後就可以用pTestRegBase作為起始地址操作寄存器了。
『捌』 linux c函數返回值是在棧中還是寄存器
函數的返回值是在寄存器中,但僅限於返回的是值。
如果返回的地址,並且這個地址是個局部變數的地址,那麼就是在棧上,所以我們不建議返回這樣的地址結果。
如果返回的是一個malloc或者new的變數的地址,就是在堆上。如果要返回地址,建議這樣做,還要注意使用完成後進行內存釋放
『玖』 請問在linux環境下中如何操作寄存器
在linux下控制硬體和在無操作系統下控制硬體的不同主要在於硬體的地址不一樣,在linux下要使用va(虛擬地址),而在無操作系統下可以直接使用硬體的pa(物理地址)。
在linux-2.6.8.1/include/asm-arm/arch-s3c2410/map.h中定義了大部分硬體的物理地址和他們的虛擬地址。
現以gpio
F為例說明,gpio
的pa
基址(ba)為0x56000000,GPFCON
pa為0x56000050
即:可見偏移量為0x50,而我們在看看GPFCON
va
,vaba
:0xf0e0
0000,va:0xf0e0
0050,偏移量為0x50。我們只要知道了vaba,和他的偏移量,我們就能計算出va,從而,就可以對其進行操作了。
如何獲取vaba:在linux-2.6.8.1/include/asm-arm/arch-s3c2410/map.h中有定義。
計算機中,分級分層的思想隨處可見,這也是計算機上的一個基本的思想和思路。
在LINUX操作系統中分了三級,三級偏移,一級地址的ba為0xf0000000,偏移到第二級,0xf0e0
0000
(以GPIO為例),再次偏移到第三級,0xf0e0
0050
(以GPFCON為例)。現在,就可以在linux
下通過0xf0e0
0050來對GPFCON
寄存器來進行操作了。
源碼中的實現過程如下:
#define
S3C2410_ADDR(x)
(0xF0000000+(x))//map.h
//linux下所有硬體一級地址vaba:0xF0000000
#define
S3C2410_VA_GPIO
S3C2410(0X00E00000)//map.h
//GPIO的偏移量0x00E00000,加上這個偏移量後,到了GPIO器件
#define
S3C2410_GPIOREG(x)
((x)+S3C2410_VA_GPIO)
#define
S3C2410_GPFCON
S3C2410_GPIOREG(0x50)//regs-gpio.h
//GPFCON寄存器的偏移量0x50,加上這個偏移量後,到了具體的寄存器,可以對硬體進行操作了
#define
S3C2410_GPFDAT
S3C2410_GPIOREG(0x54)//regs-gpio.h
#define
S3C2410_GPFUP
S3C2410_GPIOREG(0x58)//regs-gpio.h