Skip to content

feat: load firmware over SysEX - #295

Merged
jamiefaye merged 2 commits into
SynthstromAudible:communityfrom
bfredl:xload
Aug 17, 2023
Merged

jamiefaye merged 2 commits into
SynthstromAudible:communityfrom
bfredl:xload

Conversation

@bfredl

@bfredl bfredl commented Aug 3, 2023

Copy link
Copy Markdown
Collaborator

Need to clean up this mess but can somewhat reliably load a new firmware image over the existing one over USB in ~3.5 seconds.

@jamiefaye

Copy link
Copy Markdown
Collaborator

Could this be used as an attack vector? At one point, you needed to run from a https:// in order to get to SysEx from a web browser. Not sure if that rule is still in effect.

@bfredl

bfredl commented Aug 3, 2023 •

Copy link
Copy Markdown
Collaborator Author

yes, it is going to need a community feature setting which is off by default.

The browser is supposed to ask the user for giving the client permission to send sysex, but there are other access points so it's safest to opt-in from the deluge side as well.

@jamiefaye

Copy link
Copy Markdown
Collaborator

Having a Community Feature setting sounds like a good way to cover this.

This can speed-up development too. It takes 40 or more seconds to transfer an image via JLink.

@soymonitus

Copy link
Copy Markdown
Collaborator

You can't imagine how much time I invest in mounting, copying, unmounting, inserting card, .... This is going to be a huge improvement for development

@seangoodvibes

Copy link
Copy Markdown
Collaborator

Ahhh this is going to be amazing for building ... so much time invested in removing / inserting my SD cards ... my hand was feeling pain at one point lol.

@m-m-adams

Copy link
Copy Markdown
Collaborator

Thanks, gonna start working on deluge ransomware shortly

Although in practice at least in firefox it's https only and permissions are per site (and a seperate permission for sysex), so it'd depend on how much you trust people not to grant access to random websites

@bfredl
bfredl force-pushed the xload branch 2 times, most recently from 259ae00 to 32541fa Compare August 4, 2023 17:52
@bfredl

bfredl commented Aug 4, 2023

Copy link
Copy Markdown
Collaborator Author

Added a community setting feature, RCE is now disabled by default.

There is also a random 31-bit identifier generated when you enable it (persistent across reboots), which you have to supply when loading from a computer. It is nowhere near cryptographically secure (it is not like the full MIDI/driver stack has been audited/fuzzed for untrusted data anyway..), but at least you cannot just send a single non-specific and obvious MIDI message to get an unknown (but possibly dev-enabled) deluge to execute some code. It also helps to avoid mistakes (it is a way to say "trust me, I am a dev, I know what I am doing")

@soymonitus

Copy link
Copy Markdown
Collaborator

How do you supply the 31-bit identifier? I have the app SySex Librarian in mac that allows you to load a .syx message and transfer it to any USB midi device connected. How is it going to work for the .bin files? is there going to be a modified build process that also outputs a .syx file?

@bfredl
bfredl force-pushed the xload branch 2 times, most recently from 7c267e8 to 0bd8e8e Compare August 6, 2023 09:08
@bfredl

bfredl commented Aug 6, 2023

Copy link
Copy Markdown
Collaborator Author

@soymonitus so far there is a source code program included as contrib/load/loadfw.c which can convert to .syx on any platform (as well as send directly on linux using ALSA).

Need to figure out the best way to integrate client code in the build system as we yet don't assume any host c compiler. Perhaps binaries could be included as part of the binary toolchain.

@bfredl
bfredl force-pushed the xload branch 3 times, most recently from 2b11203 to 763bbb1 Compare August 7, 2023 10:49
@bfredl
bfredl marked this pull request as ready for review August 7, 2023 11:21

@sapphire-arches sapphire-arches left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Really looking forward to having this, major quality of life improvement possible. Some minor comments but mostly LGTM

disableTimer(TIMER_SYSTEM_FAST);
disableTimer(TIMER_SYSTEM_SUPERFAST);

auto ptr = (void (*)(uint32_t, uint32_t, uint32_t, char*))funcbuf;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Strictly speaking we should probably issue a IMB (instruction memory barrier) prior to jumping off in to the great beyond here. That would avoid the need for writing through the UNCACHED_MIRROR_OFFSET above I think.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I've spent quite a long time going through all ARM guides about self-modifiying code and tried all the standard options which "are supposed to" work. The renesas implementation of the arm cache hierarchy (and the co-processors as documented in the armv7a manual) simply does not follow the ARM documentation and none of the standard rules apply. UNCACHED_MIRROR_OFFSET as suggested by rohan does work though, which is why the code uses it.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

argh, thats annoying but not really as surprising as I would like it to be. perhaps manually poking some of the cache management registers would work but we can ship this for now.

