linux ioct 地址,【转】 linux2.6内核compat_ioct/unlock_ioctll函数

【转】 linux2.6内核compat_ioct/unlock_ioctll函数

(2011-09-15 07:17:49)

标签:

杂谈

The ioctl() system call has long been out of favor among the

kernel developers, who see it as a completely uncontrolled entry

point into the kernel. Given the vast number of applications which

expect ioctl() to be present, however, it will not go away anytime

soon. So it is worth the trouble to ensure that ioctl() calls are

performed quickly and correctly - and that they do not

unnecessarily impact the rest of the system.

ioctl() is one of the remaining parts of the kernel which runs

under the Big Kernel Lock (BKL). In the past, the usage of the BKL

has made it possible for long-running ioctl() methods to create

long latencies for unrelated processes. Recent changes, which have

made BKL-covered code preemptible, have mitigated that problem

somewhat. Even so, the desire to eventually get rid of the BKL

altogether suggests that ioctl() should move out from under its

protection. Simply removing the lock_kernel() call before calling

ioctl() methods is not an option, however. Each one of those

methods must first be audited to see what other locking may be

necessary for it to run safely outside of the BKL. That is a huge

job, one which would be hard to do in a single "flag day"

operation. So a migration path must be provided. As of 2.6.11, that

path will exist. The patch (by Michael s. Tsirkin) adds a new

member to the file_operations structure: If a driver or filesystem

provides an unlocked_ioctl() method, it will be called in

preference to the older ioctl(). The differences are that the inode

argument is not provided (it's available as

filp->f_dentry->d_inode) and the BKL

is not taken prior to the call. All new code should be written with

its own locking, and should use unlocked_ioctl(). Old code should

be converted as time allows. For code which must run on multiple

kernels, there is a new HAVE_UNLOCKED_IOCTL macro which can be

tested to see if the newer method is available or not. Michael's

patch adds one other operation: If this method exists, it will be

called (without the BKL) whenever a 32-bit process calls ioctl() on

a 64-bit system. It should then do whatever is required to convert

the argument to native data types and carry out the request. If

compat_ioctl() is not provided, the older conversion mechanism will

be used, as before. The HAVE_COMPAT_IOCTL macro can be tested to

see if this mechanism is available on any given kernel. The

compat_ioctl() method will probably filter down into a few

subsystems. Andi Kleen has posted patches adding new compat_ioctl()

methods to the block_device_operations and scsi_host_template

structures, for example, though those patches have not been merged

as of this writing. 1、内核本型(linux2.6.28-7)

long (*compat_ioctl)(struct tty_struct *tty, struct file *

file,

unsigned int cmd, unsigned long arg);

implement ioctl processing for 32 bit process on 64 bit

system

Optional

2、What is compat_ioctl Consider a scenario where application is

32 bit and kernel as well as architecture is 64 bit. In this case,

when an application calls ioctl(), there should be some mechanism

in kernel to handle 32 bit to 64 bit conversion. This conversion is

especially required when user passes objects of type "long" and

"void *". There is one more method called as "compat_ioctl()" that

a 64 bit driver has to implement. It gets called when 64 bit kernel

gets ioctl() call from 32 bit user. Tasks to be done by

compat_ioctl() : 1. Acquire BKL, since kernel calls compat_ioctl

without BKL.

2. 32 to 64 bit conversion for long and pointer objects passed by

user

3. Process input data, get results.

4. 64 to 32 bit conversion in order to pass the output data back

to user

5. Release BKL 3、中文档案 前段时分将我们的法氏破植到Mips64的Linux

2.6环境下,做可止性真验。

因为映雩态程法式范围太除夜,而且之前出有对64bit的环境做思索,

所以,映雩态法式任然操做32位情势编译,内核匝弄正在64bit。

我们有一个内核模块之前是正在2.4.21下的,拿到2.6后,把部门api做了些变动,直接编译并减载。

映雩态法式正在挪用ioctl的时间,老是掉踪败。

dmesg看一下内核疑息,有以下远似疑息:

ioctl32(add_vopp:9767): Unknown cmd fd(3) cmd(f00){00}

arg(ff240ae0)

后去正在内核中的ioctl中增减debug代码,收现根柢出挪用到内核中的ioctl函数。

