Hi All,
[TL;DR: Upstream u-boot uses DHCP instead of BOOTP, need to add DHCPACK in the BOOTP reply sent from BeagleBoot in order to get u-boot to respond to replies from BeagleBoot]
So I was investigating how to get BeagleBoot working with my BeagleLogic Standalone board in order to provide a way for users to flash the on board eMMC, and also as a way of fast prototyping of the bootloader changes I need to make for BeagleLogic standalone (instead of flashing the compiled u-boot into the SD card everytime I recompile it and then booting from it).
1. Compiling u-bootu-boot v2018.01 compiled with "am335x_evm_usbspl_defconfig", the SPL hung at "Trying to boot from USB Eth" and did not go to the BOOTP broadcast stage (
https://pastebin.com/MbKfB7bF)
I manually added the configuration options to am335x_evm_defconfig (
https://www.irccloud.com/pastebin/0MOcvEOA/) and after that got u-boot to the BOOTP broadcast stage as defined earlier.
However the issue was that now, BeagleBoot wasn't responding to BOOTP broadcast messages, although there were 17 of them sent.
Also, the VID and PID under which the AM335x re-enumerated wasn't according to the script. The VID/PID corresponding to the SPL should have been 0x0525/0xa4a2 but was actually 0x0451/0xD022 - again due to a change in the U-Boot's
ether.c driver which takes VID/PID from am335x_evm_defconfig (CONFIG_USB_GADGET_VENDOR_NUM and CONFIG_USB_GADGET_PRODUCT_NUM).
I put a console.log("Hello") statement in
main.js to confirm that the script was indeed receiving the packets, but was unable to respond to them. One of the reasons was that the request was not being identified correctly in
main.js ; the u-boot SPL was returning buff[4] = 0x82. After doing that, BeagleBoot started replying to the BOOTP requests, but the reply was not seen by u-boot.
To understand more, I decided to wiretap the packets using Wireshark.
2. Enter Wireshark
To see the packets in more detail, I used Wireshark to see the messages being broadcast - both by the AM335x Boot ROM (to which the script was responding well) and the U-Boot SPL. Here's the difference:
The same BOOTP request, in the Boot ROM appears as a BOOTP protocol request, while from the U-Boot SPL appears as a "DHCP Discover".
On further comparing the payload between the packets, I realized that the basic contents remain the same, while the only difference appears in the "vendor" field of the Packet, where there is a DHCP Message Type Field (53) - which leads to the difference.
Also on browsing through u-boot's sources -
bootp.c I found mentions to CONFIG_CMD_DHCP and how it was preferring selection over BOOTP in the code.
My first approach was to #undef CONFIG_CMD_DHCP in bootp.c so that the code will fall back to BOOTP and see if it responded to BeagleBoot. It indeed did, and after some modifications to main.js in BeagleBoot, it worked.
However, this approach was an ugly hack. I saw if I could do something better.
On reading the
state machine that runs the DHCP acceptance, I found that it checks for a DHCP ACK in state=REQUESTING. If this ACK is not received, it times out. This ACK not being sent from BeagleBoot was the main reason why it wasn't responding to messages.
In order to send the ACKs from BeagleBoot it was necessary to revise the script that sends the BOOTP packet. So in
protocols.js, I added code towards the end of the function to add DHCPACK in the vendor field of the packet.
On the BeagleBoot side,
https://pastebin.com/8CC7qtm1 . The only thing being that the progress crosses 100% because of an extra BOOTP reply that needs to be sent.
[To Ravi:] I'll send a pull request for the changes I made tomorrow - you may want to keep this changes on another branch and merge it into master later.
I hope this will be a useful record for anyone else who stumbles on this.
Thanks,
Abhishek