linux 一些机制 (三)

目录

一.Address_space

二.Dup系统调用

三.Proc应用

一.Address_space

       内核空间到用户空间

__user 这个特性,即__attribute__((noderef, address_space(1))),是用来修饰一个变量的,这个变量必须是非解除参考(__attribute__((noderef))——no dereference)的,即这个变量地址必须是有效的,而且变量所在的地址空间必须是1__attribute__((address_space(1)))),即用户程序空间的。这里Sparse工具把程序空间分成了3个部分,0表示normal space,即普通地址空间,对内核代码来说,当然就是内核空间地址了。1表示用户地址空间,这个不用多讲,还有一个2,表示是设备地址映射空间,例如硬件设备的寄存器在内核里所映射的地址空间。

      
# define __kernel /* default address space */
    
根据定义,就是检查是否处于内核空间。其为默认的地址空间,即0,我想定义成__attribute__((noderef, address_space(0)))也是没有问题的。

 

# define __user          __attribute__((noderef, address_space(1)))

       调用Copy_to_user copy_from_user 需要添加__user的原因就是将用户空间上的数据拷贝到内核空间上

 

# define __iomem      __attribute__((noderef, address_space(2)))

       写过内核驱动的都一定用过ioremap,事实上也与设备地址映射空间有关。

static inline void __iomem *ioremap(phys_addr_t offset, unsigned long size)

{

       return (void __iomem*) (unsigned long)offset;

}

在进行映射时,就是将物理地址对应到IO内存地址,这样就能直接操作IO内存地址,

从而操作对应的寄存器。

       比如__raw_writel,__raw_readl 就是将数据读写到对应的IO内存地址上,例如

static inline void __raw_writel(u32 b, volatile void __iomem *addr)

{

       *(volatile u32 __force *) addr = b;

}

 

在简略说说其他的定义

__safe特性声明该变量为安全变量,这是为了避免在内核函数未对传入的参数进行校验就使用的情况下,会导致编译器对其报错或输出告警信息。        通过该特性说明该变量不可能为空。

__force特性声明该变量是可以强制类型转换的。

__nocast声明该变量参数类型与实际参数类型要一致才可以。

__acquires为函数属性定义的修饰,表示函数内,该参数的引用计数值从1变为0

__releases__acquires相反,这一对修饰符用于Sparse在静态代码检测时,检查调用的次数和匹配请求,经常用于检测lock的获取和释放。

__acquire表示增加变量x的计数,增加量为1

__release表示减少变量x的计数,减少量为1。这一对与上面的那一对是一样,只是这一对用在函数的执行过程中,都用于检查代码中出现不平衡的状况。

 __cond_lock用于表示条件锁,当c这个值不为0时,计数值加1,并返回1

__chk_user_ptr__chk_io_ptr在这里只声明函数,没有函数体,目的就是在编译过程中Sparse能够捕捉到编译错误,检查参数的类型。

二.Dup系统调用

       fcntl.c中有dup2,事实上,许多函数的系统调用都在include/asm-generic/unistd.h中有对应的编号.

       Dup2用于文件流的重定向操作,

SYSCALL_DEFINE2(dup2, unsigned int, oldfd, unsigned int, newfd)

{

       Return sys_dup3;

}

实际上调用的是dup3,即

SYSCALL_DEFINE3(dup3, unsigned int, oldfd, unsigned int, newfd, int, flags)

       sys_dup3的主要操作就是根据fdtable将当前进程的所指向的fdtable进行expand操作。对于文件的结构不太清晰,待进一步的学习。      

三. Proc应用

       对于proc文件系统,一直没有用到,写驱动时用的都是sys,前段时间看了input子系统下proc的创建,随意记录一些。

 

       创建proc目录,proc_mkdir

       struct proc_dir_entry *proc_bus_input_dir

       proc_bus_input_dir=proc_mkdir”/bus/input”,NULL; //文件操作方法为NULL

 

       创建proc目录下的文件 proc_create

       Proc_create(“devices”,0,proc_bus_input_dir,&input_device_fileops);

       //proc_bus_input_dir为创建的文件所在的目录,“device”为proc文件名字,input_device_fileops为操作该文件的相应方法。文件相关的操作方法就不提了,具体的可以看input目录下input.c文件

 

       删除文件和目录

       Remove_proc_entry(“device,proc_bus_input_dir;

       Remove_proc_entry(“bus/input”,NULL);   

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值