请问在linux内核中有什么寄存器。在内核中这么读取这些寄存器?用户态怎么访

请问在linux内核中有什么寄存器。在内核中这么读取这些寄存器?用户态怎么访,第1张

不是很明白你的意思。寄存器是个硬件的结构,存在CPU中,比如EAX,EBX,ECX,EDX这些通用寄存器。硬件设备也会有寄存器,用来给软件提供控制的方法。比如显卡肯定有个寄存器来启用或者禁用。读写寄存器标准的使用IN,OUT指令(IA架构)。当然也会有把寄存器映射到内存空间,想读写内存一样读写寄存器。用户态程序一般是无法访问寄存器的,除非驱动程序把寄存器映射到用户进程空间

设备驱动? 如果是:可以写一个 字符设备驱动实现。 驱动,最简单的是:用 ioremap(),把GPIO的地址映射到 linux内核空间。 然后 *** 作该gpio的寄存器。 之后很简单,和裸板控制gpio的方法一样。只是字符设备方面的实现不一样。

arm裸机下读写寄存器很容易,各个寄存器和内存的地址是单一地址空间,他们是用相同的指令进行读写 *** 作的.而在linux下就要复杂很多,因为linux支持多个体系架构的CPU。比如arm和x86就不一样,具体的差别我暂时也说不上来,这个涉及到CPU体系的设计。目前我只关心:linux为了支持多个硬件体系,在IO访问上做了自己的接口。可以通过IO内存和IO端口这两种方式进行IO访问。在LED的例子上给出这两种方式的具体实现:

1.利用IO Port的方式:

[cpp] view plain copy

#include <linux/module.h>

#include <linux/moduleparam.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> /* copy_*_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 baikal: led dev write\n")

led = (struct led_dev *)filp->private_data

copy_from_user(&data,buf,count)

if(data == '0')

{

printk(KERN_INFO "debug by baikal: 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 baikal: 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 = 0i <LED_NUMi++)

{

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 = 0i <LED_NUMi++)

{

//iounmap(led[i].base)

cdev_del(&led[i].dev)

}

unregister_chrdev_region(dev, LED_NUM)

}

module_init(led_init)

module_exit(led_exit)

MODULE_AUTHOR("Baikal")

MODULE_LICENSE("GPL")

MODULE_DESCRIPTION("Simple LED Driver")

2.利用IO Mem的方式:

[cpp] view plain copy

#include <linux/module.h>

#include <linux/moduleparam.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> /* copy_*_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 baikal: led dev write\n")

led = (struct led_dev *)filp->private_data

copy_from_user(&data,buf,count)

if(data == '0')

{

printk(KERN_INFO "debug by baikal: led off\n")

value = ioread32(led->base)

iowrite32( value | 1<<led->offset, led->base)

}

else

{

printk(KERN_INFO "debug by baikal: 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 = 0i <LED_NUMi++)

{

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 = 0i <LED_NUMi++)

{

iounmap(led[i].base)

cdev_del(&led[i].dev)

}

unregister_chrdev_region(dev, LED_NUM)

}

module_init(led_init)

module_exit(led_exit)

MODULE_AUTHOR("Baikal")

MODULE_LICENSE("GPL")

MODULE_DESCRIPTION("Simple LED Driver")


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/8707241.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-04-20
下一篇 2023-04-20

发表评论

登录后才能评论

评论列表(0条)

保存