经过查赵冬收现了以下本钱

The new way of ioctl()

32 bit user/64 bit kernel

What is compat_ioctl ()

more on compat_ioctl

产死标题成绩的阐收:

我们的法式经过进程Linux的

ssize_t read(int fd, void *buf, size_t count);

体系挪用从真拟设备中读与内核中。

操做

int ioctl(int fd, int request, ...);

体系挪雍么对设备遏制节制,并通报一些数据。

ioctl是我们扩年夜非尺度体系挪用的足腕。

read体系挪用,对应内核中struct file_operations 挨算中的

ssize_t (*read) (struct file *filp, char *buf, size_t count,

loff_t *f_pos)

当映雩态位32bit, 内核位64bit的时间,

映雩态的法式,战内核态的法式,正在数据范例纷歧致。

好比指针本文章转载街梦网http://www.hiphopjw.com/,映雩态的指针真践沙虑unsigned long

4Byte

内核态的指针是unsigned ong: 8Byte.

对那类纷歧致,从映雩态陷进内核态的时间,除夜部门尺度挪用的参数已做了吸应的转化。

没有存正在标题成绩。好比ssize_t,内核态战映雩态纷歧致,

对那类已知范例,内核代码已做裂弄换,因为他知讲该如何转,

所以我们的法首悴用read,write,等体系挪用,皆能细确的返回成果。

再去吭哟ioctl体系挪用,

映雩态体系挪用,int ioctl(int fd, int request, ...);

内核中对应的函数

int (*ioctl) (struct inode *inode, struct file *filp, unsigned

int cmd, unsigned long arg)

request是要供号,雍么辩黑没有开得到要供。新闻后里的可变参数随便选。

假定念传进或传出自定义挨算,可以或许传个指针范例。

假定出数据通报,可以或许空着。

虽然也能够或许传阿谁int或char之类的范例去背内褐Ж报数据。

标题成绩去了,内核没有知讲您通报的是那种范例,他出法给您转化。

总结一下:

1). Linux2.6对64bit kernel 正在struct file_operation中删减了一个成员

long (*compat_ioctl) (struct file *filp, unsigned int cmd,

unsigned long arg);

雍么供给32位映雩态法式的格式,

可以或许经过进程HAVE_COMPAT_IOCTL宏去审定该成员是没有是存正在,并供给吸应的操纵格式。

2). 战int (*ioctl) (struct inode *inode, struct file *filp,

unsigned int cmd, unsigned long arg)相比

compat_ioctl少了inode参数,

可以或许经过进程filp->f_dentry->d_inode格式得到。

3). 闭于ioctl的要供号,常常是经过进程宏界讲天撕媚 举例以下:

#define IoctlGetNetDeviceInfo _IOWR(Ioctl_Magic, 1,

struct_NetDeviceInfo)

#define IoctlNetQueueInit _IOR(Ioctl_Magic, 4,

struct_NetDeviceListen)

#define IoctlNetQueueDestroy _IO(Ioctl_Magic, 5)

寄看_IOWR战IOR宏, 他们的末了一个参数是一个数据范例,展开时会搜罗sizeof()操纵,

果此32bit映雩态法式战64bit内核之间,天撕媚ioctl的request号很可以或许便会没有开,

正在compat函数中switch()的时间,便会switch没有到。

要念格式停止:

供给64bit战32bit除夜小分歧的挨算。

正在映雩态下供给一个真挨算,真挨算战内核内的挨算宽度分歧。

用_IO宏,而没有用_IOWR或_IOR宏,回正只是为了得到一个号码,真践传输数据除夜小,自己心秘密有,内核代码措置好便好了。

4). 假定compat支到的末了参数arg是一个映雩态指针, 它正在映雩态是32位的,正在内核中为了包管安然,

可操做compat_ptr(art)宏将其安然的转化为一个64位的指针(仍旧是映雩指针)

分享:

a4c26d1e5885305701be709a3d33442f.png喜欢

0

a4c26d1e5885305701be709a3d33442f.png赠金笔

加载中,请稍候......

评论加载中,请稍候...

发评论

登录名: 密码: 找回密码 注册记住登录状态

昵   称:

评论并转载此博文

a4c26d1e5885305701be709a3d33442f.png

发评论

以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值