移植xenomai到树莓派4B

内核版本: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设备也恢复了正常。

              

你可能感兴趣的:(内核,linux)