在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协议要快很多。