原文链接:https://blog.csdn.net/yangguoyu8023/article/details/122114620
1. alsa_sound_init
alsa的核心入口函数是sound\core\sound.c中的alsa_sound_init
static struct snd_minor *snd_minors[SNDRV_OS_MINORS];
static int snd_open(struct inode *inode, struct file *file)
{
unsigned int minor = iminor(inode);
struct snd_minor *mptr = NULL;
const struct file_operations *new_fops;
mptr = snd_minors[minor];
.......
new_fops = fops_get(mptr->f_ops);
.....
if (file->f_op->open)
err = file->f_op->open(inode, file);
}
static const struct file_operations snd_fops =
{
.open = snd_open,
.llseek = noop_llseek,
};
static int major = CONFIG_SND_MAJOR;
static int __init alsa_sound_init(void)
{
snd_major = major;
snd_ecards_limit = cards_limit;
if (register_chrdev(major, "alsa", &snd_fops))
}
subsys_initcall(alsa_sound_init);
1.1 snd_minors
最终会通过次设备号来匹配snd_minors,并且调用它的open函数。我们看看全局变量snd_minors在哪注册的,它是静态变量,所以在sound.c文件中搜索,发现其注册为snd_register_device。
/**
* snd_register_device - Register the ALSA device file for the card
*/
int snd_register_device(int type, struct snd_card *card, int dev,
const struct file_operations *f_ops,
void *private_data, struct device *device)
{
int minor;
struct snd_minor *preg;
preg = kmalloc(sizeof *preg, GFP_KERNEL);
preg->type = type;
preg->card = card ? card->number : -1;
preg->device = dev;
preg->f_ops = f_ops;
preg->private_data = private_data;
preg->card_ptr = card;
minor = snd_find_free_minor(type, card, dev);
device->devt = MKDEV(major, minor);
err = device_add(device);
snd_minors[minor] = preg;
}
1.2 snd_register_device
搜索snd_register_device,看谁调用了该函数,发现有如下函数调用了。
snd_pcm_dev_register
snd_ctl_dev_register