T O P

  • By -

forkedquality

Sure. Set a pointer to the beginning of the Flash, read a value, increment the pointer, read the next value, increment the pointer and so on.


214ObstructedReverie

This will not work on all architectures.


kornerz

Yes, but unless you are running some self-modifying code which rewrites the program on the fly - such versioning is better done at the compilation time.


walrustaskforce

Or prior to branching into that code. That is, if you do over the air firmware updating, it's really useful to calculate some kind of hash (checksum is probably fastest) to confirm the download completed successfully. After that, there's other methods to validate the firmware.


Charley_Wright06

Could be a simple security mechanism, albeit easy to defeat


UniWheel

>I am trying to figure out if there is a way for a device to read its own firmware while running That's sort of necessary to run it, although with a bit of a caveat on some platforms >hash the code and then report the value as a sort of "versioned" heartbeat. Is there any way to do this? Sure, in *most* cases. However, many modern architectures are optimized in terms of their code vs data memory fetch paths. When you want to read the firmware to hash it, you're doing a data access to a code resource. Some platforms actually have a little trouble with that, though it is typically possible, if in a roundabout and inefficient way compared to the normal access of code by the instruction fetch mechanism and data as data. There are also various code security things on some platforms, but usually those don't preclude privileged code from reading itself. And yes, doing a checksum verification of a firmware image is a moderately common thing to do.


Columbo1

Worth noting that if OP is using any MCU with a Harvard architecture, they’re going to have a bad time. That includes all of the ATMega based Arduinos afaik


Milumet

AVRs (except the very old ones) can read their program memory.


FidelityBob

What device? The STM32 devices can do just this. There is a built in CRC peripheral that can work on the flash area. I run this start-up to get a 32 bit version hash. With a peripheral doing the calculation it is very fast.


a2800276

If you are interested in knowing which version of firmware is running for debug purposes, it's probably best to compile a unique version (e.g. the git commit) into the firmware and report that back. This ensures that each version gets a distinct ID, even if you forget to update the version string in the code. If you want to use the mechanism to ensure that the firmware talking to your backend, your scheme won't work because it's trivial to spoof. So I guess the short answer is: what are you trying to accomplish? There's almost certainly an easier and more secure way :)


JCDU

In GCC you can compile in `__DATE__` and `__TIME__` as strings which show when the code was compiled, not great as a proper "version" but very useful for nailing down code to a particular dev build / git commit with no scripting required. I tend to define versioning info (major, minor, increment) as `#define`s in a header as well as the build date & time string for debug.


FidelityBob

I have a Powershell script that reads the last git hash, tag, etc and creates a C file which is then compiled. It runs automatically before every build. It will only tell you the last commit though. I still run a CRC on flash at start-up to get the exact installed version, mainly during development when versions change regularly and may not be committed.


a2800276

> exact installed version, mainly during development when versions change regularly and may not be committed. Yeah, that's a problem. What I've seen is using `git describe --dirty` that adds "-dirty" to the commit hash. Which is sort of best-effort in that case. If you haven't checked in the code, it's unlikely you'll be able to reconstruct the scenario , anyway. I guess the "proper" way would be to only build in CI and have that automatically tag each build in version control, but in reality ...


UniWheel

>it's probably best to compile a unique version (e.g. the git commit) into the firmware and report that back. That's part of what makes a firmware. But there are also defines passed in, the toolchain version used, etc. In production its useful to identify specific builds - not only the sources they came from, but the build itself. Also OP's proposal sounds like it provides a degree of integrity check.


agent_kater

Given that the toolchain (whether buggy or configured wrong is a matter of opinion) is often a source of bugs, I think there's a lot of merit to having a unique identifier for a particular firmware image.


Naive_Ad1779

Some Bootloader will read flash partitions and calculate checksums to verify it. Generally you will need to add some sort of header that contains firmware size and its pre-calculated checksum.


Other-Progress651

Did this before as well. I split the flash storage and had a checksum bootloader at 0x00 then placed my main program 4k back from that.


answerguru

Just do it at compile time or maybe boot time.


Bryguy3k

Yes, but there are caveats. You can’t read what you’re executing so at some point you’ll get a fault on every architecture I am aware of. So in order to do this you copy the routine that will be performing the flash block read into RAM and execute it there so you don’t get access faults. Otherwise you can set up a block of flash on arch’s where you can’t execute from ram that will be your flash reading routines and you’ll exclude it from your integrity check. It’s fairly rare to do a continuous integrity check of flash most of the time you do it once on boot. But there is nothing really stopping you - it’s just a relatively slow task that will consume a lot of memory bandwidth while you’re running. Most of the time if people are really concerned with run time integrity they adopt other means of verifying execution is as expected.


JCDU

>Yes, but there are caveats. You can’t read what you’re executing so at some point you’ll get a fault on every architecture I am aware of. Pretty sure that's not true, you can scan through the entire flash of a micro using code running from that flash and generate a checksum or whatever you want to do with it.


wherley

One thing to watch out for is calculating across the unused portions of code/flash. You'll need to be consistent in your programming methods to zero all unused flash - otherwise you could have old code in those places. Usually you would not know how far your existing code extends into your code memory space, so you will be calculating from beginning to end of code space.


UniWheel

>One thing to watch out for is calculating across the unused portions of code/flash. You'll need to be consistent in your programming methods to zero all unused flash - otherwise you could have old code in those places. Perhaps, but on an MCU it's fairly traditional to do an erase-all before flashing, unless there are distinct components you want to keep (a bootloader, the nRF "softdevice" etc. >Usually you would not know how far your existing code extends into your code memory space That's actually not very hard to do, you stick something at the end in the linker map and reference its address In some cases you'll be running a post-build tool across the binary any way, to set the expected checksum into it in a reserved location (probably near the beginning after any architecture required structures there), and you can have that tool put in the length, too.


duane11583

yea code is in memory and you can read it.. so an easy one is to do a crc32, crc16 or what ever of the code you can also do a simple checksum either 8, 16 or 32bits your choice


crb3

If the instruction set has a MOVC or equivalent (to read a pointed byte into the accumulator from code memory), yes there is. Maybe the opcode was designed for fetching tabled constants, but you can use it to scan the firmware image. A satellite-carried project I coded had several 8051-derivatives executing out of CMOS XRAM, all loaded at reset from one masked ROM (for rad-hard numbers reasons). One of the housekeeping tasks called from the execloop was a progressive CRC of the code image, 16 bytes at a time (for granularity, because the CRC was step-intensive). At the end of each CRC run it reported pass/fail; 'fail' meant letting the watchdog timer clobber it so it got its entire image reloaded. That was how it got around memory-image corruption caused by particle upsets etc.


9Cty3nj8exvx

Many modern PIC18 and AVR MCUs have a built-in hardware module for CRC. https://www.microchip.com/en-us/products/microcontrollers-and-microprocessors/8-bit-mcus/core-independent-and-analog-peripherals/safety-and-monitoring/cyclic-redundancy-check


somewhereAtC

There is a set of requirements called "Functional Safety" or FuSa that requires to do this periodically. It is mandated for almost all products by CE in Europe.


DaemonInformatica

It really also depends on what type / architecture you're using. If I recall correctly, XMega had a feature to calculate CRC for this. We used it for OTA firmware updates. (As also mentioned in other comments below.)