Open fonix232 opened 5 months ago
Hi I thinks this is already done in #20 see https://github.com/superna9999/pyamlboot/pull/20/commits/d8d772d89527c669d24db16b91c5228dae9e74a4
@superna9999 I agree, it looks okay on first blink. However, given how much data is being transferred, to avoid hanging, I think it would be better for both ReadMedia and WriteMedia if they did a batched approach for continuous progress update - basically, replacing epin.read(size, timeout).tobytes()
and epout.write(data, 1000)
with smaller entries, similarly to how the update
utility does:
mread
: https://github.com/yangfl/update/blob/master/update.cpp#L1271-L1288mwrite
: https://github.com/yangfl/update/blob/master/update.cpp#L1221-L1245With the main difference being that we wouldn't need to re-issue the control messages (self.dev.ctrl_transfer calls in the PR you linked), but only the bulk read/write part would need to repeat.
But otherwise this marginal nitpick, the code looks good, and seems to match precisely what's happening in the update tool!
Many have been tinkering with the Spotify CarThing (codename
superbird
), an Amlogic S905D2 based device. @bishopdynamics has created a cross-platform tool wrappingpyamlboot
to simplify a lot of the processes (dumping and restoring devices to specific firmware versions, enabling ADB and custom ROMs, etc.), however this tool, at the moment is somewhat limited in speed due to the indirect approach needed - instead of being able to read the attached storage (media) directly, it needs to instruct the device to read chunks of the partitions into RAM, then transfer those chunks to the host. This has a very limited read and write bandwidth - a few hundred KBps for read, and around 1.5MBps for writing. Simply said, dumping a device can take hours, which is really suboptimal.However, the semi-official
update
utility, which is sadly not cross platform, has a much faster option for both writing and reading, themread
andmwrite
methods.Fortunately, there's an older version of the
update
utility where the source code is available: https://github.com/yangfl/update/This source code defines both
mread
andmwrite
quite well:mread
function: https://github.com/yangfl/update/blob/master/update.cpp#L797-L830mwrite
function: https://github.com/yangfl/update/blob/master/update.cpp#L199-L316By the looks of it, the process is quite straightforward - I'll do
mread
as I'm more familiar with it, still need to dig throughmwrite
properly.mread
, the parameters (store or read into memory, partition name, file type (alwaysnormal
), and read size) are assignedbulkcmd update [storeOrMemory] [partition] [fileType] [readSize in hex]
ReadMediaFile
is called, with the optional output file name (empty if reading into memory) and sizeReadMediaFile
prepares the output file, then begins callingAmlReadMedia
with 0x10000L chunks read into buffer]AmlReadMedia
further sanitises its input, then callsReadMediaCMD
to send the instruction to the device to read the chunkReadMediaCMD
is a bit convoluted, but it generally sends a USB control message and checks the output (https://github.com/yangfl/update/blob/master/AmlLibusb/AmlLibusb.cpp#L168-L191)ReadMediaCMD
is finished, a bulk USB read happens into the provided buffer (https://github.com/yangfl/update/blob/master/AmlLibusb/AmlLibusb.cpp#L282-L293)mwrite
is mostly the same, with some intermittent bulkcmd's checking the status and verifying the download (I'm guessing some light checksums of blocks).Would it be possible to implement this in
pyamlboot
? I'd gladly do it myself, however neither my C++ nor my Python knowledge is on a level where I'd feel certain my efforts aren't pointless or downright dangerous.