Comment thread src/deluge/util/pack.c
}

// Return the CRC of the bytes buf[0..len-1].
uint32_t get_crc(uint8_t* buf, int len) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

FatFS and sd_util.c already have CRC implementations, can we reuse one of those?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

maybe, but the idea is that this file pack.c is self-contained as it is meant to be used both by the deluge and client software. Also I could remember wrong, but those used the slow naive method instead of the table method so I think those could reuse this rather than the other way around.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No problem, it's quite small.

return; // Do not do that
}
// data[4]: reserved, could serve as a message identifier to filter messages per category
uint8_t reply_hdr[5] = {0xf0, 0x7d, 0x03, 0x40, 0x00};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we can use the shiny new official sysex ID here, no? (00H 21H 7BH)

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

yes, but that would be a separate PR which modifies everything. My idea was to let the unofficial prefix namespace grow "organically" (ie into a big mess) as we add functionality for some more time. And later do a restructure of the messages at the same time we switch to the new prefix.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Sounds good, thanks.

return; // Do not do that
}
// data[4]: reserved, could serve as a message identifier to filter messages per category
uint8_t reply_hdr[5] = {0xf0, 0x7d, 0x03, 0x40, 0x00};

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Sounds good, thanks.

disableTimer(TIMER_SYSTEM_FAST);
disableTimer(TIMER_SYSTEM_SUPERFAST);

auto ptr = (void (*)(uint32_t, uint32_t, uint32_t, char*))funcbuf;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

argh, thats annoying but not really as surprising as I would like it to be. perhaps manually poking some of the cache management registers would work but we can ship this for now.

Comment thread src/deluge/util/pack.c
}

// Return the CRC of the bytes buf[0..len-1].
uint32_t get_crc(uint8_t* buf, int len) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

No problem, it's quite small.

@jamiefaye

Copy link
Copy Markdown
Collaborator

I suggest we leave this one out of the first community release. We can put it in when we have some facility on the user-side (like a web application) that makes use of it. A "feature flag" could handle this.

@bfredl

bfredl commented Aug 8, 2023

Copy link
Copy Markdown
Collaborator Author

I was thinking a native utility as well which could be made an (optional) step in the build system.

Currently I do ./dbt build oled debug && ./loadfw hw:2,0,2 1234abcd build/Debug/delugeOLED.bin with my (so-far linux only) c utility which is a completely different experience than from before.

A "feature flag" could handle this.

you mean like a preprocessor macro which is not defined by default but can be supplied on the cmdline, like is done in the wren PR? I could do that.

@jamiefaye

Copy link
Copy Markdown
Collaborator

A Wren-like preprocessor macro sounds good.

@jamiefaye

Copy link
Copy Markdown
Collaborator

I would like to see a Javascript library for calling SysEx. It may already exist. Then we could even have a "flash from the web" facility.

@PaulFreund

Copy link
Copy Markdown
Collaborator

I suggest we leave this one out of the first community release. We can put it in when we have some facility on the user-side (like a web application) that makes use of it. A "feature flag" could handle this.

Is there a reason you don't want to include this? I would like to have it in the first release so it is "connectivity ready" as some vendors call it. Once we get the webpage to a point where it allows easy update with firmware selection I'd like the community deluges to be ready for that and not wait until the next release that people need to install manually again

@bfredl

bfredl commented Aug 9, 2023

Copy link
Copy Markdown
Collaborator Author

I hope to get the javascript stuff in order and upstream it into this repo quite soon. Although next week might be more realistic than this week.

@bfredl

bfredl commented Aug 11, 2023

Copy link
Copy Markdown
Collaborator Author

Added a compile time flag ENABLE_SYSEX_LOAD . it is currently OFF by default but we could change it to ON before the beta release if we so want.

@bfredl
bfredl force-pushed the xload branch 2 times, most recently from 2063712 to 045dfe2 Compare August 12, 2023 09:50
@PaulFreund

Copy link
Copy Markdown
Collaborator

I have another reason to put this in the firmware. The bootloaders up to version 5 can break with 0 byte firmware images. If we allow flashing via Webpage we can prevent this from happening after the first successfull flash

@bfredl

bfredl commented Aug 15, 2023

Copy link
Copy Markdown
Collaborator Author

I also have a prototype which allows you to select a .bin file from the sdcard in a menu from the flashed firmware. If there is no outstanding issues with this PR, I would like to see this one merged first (for my own usecase it doesn't matter if it is enabled in binaries or not), and I will submit that as a follow-up.

@jamiefaye
jamiefaye added this pull request to the merge queue Aug 17, 2023
Merged via the queue into SynthstromAudible:community with commit d0d4ce7 Aug 17, 2023
@soymonitus

Copy link
Copy Markdown
Collaborator

Is the process of updating firmware over sysex explained in the docs somewhere?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants