當前位置:首頁 » 密碼管理 » linux訪問寄存器

linux訪問寄存器

發布時間: 2023-11-25 19:19:42

1. 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作為起始地址操作寄存器了。

2. linux kernel 怎麼讀cpu寫寄存器 inw

arm裸機下讀寫寄存器很容易,各個寄存器和內存的地址是單一地址空間,他們是用相同的指令進行讀寫操作的.而在linux下就要復雜很多,因為linux支持多個體系架構的CPU。比如arm和x86就不一樣,具體的差別我暫時也說不上來,這個涉及到CPU體系的設計。目前我只關心:linux為了支持多個硬體體系,在IO訪問上做了自己的介面。可以通過IO內存和IO埠這兩種方式進行IO訪問。在LED的例子上給出這兩種方式的具體實現:
1.利用IO Port的方式:

[cpp] view plain
#include <linux/mole.h>
#include <linux/moleparam.h>
#include <linux/init.h>

#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/seq_file.h>
#include <linux/cdev.h>
#include <linux/ioport.h>

#include <mach/regs-gpio.h>
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* _*_user */
#include <asm/io.h>

#define LED_NUM 4

struct led_dev
{
struct cdev dev;
unsigned port;
unsigned long offset;
};

struct led_dev led[4];
dev_t dev = 0;
static struct resource *led_resource;

int led_open(struct inode *inode, struct file *filp)
{
struct led_dev *led; /* device information */

led = container_of(inode->i_cdev, struct led_dev, dev);
filp->private_data = led; /* for other methods */

return 0; /* success */
}

int led_release(struct inode *inode, struct file *filp)
{
return 0;
}

ssize_t led_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
return 0;
}

ssize_t led_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
char data;
struct led_dev *led;
u32 value;
printk(KERN_INFO "debug by kal: led dev write\n");

led = (struct led_dev *)filp->private_data;
_from_user(&data,buf,count);
if(data == '0')
{
printk(KERN_INFO "debug by kal: led off\n");
value = inl((unsigned)(S3C2410_GPBDAT));
outl(value | 1<<led->offset,(unsigned)(S3C2410_GPBDAT));
//value = ioread32(led->base);
//iowrite32( value | 1<<led->offset, led->base);
}
else
{
printk(KERN_INFO "debug by kal: led on\n");
value = inl((unsigned)(S3C2410_GPBDAT));
outl(value & ~(1<<led->offset),(unsigned)(S3C2410_GPBDAT));
//value = ioread32(led->base);
//iowrite32( value & ~(1<<led->offset), led->base);
}
}

struct file_operations led_fops = {
.owner = THIS_MODULE,
.read = led_read,
.write = led_write,
//.ioctl = led_ioctl,
.open = led_open,
.release = led_release,
};

static int led_init(void)
{
int result, i;

result = alloc_chrdev_region(&dev, 0, LED_NUM,"LED");
if (result < 0) {
printk(KERN_WARNING "LED: can't get major %d\n", MAJOR(dev));
return result;
}
led_resource = request_region(0x56000014,0x4,"led");
if(led_resource == NULL)
{
printk(KERN_ERR " Unable to register LED I/O addresses\n");
return -1;
}
for(i = 0; i < LED_NUM; i++)
{
cdev_init( &led[i].dev, &led_fops);
//led[i].port = ioport_map(0x56000014,0x4);
//led[i].base = ioremap(0x56000014,0x4);
led[i].offset = i + 5; //leds GPB5\6\7\8
led[i].dev.owner = THIS_MODULE;
led[i].dev.ops = &led_fops;
result = cdev_add(&led[i].dev,MKDEV(MAJOR(dev),i),1);
if(result < 0)
{
printk(KERN_ERR "LED: can't add led%d\n",i);
return result;
}
}

return 0;
}

static void led_exit(void)
{
int i;
release_region(0x56000014,0x4);
for( i = 0; i < LED_NUM; i++)
{
//iounmap(led[i].base);

cdev_del(&led[i].dev);
}
unregister_chrdev_region(dev, LED_NUM);

}

mole_init(led_init);
mole_exit(led_exit);

MODULE_AUTHOR("Baikal");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple LED Driver");

2.利用IO Mem的方式:

[cpp] view plain
#include <linux/mole.h>
#include <linux/moleparam.h>
#include <linux/init.h>

#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <linux/seq_file.h>
#include <linux/cdev.h>
#include <linux/ioport.h>

#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* _*_user */
#include <asm/io.h>

#define LED_NUM 4

struct led_dev
{
struct cdev dev;
void __iomem *base;
unsigned long offset;
};

struct led_dev led[4];
dev_t dev = 0;

int led_open(struct inode *inode, struct file *filp)
{
struct led_dev *led; /* device information */

led = container_of(inode->i_cdev, struct led_dev, dev);
filp->private_data = led; /* for other methods */

return 0; /* success */
}

int led_release(struct inode *inode, struct file *filp)
{
return 0;
}

ssize_t led_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
return 0;
}

ssize_t led_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
char data;
struct led_dev *led;
u32 value;
printk(KERN_INFO "debug by kal: led dev write\n");

led = (struct led_dev *)filp->private_data;
_from_user(&data,buf,count);
if(data == '0')
{
printk(KERN_INFO "debug by kal: led off\n");
value = ioread32(led->base);
iowrite32( value | 1<<led->offset, led->base);
}
else
{
printk(KERN_INFO "debug by kal: led on\n");
value = ioread32(led->base);
iowrite32( value & ~(1<<led->offset), led->base);
}
}

