RPI: 一个适合RASPBERRY PI ZERO W的u-boot

在u-boot的主线版本上,似乎还没有出现一个可以将Raspberry Pi Zero或者Raspberry Pi Zero W的USB接口当成slave使用的版本。我们需要一个这样的版本,能通过USB接口访问fastboot服务的版本,这样就可以很方便地将系统镜像写入到SD卡中。

 

  • 调试u-boot的方法

由于在开发阶段,为了很方便地验证编译出来的二进制文件能不能正常使用。同时为了尽可能地避免插拔SD卡,有两种方法:

1。 使用官方的usbboot工具 https://github.com/raspberrypi/usbboot

在Ubuntu 16.04系统上很容易就可以从源代码中编译出来。这里选用的版本为:

commit 2989957c0ff2f503fa5c28f309d48fb1b1eeb9fa
Author: Tim Gover <990920+timg236@users.noreply.github.com>
Date:   Fri Dec 13 09:21:54 2019 +0000

    Fix serial check for BCM2711 (#46)
    
    The second stage can/will support file-server so don't force
    bootcode.bin for 2711. The second stage will (probably) reply
    with SerialNumber==1 when it wants the file-server as on Pi3.

通过-v参数,可以很方便地看到,在树莓派开机的时候需要哪些文件

同时,由于u-boot需要额外的env配置文件,但是这个方法无法做到加载这些额外的文件

2。使用类似于双系统的方法:

待调试的u-boot文件放在第二个fat分区,这个分区上的文件可以通过第一个fat分区引导的系统进行更新。同时,要执行第二个系统通过如下方法进入:

https://github.com/raspberrypi/noobs/blob/master/recovery/main.cpp

void showBootMenu(const QString &drive, const QString &defaultPartition, bool setDisplayMode)
{
    QByteArray reboot_part;
#ifdef Q_WS_QWS
    QWSServer::setBackground(BACKGROUND_COLOR);
    QWSServer::setCursorVisible(true);
#endif
    BootSelectionDialog bsd(drive, defaultPartition);
    if (setDisplayMode)
        bsd.setDisplayMode();
    bsd.exec();

    // Shut down networking
    QProcess::execute("ifdown -a");
    // Unmount file systems
    QProcess::execute("umount -ar");
    ::sync();
    // Reboot
    reboot_part = getFileContents("/run/reboot_part").trimmed();
    ::syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, reboot_part.constData());
}

 

  • 源代码

为了能够用于启动Android系统,这里选用的是AOSP上的代码

commit 8511c75bb4fe3ec225dad073208d17aa71330e8e
Author: Tristan Muntsinger <muntsinger@google.com>
Date:   Fri Jan 3 15:15:00 2020 -0800

    ANDROID: Enable Rockchip GPIO command
    
    This enables the Rockchip GPIO command in U-Boot with
    the intent for it to be used to toggle the PoE
    (Power-over-Ethernet) fan.
    
    Bug: 147114554
    Test: local build and boot
    Signed-off-by: Tristan Muntsinger <muntsinger@google.com>
    Change-Id: I1a46c5405bd960f32ed88c79aaf9aeb679069f4c

 

  • 使其支持USB slave模式

虽然官方的代码没有支持USB slave模式,但要让Raspberry Pi Zero W支持USB slave模式还是很简单的,只需要修改下面几行代码:

diff --git a/drivers/usb/gadget/dwc2_udc_otg.c b/drivers/usb/gadget/dwc2_udc_otg.c
index 35f4147..a54ff43 100644
--- a/drivers/usb/gadget/dwc2_udc_otg.c
+++ b/drivers/usb/gadget/dwc2_udc_otg.c
@@ -1093,6 +1093,11 @@ static void dwc2_set_stm32mp1_hsotg_params(struct dwc2_plat_otg_data *p)
                p->usb_gusbcfg |= 1 << 30; /* FDMOD: Force device mode */
 }
 
+static void dwc2_set_bcm2835_hsotg_params(struct dwc2_plat_otg_data *p)
+{
+       p->usb_gusbcfg = MODE_DMA;
+}
+
 static int dwc2_udc_otg_reset_init(struct udevice *dev,
                                   struct reset_ctl_bulk *resets)
 {
@@ -1215,6 +1220,8 @@ static const struct udevice_id dwc2_udc_otg_ids[] = {
        { .compatible = "snps,dwc2" },
        { .compatible = "st,stm32mp1-hsotg",
          .data = (ulong)dwc2_set_stm32mp1_hsotg_params },
+       { .compatible = "brcm,bcm2835-usb",
+         .data = (ulong)dwc2_set_bcm2835_hsotg_params },
        {},
 };

 

当然让它能跑USB slave模式,最主要的原因,当然是让fastboot跑在USB模式,这样就可以通过USB接口刷镜像文件了。从当前的测试来看,在USB slave模式下,数据的下载速率可以达到16MB, 比跑百兆网口的udp协议要快很多。

 

发表评论

电子邮件地址不会被公开。 必填项已用*标注