// 在内核中发起系统调用,执行本应用户空间发起调用的fops函数集,完成参数设置任务[luther.gliethttp]
int snd_pcm_kernel_ioctl(struct snd_pcm_substream *substream,
unsigned int cmd, void *arg)
{
mm_segment_t fs;
int result;
// get_fs()和set_fs()位于include/asm-generic/uaccess.h
《浅析get_fs()和set_fs()设置user用户空间所能访问的最大虚拟地址》 fs = snd_enter_user(); // 设置fs的addr_limit最大可访问地址为0xffffffff,而非原来正常的0xc0000000, 应用程序所能访问的最大虚拟地址[luther.gliethttp]
switch (substream->stream) {
case SNDRV_PCM_STREAM_PLAYBACK:
result = snd_pcm_playback_ioctl1(NULL, substream, cmd,
(void __user *)arg); // 执行用户空间的放音ioctl
break;
case SNDRV_PCM_STREAM_CAPTURE:
result = snd_pcm_capture_ioctl1(NULL, substream, cmd,
(void __user *)arg); // 执行用户空间的录音ioctl
break;
default:
result = -EINVAL;
break;
}
snd_leave_user(fs); // 恢复到user用户空间
return result;
}
阅读(1712) | 评论(0) | 转发(0) |