struct file_operations led_fops = {
.owner = THIS_MODULE,
.read = led_read,
.write = led_write,
//.ioctl = led_ioctl,
.open = led_open,
.release = led_release,
};

static int led_init(void)
{
int result, i;

result = alloc_chrdev_region(&dev, 0, LED_NUM,"LED");
if (result < 0) {
printk(KERN_WARNING "LED: can't get major %d\n", MAJOR(dev));
return result;
}

for(i = 0; i < LED_NUM; i++)
{
cdev_init( &led[i].dev, &led_fops);
request_mem_region(0x56000014,0x4,"led");
led[i].base = ioremap(0x56000014,0x4);
led[i].offset = i + 5; //leds GPB5\6\7\8
led[i].dev.owner = THIS_MODULE;
led[i].dev.ops = &led_fops;
result = cdev_add(&led[i].dev,MKDEV(MAJOR(dev),i),1);
if(result < 0)
{
printk(KERN_ERR "LED: can't add led%d\n",i);
return result;
}
}

return 0;
}

static void led_exit(void)
{
int i;
release_mem_region(0x56000014,0x4);
for( i = 0; i < LED_NUM; i++)
{
iounmap(led[i].base);

cdev_del(&led[i].dev);
}
unregister_chrdev_region(dev, LED_NUM);

}

mole_init(led_init);
mole_exit(led_exit);

MODULE_AUTHOR("Baikal");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple LED Driver");

3. Linux如何讀取某個寄存器的值如何讀

處理概要: 通過制定類型(int,char等)的指針變數,把rw的地址給這個指針。 通過指針操作,取得含有07位的數值,然後通過移位運算即可取得07位的值。 僅供參考。

4. linux系統怎麼查看cpu使用情況

1、查看內存:在SSH遠程式控制制端,輸入命令「cat /proc/meminfo」,按下「Enter」回車鍵,即可看到總的內存佔用情況。
2、查看CPU:在SSH遠程式控制制端,輸入命令「top」,按下「Enter」回車鍵,即可看到cpu的使用率。
3、Linux上的VNC服務端,比較常用的就是tigervnc和x11vnc。x11vnc可以讓遠程訪問者控制本地的實際顯示器,而tigervnc既可以遠程式控制制實際顯示器,還可以控制平行獨立於當前物理顯示器的虛擬顯示器。
中央處理器(Central Processing Unit),簡稱CPU,是1971年推出的一個計算機的運算核心和控制核心,是信息處理、程序運行的最終執行單元。

中央處理器包含運算邏輯部件、寄存器部件和控制部件等,並具有處理指令、執行操作、控制時間、處理數據等功能。
CPU包括運算邏輯部件、寄存器部件和控制部件等。[1]

邏輯部件
英文Logic components;運算邏輯部件,可以執行定點或浮點算術運算操作、移位操作以及邏輯操作,也可執行地址運算和轉換。

寄存器
中央處理器
中央處理器
寄存器部件,包括通用寄存器、專用寄存器和控制寄存器。

通用寄存器又可分定點數和浮點數兩類,它們用來保存指令執行過程中臨時存放的寄存器操作數和中間(或最終)的操作結果。

通用寄存器是中央處理器的重要組成部分,大多數指令都要訪問到通用寄存器。通用寄存器的寬度決定計算機內部的數據通路寬度,其埠數目往往可影響內部操作的並行性。

專用寄存器是為了執行一些特殊操作所需用的寄存器。

控制寄存器(CR0~CR3)用於控制和確定處理器的操作模式以及當前執行任務的特性。CR0中含有控制處理器操作模式和狀態的系統控制標志;CR1保留不用;CR2含有導致頁錯誤的線性地址;CR3中含有頁目錄表物理內存基地址.

控制部件
英文Control unit;控制部件,主要是負責對指令解碼,並且發出為完成每條指令所要執行的各個操作的控制信號。

其結構有兩種:一種是以微存儲為核心的微程序控制方式;一種是以邏輯硬布線結構為主的控制方式。

微存儲中保持微碼,每一個微碼對應於一個最基本的微操作,又稱微指令;各條指令是由不同序列的微碼組成,這種微碼序列構成微程序。中央處理器在對指令解碼以後,即發出一定時序的控制信號,按給定序列的順序以微周期為節拍執行由這些微碼確定的若干個微操作,即可完成某條指令的執行。

簡單指令是由(3~5)個微操作組成,復雜指令則要由幾十個微操作甚至幾百個微操作組成。

熱點內容
魅族手機軟體怎麼加密 發布:2024-11-29 07:50:04 瀏覽:214
阿里雲伺服器託管合同 發布:2024-11-29 07:46:37 瀏覽:296
linux用戶許可權設置 發布:2024-11-29 07:43:39 瀏覽:270
c語言if函數嵌套 發布:2024-11-29 07:43:35 瀏覽:757
學編程L2 發布:2024-11-29 07:39:58 瀏覽:429
微信如何設置收與付密碼 發布:2024-11-29 07:39:15 瀏覽:541
mysql備份與恢復腳本 發布:2024-11-29 07:39:13 瀏覽:50
在c語言的基本單位是 發布:2024-11-29 07:38:36 瀏覽:792
c語言演算法結構 發布:2024-11-29 07:23:08 瀏覽:222
空氣壓縮呼吸 發布:2024-11-29 07:23:00 瀏覽:56