Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fel: Try to detect VM environments and print a warning for those #98

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions fel.c
Original file line number Diff line number Diff line change
Expand Up @@ -1069,6 +1069,17 @@ int main(int argc, char **argv)
if (*argv[i] == '-')
pr_fatal("Invalid option %s\n", argv[i]);

/* Check for virtual machine */
const char *emulation = fel_check_vm();
if (emulation) {
/* print a warning message, but otherwise try to continue normally */
printf("Virtual machine detected! (%s)\n\n", emulation);
printf("The FEL protocol (handler in the BROM) is not very robust. Trying to use it\n"
"via emulated USB is known to be problematic on some virtual machines. If you\n"
"insist on doing this, expect spurious errors due to timing issues etc. These\n"
"do _not_ mean that sunxi-fel is at fault, and it can't do anything about it.\n\n");
}

/* Process options that don't require a FEL device handle */
if (device_list)
felusb_list_devices(); /* and exit program afterwards */
Expand Down
44 changes: 44 additions & 0 deletions fel_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -820,3 +820,47 @@ feldev_list_entry *list_fel_devices(size_t *count)
if (count) *count = devices;
return list;
}

/*
* Check for virtual machine (USB emulation). The FEL protocol is rather
* sensitive to errors and timing issues, so such environments are known
* to NOT work well with sunxi-fel.
*
* Returns either NULL (if no virtual machine could be detected), or a string
* pointer that identifies the environment. (e.g. "VirtualBox", "VMware", ...)
*/
const char *fel_check_vm(void) {
const char *result = NULL;

ssize_t rc;
libusb_context *ctx;
libusb_device **usb;
struct libusb_device_descriptor desc;

libusb_init(&ctx);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to check for error code from libusb_init() too? http://libusb.sourceforge.net/api-1.0/group__lib.html#ga9517c37281bba0b51cc62eba728be48b

rc = libusb_get_device_list(ctx, &usb);
if (rc < 0)
usb_error(rc, "libusb_get_device_list()", 1);

// iterate over device descriptors, checking their vendor IDs
while (--rc >= 0) {
libusb_get_device_descriptor(usb[rc], &desc);
switch (desc.idVendor) {
case 0x0E0F:
result = "VMware";
break;
case 0x15AD:
result = "VMware";
break;
case 0x80EE:
result = "VirtualBox";
break;
}
if (result)
break; // exit while loop
}
libusb_free_device_list(usb, true);
libusb_exit(ctx);

return result;
}
3 changes: 3 additions & 0 deletions fel_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,7 @@ void fel_clrsetbits_le32(feldev_handle *dev,
bool fel_get_sid_root_key(feldev_handle *dev, uint32_t *result,
bool force_workaround);

/* check for virtual machine (USB emulation) */
const char *fel_check_vm(void);

#endif /* _SUNXI_TOOLS_FEL_LIB_H */