内核版本:4.19.122
Xenomai版本:3.1
IPIPE版本:ipipe-core-4.19.115-arm64-6.patch
步骤:
1,git clone https://github.com/raspberrypi/linux.git (最好加上--depth=1,否则时间会很长)
2,打ipipe patch
patch -p1 < ../ipipe-core-4.19.115-arm64-6.patch
会有几个小冲突,但比较容易解决,至少比之前在firefly上移植4.4版的ipipe要简单的多了。
3,xenomai patch
./xenomai/scripts/prepare-kernel.sh --arch=arm64 --linux=rpi-kernel
4,配置和编译内核:
1)make bcm2711_xeno_defconfig
2)关闭cpu idle, cpu freq,CMA,migrate,hugepage等
3)make -jX
问题:
编好内核之后,启动的时候会出现两个warning,我们逐一进行分析
1,MSI domain irqchip Brcm_MSI is not pipeline-safe!
[ 0.472771] MSI domain irqchip Brcm_MSI is not pipeline-safe! [ 0.472811] WARNING: CPU: 2 PID: 1 at kernel/irq/msi.c:273 msi_create_irq_domain+0x198/0x1a0 [ 0.478115] Modules linked in: [ 0.480780] CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.19.122-v8-xeno+ #5 [ 0.483509] Hardware name: Raspberry Pi 4 Model B Rev 1.2 (DT) [ 0.486246] I-pipe domain: Linux [ 0.488976] pstate: 60000005 (nZCv daif -PAN -UAO) [ 0.491664] pc : msi_create_irq_domain+0x198/0x1a0 [ 0.494387] lr : msi_create_irq_domain+0x198/0x1a0 [ 0.497055] sp : ffffff800802bac0 [ 0.499709] x29: ffffff800802bac0 x28: ffffffc07d72dc10
这个问题,我们首先找到名为Brcm_MSI的irq_chip,在bdrivers/pci/controller/pcie-brcmstb.c定义:
static struct irq_chip brcm_msi_irq_chip = {
.name = "Brcm_MSI",
.irq_mask = pci_msi_mask_irq,
.irq_unmask = pci_msi_unmask_irq,
+ .flags = IRQCHIP_PIPELINE_SAFE,
};
看了一下系统其他的irq_chip,都要声明IRQCHIP_PIPELINE_SAFE,所以这个告警就消失了。
这个告警不会影响内核,但我对待内核日志中的告警,通常还是尽量去解决掉的。
2,irq 38 handler xhci_msi_irq+0x0/0x30 enabled interrupts,检测到没有关中断,这个问题不只是一个warning,同时会影响系统的使用,插拔usb设备后,系统会死机
[ 0.673365] usb usb2: New USB device found, idVendor=1d6b, idProduct=0003, bcdDevice= 4.19 [ 0.675519] irq 38 handler xhci_msi_irq+0x0/0x30 enabled interrupts [ 0.678105] usb usb2: New USB device strings: Mfr=3, Product=2, SerialNumber=1 [ 0.680790] WARNING: CPU: 0 PID: 0 at kernel/irq/handle.c:153 __handle_irq_event_percpu+0x2b8/0x2d0 [ 0.683378] usb usb2: Product: xHCI Host Controller [ 0.686064] Modules linked in: [ 0.686082] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 4.19.122-v8-xeno+ #6 [ 0.686089] Hardware name: Raspberry Pi 4 Model B Rev 1.2 (DT) [ 0.686096] I-pipe domain: Linux [ 0.686108] pstate: 80000005 (Nzcv daif -PAN -UAO) [ 0.688767] usb usb2: Manufacturer: Linux 4.19.122-v8-xeno+ xhci-hcd [ 0.691322] pc : __handle_irq_event_percpu+0x2b8/0x2d0 [ 0.694056] usb usb2: SerialNumber: 0000:01:00.0 [ 0.696702] lr : __handle_irq_event_percpu+0x2b8/0x2d0 [ 0.696709] sp : ffffff8008003da0 [ 0.696717] x29: ffffff8008003da0 x28: ffffffc07c6f2880 [ 0.696734] x27: ffffffc07c386000 x26: ffffff8008cd8000
IPIPE对中断体系做了比较大的修改,所以无论是中断处理还是开关中断都和标准linux有很大的区别,先看一下告警的产生:if WARN_ONCE(!irqs_disabled(),"irq %u handler %pF enabled interrupts\n", irq, action->handler))
判断irqs_disabled的逻辑会一直走到ipipe_test_root,并在这个函数中检测__ipipe_root_status的IPIPE_STALL_FLAG
那么内核何时设置__ipipe_root_status?
咨询了一下xenomai社区,社区回复说目前还没有人在rpi 4b上成功移植xenomai,所以竟然成了全球第一(肯定有人已经移植了,只是没有公布而已)
社区没有帮助,自己也没有头绪,胡乱改了几个brcm_msi_irq_chip中的irq_mask, irq_unmask之后,并没有成功。
再看一遍log:
[ 0.756470] __handle_irq_event_percpu+0x2b8/0x2d0 [ 0.758914] handle_irq_event_percpu+0x40/0x98 [ 0.761365] handle_irq_event+0x50/0x80 [ 0.763801] handle_simple_irq+0xb4/0x118 [ 0.766221] generic_handle_irq+0x34/0x50 [ 0.768640] brcm_pcie_msi_isr+0xac/0x1a8 [ 0.771078] __ipipe_dispatch_irq+0x180/0x1c8 [ 0.773494] __ipipe_grab_irq+0x6c/0xa8 [ 0.775910] gic_handle_irq+0x60/0xb0 [ 0.778301] handle_arch_irq_pipelined+0x28/0x78 [ 0.780675] el1_irq+0xc0/0x160
发现brcm_pcie_msi_isr处理过程中,还是标准的处理,并没有对ipipe做适配,也就是想社区讲的,还没有人做这件事,所以在ipipe-core-4.19.115-arm64-6.patch也没有相应的代码。
修改:
在ipipe打开的情况下,需要将generic_handle_irq替换为ipipe_handle_demuxed_irq(irq_linear_revmap(msi->inner_domain, hwirq));,修改如下:
/* Account for legacy interrupt offset */
hwirq = bit - msi->intr_legacy_offset;
-
+#ifdef CONFIG_IPIPE
+ ipipe_handle_demuxed_irq(irq_linear_revmap(msi->inner_domain, hwirq));
+#else
virq = irq_find_mapping(msi->inner_domain, hwirq);
if (virq) {
if (msi->used & (1 << hwirq))
@@ -955,6 +957,7 @@ static void brcm_pcie_msi_isr(struct irq_desc *desc)
/* Unknown MSI, just clear it */
dev_dbg(dev, "unexpected MSI\n");
}
+#endif
修改之后,在xhci_msi_irq中断处理过程中,__ipipe_root_status会被正确置位,插拔usb设备也恢复了正常。