mailbox是kernel提供的一种板子上的硬件和soc通过messages queue,interrupt 进行通讯的一个架构。正式版的英文翻译如下: menuconfig MAILBOX bool "Mailbox Hardware Support" help Mailbox is a framework to control hardware communication between on-chip processors through queued messages and interrupt driven signals. Say Y if your platform supports hardware mailboxes. mailbox的实现分为contoller和client。简单的说就是clinet 可以通过controller提供的channle发送信息给conroller 因此在drivers/mailbox下实现的都是controller的源码 具体到某个厂商的硬件,则描述如下: config ARM_MHU tristate "ARM MHU Mailbox" depends on ARM_AMBA help Say Y here if you want to build the ARM MHU controller driver. The controller has 3 mailbox channels, the last of which can be used in Secure mode only. 通过makefile我们知道要实现mailbox的源文件其实只有两个 obj-$(CONFIG_MAILBOX)+= mailbox.o obj-$(CONFIG_ARM_MHU)+= arm_mhu.o 其中mailbox.c 是kernel提供的framework,arm_mhu.c 则是具体厂商的实现 这里直接看arm_mhu.c的probe函数 static int mhu_probe(struct amba_device *adev, const struct amba_id *id) { int i, err; struct arm_mhu *mhu; struct device *dev = &adev->dev; int mhu_reg[MHU_CHANS] = {MHU_LP_OFFSET, MHU_HP_OFFSET, MHU_SEC_OFFSET}; /* Allocate memory for device */ mhu = devm_kzalloc(dev, sizeof(*mhu), GFP_KERNEL); if (!mhu) return -ENOMEM; mhu->base = devm_ioremap_resource(dev, &adev->res); if (IS_ERR(mhu->base)) { dev_err(dev, "ioremap failed\n"); return PTR_ERR(mhu->base); } //mailbox的channel 表示可以发送信息的寄存器 for (i = 0; i < MHU_CHANS; i++) { mhu->chan[i].con_priv = &mhu->mlink[i]; mhu->mlink[i].irq = adev->irq[i]; mhu->mlink[i].rx_reg = mhu->base + mhu_reg[i]; mhu->mlink[i].tx_reg = mhu->mlink[i].rx_reg + TX_REG_OFFSET; } //初始化mbox的结构体 mhu->mbox.dev = dev; mhu->mbox.chans = &mhu->chan[0]; mhu->mbox.num_chans = MHU_CHANS; //mbox.ops 表示mailbox这个硬件具体的操作,例如发送数据,初始化等 mhu->mbox.ops = &mhu_ops; //发送数据采用poll的方式 mhu->mbox.txdone_irq = false; mhu->mbox.txdone_poll = true; mhu->mbox.txpoll_period = 1; amba_set_drvdata(adev, mhu); //所有的controller 最终都要通过mbox_controller_register 来注册自己 err = mbox_controller_register(&mhu->mbox); if (err) { dev_err(dev, "Failed to register mailboxes %d\n", err); return err; } dev_info(dev, "ARM MHU Mailbox registered\n"); return 0; } int mbox_controller_register(struct mbox_controller *mbox) { int i, txdone; //下面这四个任何一个为null,就退出注册 /* Sanity check */ if (!mbox || !mbox->dev || !mbox->ops || !mbox->num_chans) return -EINVAL; //client发送数据是通过poll的方式还是irq的方式,后面针对两种方式有不同的处理方式 if (mbox->txdone_irq) txdone = TXDONE_BY_IRQ; else if (mbox->txdone_poll) txdone = TXDONE_BY_POLL; else /* It has to be ACK then */ txdone = TXDONE_BY_ACK; //如果是poll的方式,则注册一个timer,定时查询 if (txdone == TXDONE_BY_POLL) { if (!mbox->ops->last_tx_done) { dev_err(mbox->dev, "last_tx_done method is absent\n"); return -EINVAL; } hrtimer_init(&mbox->poll_hrt, CLOCK_MONOTONIC, HRTIMER_MODE_REL); mbox->poll_hrt.function = txdone_hrtimer; } //初始化controller的channel,表示contoller 同时能尽量几路信息的传递 for (i = 0; i < mbox->num_chans; i++) { struct mbox_chan *chan = &mbox->chans[i]; chan->cl = NULL; chan->mbox = mbox; chan->txdone_method = txdone; spin_lock_init(&chan->lock); } if (!mbox->of_xlate) mbox->of_xlate = of_mbox_index_xlate; //所有的mailbox最终都会添加到mbox_cons 这个list中 mutex_lock(&con_mutex); list_add_tail(&mbox->node, &mbox_cons); mutex_unlock(&con_mutex); return 0; }