linux寄存器
㈠ linux如何讀取某個寄存器的值如何讀
處理概要: 通過制定類型(int,char等)的指針變數,把rw的地址給這個指針。 通過指針操作,取得含有07位的數值,然後通過移位運算即可取得07位的值。 僅供參考。
㈡ 請問在linux內核中有什麼寄存器。在內核中這么讀取這些寄存器用戶態怎麼訪
不是很明白你的意思。寄存器是個硬體的結構,存在CPU中,比如EAX,EBX,ECX,EDX這些通用寄存器。硬體設備也會有寄存器,用來給軟體提供控制的方法。比如顯卡肯定有個寄存器來啟用或者禁用。讀寫寄存器標準的使用IN,OUT指令(IA架構)。當然也會有把寄存器映射到內存空間,想讀寫內存一樣讀寫寄存器。用戶態程序一般是無法訪問寄存器的,除非驅動程序把寄存器映射到用戶進程空間
㈢ 請問在linux內核中有什麼寄存器。在內核中這么讀取這些寄存器用戶態怎麼訪
寄存器由硬體決定。內核直接讀寫。用戶態通過系統調用執行內核代碼來讀寫。
㈣ 關於linux驅動中的寄存器地址
寄存器名字就成了「指針」,是一個地址
沒有的就要自己加了
㈤ 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");
㈥ linux c函數返回值是在棧中還是寄存器
函數的返回值是在寄存器中,但僅限於返回的是值。
如果返回的地址,並且這個地址是個局部變數的地址,那麼就是在棧上,所以我們不建議返回這樣的地址結果。
如果返回的是一個malloc或者new的變數的地址,就是在堆上。如果要返回地址,建議這樣做,還要注意使用完成後進行內存釋放
㈦ linux驅動中外設寄存器在哪裡配置的
1、不同外設的驅動是不同的,要跟據外設對應的datasheet設置;
2、一般寄存器的設置都在驅動程序的init函數里。
㈧ arm linux 怎麼把內核空間的寄存器映射到用戶 空間
如果是通過 alloc_page() 獲得了高端內存對應的 page,如何給它找個線性空間?
內核專門為此留出一塊線性空間,從 PKMAP_BASE 到 FIXADDR_START ,用於映射高端內存。在 2.6內核上,這個地址范圍是 4G-8M 到 4G-4M 之間。這個空間起叫」內核永久映射空間」或者」永久內核映射空間」。這個空間和其它空間使用同樣的頁目錄表,對於內核來說,就是 swapper_pg_dir,對普通進程來說,通過 CR3 寄存器指向。通常情況下,這個空間是 4M 大小,因此僅僅需要一個頁表即可,內核通過來 pkmap_page_table 尋找這個頁表。通過 kmap(),可以把一個 page 映射到這個空間來。由於這個空間是 4M 大小,最多能同時映射 1024 個 page。因此,對於不使用的的 page,及應該時從這個空間釋放掉(也就是解除映射關系),通過 kunmap() ,可以把一個 page 對應的線性地址從這個空間釋放出來。
㈨ linux系統下寄存器
Linux也可以家用的!~! 現在的Linux人性化多了~!~ 樓上的那樣說就大錯特錯了~~! Windows就是一點人性化而己我個人覺得Linux和Windows是沒有比的!~都是操作系統但是我支持Linux多一點!~!~ Linux中也可以和Windows文件共享!~~上網聊天那也不在話下了功能多著呢安全方面和性能方面就不用說了吧~!~!Windows那還真沒得比呢~!~!